📄 红外接收程序.lst
字号:
C51 COMPILER V9.01 红蚠接收程序 05/24/2012 22:39:58 PAGE 1
C51 COMPILER V9.01, COMPILATION OF MODULE 红蚠接收程序
OBJECT MODULE PLACED IN 红外接收程序.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE 红外接收程序.c BROWSE DEBUG OBJECTEXTEND
line level source
1 /*********************************************
2 12Mhz 晶振
3
4 **本程序适合32位码遥控器,即16位系统码,16位
5
6 数据码,如:57L5,55K2,54B4,KD-29,55K8,5Z26A,
7
8 等型号的遥控器,转贴请保持代码的完整性
9
10 当有按键时就会产一个9.12ms低电平和4.5ms高电平的起始码,紧接着是16位系统码,
11 此系统码能区别不同的电器设备,防止不同机种遥控码互相干扰,接下来是8位数据码
12 和8位数据反码,间隔23ms的高电平后,再发一个与启始码完全一样的结束码 。
13
14 以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;
15 以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”
16
17 定时器约定采用方式2自动重载形式。最小定时周期50us,为一个计数单位。
18 因此:
19 引导信号:13.5ms相当于270个单位
20 0: 为22.6个
21 1: 为45.2个
22 为了增强抗干扰能力,可以用一个范围来确定某个信号
23
24 有效信号一定超过半个脉冲周期即11.3个单位
25 所以
26
27 合法信号范围 【10,280】
28 引导信号范围 【200,280】
29 0 信号范围 【10,30】
30 1 信号范围 【30,60】
31
32 利用HS0038B解码。1脚out接20K上拉电阻,2脚接地,3脚串联100欧姆电阻接VCC,3脚对地接4.7us电容。
33 *********************************************/
34
35 #include "reg51.h"
36
37
38 #define uint unsigned int
39 #define uchar unsigned char
40
41
42 sbit IR=P3^3;//红外端口
43 sbit lock=P3^2;
44
45
46 unsigned char code zxm[]={0x03,0xf3,0x26,0x62,0xd2,0x4a,0x0a,0xe3,0x02,0x42};
47 uchar num,n;
48 uchar key_code=0;//遥控键值
49 uchar new_code=0;//有无新按键
50 uchar buf[4];//暂存地址码、 地址反码 、用户码 、用户反码
51 uchar key_bit_count=0;//键编码脉冲计数
52 uint count=0;//定时中断次数计数
53 uint buf_count=0;//定时中断计数暂存
54 uchar common_code_count=0;//前导码脉冲计数
55 bit IR_status=0;//脉冲接收器所处的状态,0:无信号,1:系统码接收区
C51 COMPILER V9.01 红蚠接收程序 05/24/2012 22:39:58 PAGE 2
56
57 char cnt;
58
59 void delay_10us(unsigned char y)///延时子程序10us
60 {
61 1 unsigned char x;
62 1 for(x=y;x>0;x--);
63 1 }
64
65 void init(void)/////初始化
66 {
67 1 IR=1; //红外端口写1
68 1
69 1 EA=1; //开总中断
70 1 TMOD=0x02; //定时器0,模式2,8位自动装载模式
71 1 TH0=0Xce; //定时50us
72 1 TL0=0Xce;
73 1
74 1 IT1=1; //INT1下降沿触发
75 1 ET0=1; //允许定时器中断
76 1 EX1=1; //允许外部中断
77 1 }
78
79
80 /***********************************************
81 定时器中断
82
83 ***********************************************/
84 void time0() interrupt 1///定时器中断
85 {
86 1 count++;//定时器中断次数累加
87 1 }
88
89
90 /**********************************************
91 外部中断,红外解码程序
92 **********************************************/
93 void int1() interrupt 2///外部中断
94 {
95 1
96 1 TR0=1;//开定时器中断
97 1
98 1 if(count>12&&count<280)//信息持续时间超过最小脉宽0.565ms且不大于引导信号9+4.5=13.5ms 如果信号合法,则
-放入buf_count,count清0,对下一个脉冲信号计时
99 1 {
100 2 buf_count=count;
101 2 count=0;
102 2 }
103 1 delay_10us(10);//延时100us以消除下降沿跳变抖动
104 1
105 1 if(IR==0)//INT1引脚稳定为低电平,则表法确实是信号,count重新计时,因上面延时了50us,故要补偿1次TO中断
106 1 {
107 2 count=2;
108 2 }
109 1
110 1 if(buf_count>=0&&buf_count<280)//若收到的信号合法,则再进行信号分析
111 1 {
112 2
113 2 if(IR_status==0)//如果之前未收到引导码
114 2 {
115 3 if(buf_count>100&&buf_count<280)//判断是否引导码13.5ms
116 3 {
C51 COMPILER V9.01 红蚠接收程序 05/24/2012 22:39:58 PAGE 3
117 4 IR_status=1;//系统标记
118 4 buf_count=0;//
119 4 n=0;//buf的角标从0开始
120 4 }
121 3 }
122 2 else if(IR_status==1)///收到引导码
123 2 {
124 3 if(key_bit_count<32)//收到数据少于32位,则将收到的数据写入buf[]
125 3 {
126 4 if(buf_count>30&&buf_count<60)
127 4 {
128 5 buf_count=0;
129 5 buf[n]>>=1;
130 5 buf[n]|=0x80;//收到1
131 5 key_bit_count++;//数据脉冲累加
132 5 }
133 4 else if(buf_count>10&&buf_count<30)//收到0
134 4 {
135 5 buf_count=0;
136 5 buf[n]>>=1;//收到0
137 5 key_bit_count++;
138 5
139 5 }
140 4
141 4 if(key_bit_count==32)//若收完8位数据则做以下处理
142 4 {
143 5 IR_status=0;//接收状态返回到空闲
144 5 key_bit_count=0;
145 5 buf_count=0;
146 5 TR0=0;
147 5 EX1=0; //停止外中断
148 5 new_code=1;
149 5 }
150 4 n=key_bit_count/8;
151 4 }
152 3 }
153 2 }
154 1 }
155
156 void disp(unsigned long n)
157 {
158 1 unsigned char i=0,t[6]={0};
159 1
160 1 while(n)
161 1 {
162 2 t[i++]=n%10;
163 2 n/=10;
164 2 if(i>5)
165 2 break;
166 2 }
167 1
168 1 for(i=0;i<6;i++)
169 1 {
170 2 SBUF=zxm[t[i]];
171 2 while(!TI);
172 2 TI=0;
173 2 }
174 1
175 1 lock=0;
176 1 lock=1;
177 1 }
178 /*************************************
C51 COMPILER V9.01 红蚠接收程序 05/24/2012 22:39:58 PAGE 4
179 主程序
180 *************************************/
181 void main()
182 {
183 1 init(); ///初始化
184 1
185 1 disp(0);
186 1 while(1)
187 1 {
188 2
189 2 if(new_code)//判断是否有新按键,如果有则执行下面程序,没有则一直循环
190 2 {
191 3 new_code=0;
192 3 //buf[0] 地址码 buf[1] 地址反码 buf[2] 用户码 buf[3] 用户反码
193 3
194 3 if(buf[0]==~buf[1] && buf[2]==~buf[3])
195 3 {
196 4
197 4 if(buf[0]==56)
198 4 {
199 5 disp(buf[2]);
200 5 }
201 4
202 4 }
203 3
204 3 EX1=1; //重新开启外中断
205 3 }
206 2 }
207 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 492 ----
CONSTANT SIZE = 16 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 15 11
IDATA SIZE = ---- ----
BIT SIZE = 1 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -