完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、时序
一个完整的NEC解码协议,由以下几个部分组成,其中数据位为低位先行 详细的数据格式如下,其中如果一直按住一个按钮的时候,会隔110ms左右发一次引导码 二、代码实现 #include #include static uint64_t time_100us = 0; static bool ir_pin_status = false; static EN_IR__NEC_STATE_T en_ir_state = EN_IR_NEC_STATE_IDLE; static uint8_t ir_receive_data_count= 0; static uint32_t ir_receive_data= 0; static uint8_t ir_key_code= 0; static void device_ir_NEC_poll(TASK_PARAM)//定时器中断,100us触发一次,根据具体器件实现 { time_100us ++; if(time_100us >60000){ time_100us = 0; } } static void device_ir_external_irq_pressed(void)//外部中断,配置为ir接收引脚,上升沿和下降沿都触发 { ir_pin_status = platform_gpio_get_level(IR_PIN);//获取当前ir输入电平,高电平证明是上升沿触发,反之下降沿 switch(en_ir_state ){ case EN_IR_NEC_STATE_IDLE ://空闲状态 if(ir_pin_status ==0){//下降沿触发 en_ir_state = EN_IR_NEC_STATE_PREAMBLE_START_LOW;//状态改为等待9ms低电平引导码 } break; case EN_IR_NEC_STATE_PREAMBLE_START_LOW://9ms低电平引导判断 if((ir_pin_status ==1)&&(time_100us >=70)&&(time_100us <=110)){//满足9ms电平引导时序 en_ir_state = EN_IR_NEC_STATE_PREAMBLE_START_HIGH;//状态改为等待高电平引导码 }else{ en_ir_state = EN_IR_NEC_STATE_IDLE;//校验失败,返回空闲状态 } break; case EN_IR_NEC_STATE_PREAMBLE_START_HIGH://4.5ms高电平引导或repeat if(ir_pin_status ==0){//下降沿触发 if((time_100us >=35)&&(time_100us <=60)){//4.5ms高电平引导 en_ir_state = EN_IR_NEC_STATE_RECEIVE_DECODE;//状态改为接收数据 ir_receive_data_count= 0;//清空接收计次 ir_receive_data= 0;//清空接收数据 } else if ((time_100us >=15)&&(time_100us <35)){//2.25ms高电平repeat en_ir_state = EN_IR_NEC_STATE_RECEIVE_REPEAT;//状态改为repeat }else{ en_ir_state = EN_IR_NEC_STATE_IDLE;//校验失败,返回空闲状态 } }else{ en_ir_state = EN_IR_NEC_STATE_IDLE;//校验失败,返回空闲状态 } break; case EN_IR_NEC_STATE_RECEIVE_DECODE://接收数据 if(ir_pin_status == 0){//下降沿触发(即只判断高电平持续时间) if((time_100us <=8)&&(time_100us >=3)){//满足(1.12-0.56ms)存入低电平 ir_receive_data >>= 1; }else if((time_100us >=12)&&(time_100us <=20)){//满足(2.25-0.56ms)存入高电平 ir_receive_data = ((ir_receive_data >> 1) | 0x80000000); }else{//校验失败 en_ir_state = EN_IR_NEC_STATE_IDLE; } if(++ir_receive_data_count >= 32){//接收到4个字节(两个头码和两个数据),后停止接收 device_ir_NEC_decode(ir_receive_data);//数据解码 en_ir_state = EN_IR_NEC_STATE_IDLE;//回到空闲状态 } } break; case EN_IR_NEC_STATE_RECEIVE_REPEAT: //自由选择是否继续报上一个键值 break; } time_100us = 0;//每次判断完数据,需要把计数清空 } static bool device_ir_NEC_decode(uint32_t code) { uint8_t head_code_low = code &0x000000FF; //取出低8位数据 uint8_t head_code_high = (code &0x0000FF00) >> 8; //取出低8-16位数据 uint8_t key_code = (code &0x00FF0000) >> 16; //取出低16-24位数据 uint8_t key_code_minus = (code &0xFF000000) >> 24; //取出低24-32位数据 if((head_code_low ==IR_NEC_HEAD_CODE_LOW) && //判断是否是头码低位 (head_code_high ==IR_NEC_HEAD_CODE_HIGH) && //判断是否是头码高位 (key_code ==((~key_code_minus )&0xFF))){ //判断key_code_minus 是否是key的反码 ir_key_code = key_code;//获取键值 return true; } ir_key_code = 0; return false; } bool device_ir_NEC_get_key(uint8_t *p_key)//用于给其他应用模块取得键值 { if(!ir_key_code){ *p_key = ir_key_code; ir_key_code =0;//获取过键值后,清空键值 return true; } return false; } |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 11:53 , Processed in 1.366186 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号