51单片机红外遥控器开发实战解析(附完整工程代码)
本文详细介绍了基于51单片机的红外遥控接收系统开发,包含完整工程代码解析。系统由三大核心模块组成:1.红外接收模块(ired.c/h)采用NEC协议解码,通过外部中断检测9ms引导脉冲和4.5ms高电平,实现32位数据接收校验;2.LCD1602显示模块实现双行字符显示;3.数码管模块通过74HC138译码器驱动显示十六进制数据。主控逻辑实现红外数据解析、数码管显示及特定编码响应功能,并给出优化建
目录
51单片机红外遥控器开发实战解析(附完整工程代码)
一、工程架构与核心模块
本工程实现了一个基于51单片机的红外遥控接收系统,包含红外解码、LCD显示、数码管显示三大核心模块,工程文件结构如下:
- ired.c/h // 红外接收驱动
- LCD1602.c/h // 1602液晶驱动
- smg.c/h // 数码管驱动
- public.c/h // 公共函数库
- main.c // 主控逻辑
二、红外接收模块解析(ired.c/h)
1. 初始化函数
void ired_init() {
IT0=1; // 设置INT0为下降沿触发
EX0=1; // 使能INT0中断
EA=1; // 全局中断使能
IRED=1; // 设置红外接收引脚为高电平
}
关键点:
-
使用外部中断0(INT0)检测红外信号下降沿
-
IRED引脚定义为P3^2(见ired.h)
2. 中断解码逻辑
void ired() interrupt 0 {
// 检测9ms引导脉冲
while((!IRED)&&time_cnt) { /*...*/ } // 等待低电平结束
// 检测4.5ms高电平
while(IRED&&time_cnt) { /*...*/ }
// 32位数据接收(4字节*8位)
for(i=0;i<4;i++) {
for(j=0;j<8;j++) {
// 检测560us低电平
while((IRED==0)&&time_cnt) { /*...*/ }
// 测量高电平持续时间
while(IRED) {
delay_10us(10);
ired_high_time++; // 计算高电平时间
}
// 数据解码:>0.8ms判为1,否则为0
gired_date[i] >>= 1;
if(ired_high_time>=8) gired_date[i] |= 0x80;
}
}
// 数据校验(第三字节取反=第四字节)
if(gired_date[2] != ~gired_date[3]) {
memset(gired_date,0,4); // 校验失败清空数据
}
}
协议解析:
-
支持NEC红外协议(9ms引导脉冲+4.5ms高电平)
-
gired_date[0-3]存储:地址码、地址反码、数据码、数据反码
-
关键时间阈值:
-
560us低电平 + 560us高电平 → 逻辑0
-
560us低电平 + 1.68ms高电平 → 逻辑1
-
三、LCD1602显示模块(LCD1602.c/h)
1. 核心函数
// 写指令函数
void lcd1602_write_cdm(u8 cdm) {
LCD1602_RS=0; // 命令模式
LCD1602_DATEPORT=cdm;
LCD1602_E=1; // 使能脉冲
delay_ms(1);
LCD1602_E=0;
}
// 字符串显示函数
void lcd1602_show_string(u8 x,u8 y,u8 *str) {
if(y==0) lcd1602_write_cdm(0x80+x); // 第一行定位
else lcd1602_write_cdm(0xC0+x); // 第二行定位
while(*str) lcd1602_write_date(*str++); // 逐个输出字符
}
关键指令:
-
0x38:8位数据接口/2行显示 -
0x0C:开显示/关光标 -
0x01:清屏
四、数码管显示模块(smg.c/h)
1. 数码管驱动
void smg_display(u8 dat[],u8 pos) {
for(i=pos-1; i<8; i++) {
// 位选控制(74HC138译码器)
switch(i) {
case 0: LSC=1;LSB=1;LSA=1; break; // LED1
case 1: LSC=1;LSB=1;LSA=0; break; // LED2
/* 其余6位类似 */
}
// 段选数据输出
SMG_A_DP_PORT = dat[i-pos+1];
delay_10us(100);
SMG_A_DP_PORT=0x00; // 消影
}
}
显示编码:
// 0-F共阳数码管编码
u8 gsmg_code[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
五、主控逻辑(main.c)
1. 主程序框架
void main() {
lcd1602_init(); // 初始化LCD
ired_init(); // 初始化红外
// 初始显示内容
lcd1602_show_string(0,0,"who did it bro?");
lcd1602_show_string(6,1,"O_o");
while(1) {
// 1. 获取红外数据
ired_tempx = gired_date[2];
// 2. 数码管显示数据(十六进制)
ired_buf[0]=gsmg_code[ired_tempx/16]; // 高4位
ired_buf[1]=gsmg_code[ired_tempx%16]; // 低4位
ired_buf[2]=0x76; // 显示"H"
// 3. 特定红外码响应
if(ired_tempx==LIHUA) { // 0x22
LED_PORT=~0x01; // LED1亮
lcd1602_show_string(0,0,"lihua");
lcd1602_show_string(0,1,"come on!");
}
else if(ired_tempx==ZHANGSAN) { // 0xA3
LED_PORT=~0x02; // LED2亮
/* 类似显示逻辑 */
}
// 4. 数码管刷新
smg_display(ired_buf,6);
}
}
关键逻辑:
-
数码管显示接收数据的十六进制值(如0xA3显示"A3H")
-
特殊编码触发LCD内容更新和LED指示
六、优化建议(不改动原代码)
-
增加消抖处理
在红外解码中加入状态机机制,避免临界值误判:
// 在测量高电平处改进
if(ired_high_time>15) return; // 异常脉冲保护
-
添加长按检测
扩展按键处理逻辑,区分单击/长按:
// 在key_scan()中增加
static u16 press_timer=0;
if(KEY1==0) press_timer++;
else press_timer=0;
if(press_timer>1000) return LONG_PRESS;
-
显示优化
数码管显示增加小数点标识:
// 修改显示数据
ired_buf[1] = gsmg_code[ired_tempx%16] | 0x80; // 添加小数点
-
资源节省
使用看门狗复位替代死循环:
// public.h添加
#define WDT_CONTR 0xE1
// main.c中
WDT_CONTR = 0x34; // 启动看门狗
注意:所有优化建议均不改变原有代码结构,可作为功能扩展方向。
七、项目总结
本工程完整实现了:
-
✅ NEC红外协议精确解码
-
✅ LCD1602的双行菜单显示
-
✅ 数码管实时数据反馈
-
✅ 按键与LED联动控制
接线参考:
红外接收器 → P3.2
LCD1602 → P0(数据), P2.5-P2.7(控制)
数码管 → P0(段选), P2.2-P2.4(位选)
LED → P2.0-P2.3
通过本项目的学习,可以掌握51单片机的中断处理、时序分析、外设驱动等核心开发技能,特别适合红外遥控、智能家居控制等应用场景的开发。
更多推荐



所有评论(0)