完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、NEC协议简介
利用红外传输信息,编码协议有很多,我采用了常用的NEC协议进行编码。 NEC协议构成包括引导码、地址码、地址反码、控制码、控制反码。其采用PWM脉冲位置调制,以发射红外载波的占空比代表“0”和“1”。 NEC码的位定义:一个脉冲对应560us的连续载波,一个逻辑1传输需要2.25ms(560us脉冲+1680us低电平),一个逻辑0的传输需要1.125ms(560us脉冲+560us低电平)。一体化红外接收头HS0038B在收到脉冲时为低电平,没有脉冲时为高电平。这样的话,在接收头端收到的信号是:逻辑1对应560us低+1680us高,逻辑0对应560us低+560us高。 NEC同步码由9ms高电平和4.5ms低电平组成。另外,如果一直按住按键,遥控器会发送重复码(9ms高电平+2.5m低电平+0.56ms高电平+97.94ms低电平)。 2、载波实现及TIM配置 TIM_HandleTypeDef TIM3_Handler; //定时器句柄 TIM_OC_InitTypeDef TIM3_CH2Handler; //定时器3通道2句柄 //TIM3 PWM部分初始化 //arr:自动重装值。 //psc:时钟预分频数 //定时器溢出时间计算方法:Tout=((arr+1)*(psc+1))/Ft us. //Ft=定时器工作频率,单位:Mhz void TIM3_PWM_Init(u16 arr,u16 psc) { TIM3_Handler.Instance=TIM3; //定时器3 TIM3_Handler.Init.Prescaler=psc; //定时器分频 TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式 TIM3_Handler.Init.Period=arr; //自动重装载值 TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1; HAL_TIM_PWM_Init(&TIM3_Handler); //初始化PWM TIM3_CH2Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1 TIM3_CH2Handler.Pulse=arr/2; //设置比较值,此值用来确定占空比 TIM3_CH2Handler.OCPolarity=TIM_OCPOLARITY_HIGH; //输出比较极性为高 HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH2Handler,TIM_CHANNEL_1);//配置TIM3通道1 HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH2Handler,TIM_CHANNEL_2);//配置TIM3通道2 HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH2Handler,TIM_CHANNEL_3);//配置TIM3通道3 HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH2Handler,TIM_CHANNEL_4);//配置TIM3通道4 HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_1);//开启PWM通道1 HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_2);//开启PWM通道2 HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_3);//开启PWM通道3 HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_4);//开启PWM通道4 } //定时器底层驱动,时钟使能,引脚配置 //此函数会被HAL_TIM_PWM_Init()调用 //htim:定时器句柄 void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim) { GPIO_InitTypeDef GPIO_Initure; if(htim->Instance==TIM3) { __HAL_RCC_TIM3_CLK_ENABLE(); //使能定时器3 __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 __HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟 GPIO_Initure.Pin=GPIO_PIN_6 | GPIO_PIN_7;//PA6,PA7 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;//高速 HAL_GPIO_Init(GPIOA,&GPIO_Initure); GPIO_Initure.Pin=GPIO_PIN_0 | GPIO_PIN_1;//PB0, PB1 HAL_GPIO_Init(GPIOB,&GPIO_Initure); } } //设置TIM3通道1~4的占空比 //compare:比较值 void TIM_SetTIM3Compare(u32 compare, u8 CH) { if(CH == 1) TIM3->CCR1=compare; else if(CH == 2) TIM3->CCR2=compare; else if(CH == 3) TIM3->CCR3=compare; else if(CH == 4) TIM3->CCR4=compare; } 3、编码发送 void IRSend(u8 num, u8 CH){ u8 addr = REMOTE_ID; /* 发送引导码 */ NEC_Start(CH); /* 发送地址码 */ NEC_Send_Byte(addr, CH); /* 发送地址反码 */ NEC_Send_Byte(~addr, CH); /* 发送控制码 */ NEC_Send_Byte(num, CH); /* 发送控制反码 */ NEC_Send_Byte(~num, CH); Logical_0(CH);//停止位,如果没有这个的话,上面发的最后一位的时长检测会出问题; //理论上给个电平跳变就行,不一定发逻辑0。跳变完恢复为空闲状态 } void NEC_Start(u8 CH){ TIM_SetTIM3Compare(947, CH); delay_us(9000); TIM_SetTIM3Compare(0, CH); delay_us(4500); } void NEC_Send_Byte(u8 value, u8 CH){ u8 i; for(i = 0; i < 8; i++){ if(value & 0x80){ Logical_1(CH); }else { Logical_0(CH); } value <<= 1; } } void Logical_0(u8 CH){ TIM_SetTIM3Compare(947, CH); delay_us(560); TIM_SetTIM3Compare(0, CH); delay_us(560); } void Logical_1(u8 CH){ TIM_SetTIM3Compare(947, CH); delay_us(560); TIM_SetTIM3Compare(0, CH); delay_us(1680); } |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1178浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 10:45 , Processed in 1.293649 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号