STM32红外接收与发送实战一(发射红外信号):利用定时器产生一个38KHZ的载波来发送红外信号
在上一篇博客《STM32红外接收与发送实战一》中,我们了解到大多数红外信号遵循的是 NEC 协议。该协议的核心组成部分包括 引导码、用户码、用户码反码、按键键码 和 键码反码。此外,还明白了红外发射信号是通过调制在一个 38kHz 的载波上发射出去的。
因此,如果我们要实现红外信号的发送,首先需要生成一个 38kHz 的载波信号,然后按照 NEC 协议的格式将数据编码并发射出去。这个载波信号的存在决定了红外发射管何时打开或关闭,而数据则通过载波的脉冲来传递。
首先,要通过定时器产生一个38KHZ的脉冲信号。先进行定时器的初始化(因为我的红外发射管连接着定时器3的CH3通道,所以来初始化这个IO口)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //推挽复用输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 3. 配置TIM3的时钟频率和周期
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Prescaler = 70;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period = 25;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
// 4. 配置PWM模式,首先初始化占空比为0%
TIM_OCInitTypeDef TIM_OCInitStruct;
TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStruct.TIM_Pulse = 0;
TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC3Init(TIM3,&TIM_OCInitStruct);
// 5. 使能或者失能 TIMx 在 CCR1 上的预装载寄存器
TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
// 6. 启动定时器
TIM_Cmd(TIM3, ENABLE);
因为我初始化占空比为0,要产生一个38KHZ的载波信号,占空比需要为三分之一,所以使用这行代码可以产生一个38KHZ的载波信号(当占空比为零时,可以认为,不产生信号)
TIM_SetCompare3(TIM3, 8);
我们发送红外信号是遵循NEC协议来发送的,
当为高电平时,我们的38KHZ的载波信号发射,当为低电平时,关闭载波信号。
//发送引导码
void RED_Send_Boot(void){
TIM_SetCompare3(TIM3, 8);
Delay_us(9000);
TIM_SetCompare3(TIM3, 0);
Delay_us(4500);
}
//发送数据码,0还是1;
void RED_Send_Data(uint8_t data){
if(data==0){
TIM_SetCompare3(TIM3, 8);
Delay_us(560);
TIM_SetCompare3(TIM3, 0);
Delay_us(560);
}
else{
TIM_SetCompare3(TIM3, 8);
Delay_us(560);
TIM_SetCompare3(TIM3, 0);
Delay_us(1690);
}
}
//发送数据
void RED_Send_Data_all(uint8_t* data,uint8_t len){
RED_Send_Boot();
for(int i=0;i<len;i++){
for(int j=7;j>=0;j--){
uint8_t qwe =(data[i]>>j)&0x01;
RED_Send_Data(qwe);
}
}
}
在主函数中,通过调用RED_Send_Data_all函数来发射红外数据。(注意,这里没有发送用户编码,其实要是自己玩玩的话,协议可以自已设定,只要发送方和接收方约定好就行)
作者:愤怒的小王¥