前期我发帖称也谈51单片机红外通信(附四种方案),现对第一方案一处错误进行修正。前期贴链接附在下面:
也谈51单片机红外通信(附有四种红外解码源码) - 单片机DIY制作 (51hei.com)
- /*-----------------------------------------------
- 【实验平台】: QX-MCS51 单片机开发板
- * 【外部晶振】: 11.0592Mhz
- * 【主控芯片】: STC89C52
- * 【编译环境】: Keil μVisio4
- * 【编 程】:wzqwxx 水上人家
- 名称:遥控器红外解码数码管显示
- 内容:按配套遥控器会在数码管上对应显示键码值,实测通过
- NEC 标准下的编码表示
- 其中:引导码高电平约9000us 左右,低电平约4500us 左右;
- 接收端:引导码低电平约9000us 左右,高电平约4500us 左右;
- 用户码16 位,数据码16 位,共32位;
- 发送端: 数据0 是用“高电平约560us +低电平约560us”表示。
- 数据1 可用“高电平约560us+低电平约1680us”表示
- 接收端反转:数据0 是用“低电平约560us +高电平约560us”表示。
- 数据1 可用“低电平约560us+高电平约1680us”表示
- ------------------------------------------------*/
- #include<reg52.h> //包含头文件,头文件包含特殊功能寄存器的定义
- #include <stdio.h>
- #include "SMG.H"
- sbit IR=P3^2; //红外接口
- sbit beep = P2^3;//蜂鸣器接口
- unsigned char irtime; //红外用全局变量 计数延时,识别比特位电平高低
- unsigned char IRcord[4]= {0x12,0x34,0x56,0x78};//存储键码
- void tim0_isr (void) interrupt 1 //STC89C52 11.0592M
- {
- irtime++; //用于计数2个下降沿之间的时间 每个溢出中断时长256*1.085069us=277.77us
- }
- void EX0_ISR (void) interrupt 0 //外部中断0服务函数
- {
- static unsigned char i,blag; //接收红外信号处理
- if(blag == 1)
- {
- if( irtime <3 || irtime >51)goto end; //两个下降沿延时过短(少于833us)或过长不解码 滤除干扰波
- if(irtime > 28 && irtime < 55)//跳过引导码 头码,9ms+4.5ms
- { i=0; goto end;}
- IRcord[i/8] >>= 1; //i/8每处理8位换下一个元素,总的处理4个字节共32位的数据
- if(irtime > 5 ) IRcord[i/8] |= 0x80; //位0电平时长计数上限4,位1高电平计数上限8
- i++; //这里取6为0/1 的识别分界
- if(i > 31){ i = 0; blag = 0; beep = 0; delay(30); beep = 1; } //beep 鸣叫一声 解码成功
- }
- else
- {blag = 1;}
- end:irtime=0;
- }
- //void UART_init()
- //{
- // TMOD |= 0x20; //T1工作模式2 8位自动重装
- // TH1 = 0xfd;
- // TL1 = 0xfd; //比特率9600 时钟频率11.0592MHZ
- // TR1 = 1; //启动T1定时器
- // SM0 = 0;
- // SM1 = 1; //串口工作方式1 10位异步
- // REN = 1; //串口允许接收
- // TI = 1;
- //}
- void TIM0init(void)//定时器0初始化
- {
- TMOD|=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
- TH0=0x00; //重载值
- TL0=0x00; //初始化值
- ET0=1; //开中断
- TR0=1;
- }
- void EX0init(void)
- {
- IT0 = 1; //指定外部中断0下降沿触发,INT0 (P3.2)
- EX0 = 1; //使能外部中断
- EA = 1; //开总中断
- }
- void main(void)
- {
- // UART_init();
- EX0init(); //初始化外部中断
- TIM0init();//初始化定时器
- while(1)//主循环
- {
- SMGXSSZ(IRcord);
- // printf(" %bx %bx %bx %bx \n ",IRcord[0],IRcord[1],IRcord[2],IRcord[3]) ;
- }
- }
-
-
复制代码
- #include "SMG.H"
- uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
- 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
- //0-F的码表
- uchar code wen_code[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //数码管位数选择码表
- void delay(uint i)//延时毫秒程序
- {
- uint m,n;
- for(m=i;m>0;m--)
- for(n=114;n>0;n--);
- }
-
- //一位数码管显示,参数1:位,参数2:数
- void smgxs(uchar we,uchar shu)
- {
-
- P0=table[shu];
- du=1;
- du=0;
- P0=wen_code[we];
- we=1;
- we=0;
- delay(2);
- }
- //void smgxs8w(unsigned long shu) //数码管显示8位大数
- //{
- // unsigned long shu_temp=shu;
- // uchar i=8;
- // if(shu>0)
- // {
- // while(shu_temp)
- // {
- // i--;
- // smgxs(i,shu_temp%10);
- // shu_temp=shu_temp/10;
- // }
- // } else {smgxs(7,0);}//归零数码管显一个零
- //}
- void SMGXSSZ(uchar shuz[]) //数码管显示数组
- {
- uchar i;
- for(i = 0;i < 4;i++)
- {
- smgxs(i*2+1,shuz[i]&0x0f); //显示十六进制数
- smgxs(i*2,shuz[i]>>4);
- }
- }
复制代码
|