基于NEC编码的AVR16或AVR128的红外按键接受程序
### 基于NEC编码的AVR16或AVR128的红外按键接收程序解析 #### 核心知识点概述 本程序是作者在参加电子设计比赛中编写的,用于实现基于NEC(National Electric Code)编码协议的红外线信号接收功能。该程序能够识别并处理NEC编码的红外信号,并将接收到的数据转换为对应的按键值。下面将对代码进行详细的分析和解释。 #### 关键宏定义与变量介绍 1. **宏定义**: - `#define uchar unsigned char`:定义`uchar`为`unsigned char`类型。 - `#define uint unsigned int`:定义`uint`为`unsigned int`类型。 2. **全局变量**: - `uchar flag, num, flagkey = 0;`:其中`flag`用于标识接收状态,`num`记录已接收的位数,`flagkey`标志是否已成功接收一个完整的键值。 - `uint abit;`:存储当前接收的一位数据。 - `uint time;`:用于存储定时器中断时的时间值,即脉冲宽度。 - `uchar flagmeasure, flagset, flagplus, flaginitset = 0;`:这些变量用于控制不同的工作模式或初始化状态。 - `long keyn = 0;`:最终按键值。 #### 主要逻辑流程 1. **中断服务函数**: - 在`#pragma interrupt_handler negedge:6`中定义了一个外部中断服务函数,该函数在检测到下降沿时被调用。 - 函数开始处通过`CLI();`关闭全局中断,确保在执行关键操作时不被其他中断打断。 - 读取定时器溢出计数值`time=ICR1L; time|=(int)ICR1H<<8;`,用于计算脉冲宽度。 - 通过比较脉冲宽度判断接收状态,例如`if(1600 < time && time < 1800 && num == 0)`用来确认起始位是否正确,这一步骤至关重要,因为它是后续数据接收的基础。 2. **接收逻辑**: - 如果起始位正确,则进一步根据后续脉冲宽度的不同来确定每一位数据(0或1),例如: - `if (260 < time && time < 330) {abit = 1; key = (key << 1) + abit; num++;}` - `if (110 < time && time < 190) {abit = 0; key = (key << 1) + abit; num++;}` - 当接收完整个32位数据后,将接收到的数据存储在`keydisp`中,并将`flagkey`设置为1,表示已经完成了一次完整的接收过程。 3. **按键值映射**: - 通过`switch(keydisp % 10000)`将接收到的`keydisp`值映射到具体的按键值`keyn`上。每个按键值都有其对应的NEC码,例如: - `case 3975: keyn = 1; break;` - `case 895: keyn = 2; break;` - ... - `case 6615: keyn = 11; break;` - 此处列出了大量的case语句来覆盖各种可能的按键值,通过这种方式可以方便地添加新的按键映射关系。 4. **工作模式切换**: - 根据接收到的按键值改变不同的工作模式或初始化状态。例如: - `if (keyn == 29) {flagset = 1; flagplus = 0; flagmeasure = 0; flaginitset = 1; flaginitplus = 0; flaginitmeasure = 0;}` 这段代码用于切换到某种特定的工作模式。 #### 小结 本程序通过中断的方式实现了NEC编码的红外线信号接收,并通过精确的脉冲宽度判断来解析数据。通过对比预设的按键值与接收到的数据,可以准确地映射到具体的按键动作上。需要注意的是,在实际应用中,由于硬件平台的不同,部分配置可能需要调整,如定时器的设置、引脚分配等。此外,为了提高稳定性和鲁棒性,可以在程序中增加错误检测和异常处理机制。
#define KEY_H
#define uchar unsigned char
#define uint unsigned int
unsigned long keydisp,key;
uchar flag,num,flagkey=0;//flagkey用于判断是否有按键按下
uint abit;
uint time;
uchar flagmeasure,flagset,flagplus,flaginitset=0;flaginitplus=0;flaginitmeasure=0;//flagmeasure测量循环条件,flagset直接置数循环条件,flagplus减价置数条件,
//flagmodeinit各个循环初始化条件。
long keyn=0;
#pragma interrupt_handler negedge:6
void negedge(void)
{
CLI();
DDRD&=~BIT(6);
TCCR1B&=0X1f;
time=ICR1L; //Read low byte first (important)
time|=(int)ICR1H << 8;
TCNT1H=0X00;
TCNT1L=0X00;
//TCCR1B=0X03;
TCCR1B&=0X1f;
TCCR1B|=0X03;
- lanlanzhilian2013-12-05程序很容易看懂,借鉴了一下!
- as65482013-05-10还是不错,对我有很大帮助
- 粉丝: 10
- 资源: 11
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Analytics-2024-11-07-080019.ips.ca.synced
- java订单管理系统源码ssh框架数据库 MySQL源码类型 WebForm
- DS18B20温度传感器STM32驱动头文件
- (源码)基于Spring Boot的二猫社区管理系统.zip
- content_1731501062882.xlsx
- javaswing游戏项目源码.zip
- Python实现收集器的源码.zip
- (源码)基于Java多线程的并发任务管理系统.zip
- C#在线网校考试系统源码 在线学习云服务平台源码数据库 SQL2008源码类型 WebForm
- com.sun.net.httpserver安卓HTTP服务器jar包最新版2.2.1