版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、红外线程序为 LC7461 等 这里以红外线编码为例来说明用单片机实现红外的详细过 程,站长琢磨这个程序花了相当多的精力,期间几经修改逐步完善,后来还用它开发了几个小产 品,希望能对网友学习单片机有所帮助。红外线是目前使用最广泛的一种通信和。由于红外线装置具有体积小、功耗低 功能强、成本特点,因而,继彩电、机之后,在机、音响设备、空凋机以及玩具等其它 小型电器装置上也纷纷采用红外线。工业设备中,在高压、辐射、气体、粉尘等环境下,采 用红外线不仅完全可靠而且能有效地电气干扰。 1 红外系统系统由发射和接收两大部分组成,应用编/ 通用红外集成电路来进行控制操作,如图 1 所示。发射部分包括键盘矩阵
2、、编码调制、LED 红外发送器;接收部分包括光、电转换放大器、 解调、电路。 2 及其编码很多,根据编码格式可以分成脉冲宽度调制和脉冲相位调制两大类,这里以运用比较广泛,比较容易的脉冲宽度调制来加以说明,现以 LC7461 组成发射电路为例说明编码原理。当特征:按键按下后,即有码发出,所按的键不同编码也不同。这种码具有以下采用脉宽调制的串行码,以脉宽为 0.565ms、间隔 0.56ms、周期为 1.125ms 的组合表示二进制的“0”以脉宽为 0.565ms、间隔 1.685ms、周期为 2.25ms 的组合表示二进制的“1”上述“0”和“1”组成的 42 位二进制码经 38kHz 的载频进
3、行二次调制以提高发射效率,达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空间发射,7461 产生的编码是连续的 42 位二进制码组,其中前 26 位为用户识别码,能区别不同的红外遥控设备,防止不同机种码互相干扰。后 16 位为 8 位的操作码和 8 位的操作反码用于核对数据是否接收准确。上任意一个按键按下超过 36ms 时,LC7461 当的振荡器使激活,将发射一个特定的 同步码头,对于接收端而言就是一个 9ms 的低电平,和一个 4.5ms 的,这个同步码头可以使程序知道从这个同步码头以后可以开始接收数据。的关键是如何识别“0”和“1”,从位的定义可以发现“0”、“1”均以 0
4、.56ms 的低电平开始,不的宽度不同,“0”为 0.56ms,“1”为 1.68ms,所以必须根据的宽度区别“0”和“1”。如同的是果从 0.56ms 低电平过后,开始延时,0.56ms 以后,若读到的电平为低,说明该位为“0”,反之则为“1”为了可靠起见,延时必须比 0.56ms 长些,但又过 1.12ms,否则如果该位为“0”,读到的已是下,因此取(1.12ms+0.56ms)/2=0.84ms 最为可靠,一般取 0.84ms 左右即可。一位的根据红外编码的格式,程序应该等待 9ms 的起始码和 4.5ms 的结果码完成后才能读码。如果邮购开发的 51 单片机试验板和扩展元件的网友,可以
5、获得如上图所示的红外手柄,这的编码格式符合上面的描述规律,而且价格低廉,有 32 个按键,按键外形比较 种,如果用于批量开发,可以把上贴膜换成你需要的字符,这为开发产品提供了便利。及 LT0038 是塑封红外线,它是一种集红外线接收、放大、整形于一体的集成电路,不需 要任何外接元件,就能完成从红外线接收到输出与 TTL 电平信号兼容的所有工作,没有红外信号时为,收到红外信号时为低电平,而体积和普通的塑封三极管大小一样,它适合于各种红外线和红外线数据传输。 下面是一个对 51 实验板配套的红外线的程序,它可以把上图 32 键的红外每一个按键的键值读出来,并且通过实验板上 P1 口的 8 个LED
6、 显示出来,在嘀嘀”的提示音。成功的同时并且能发出“嘀0000HAJMP MAIN;转入主程序 0003H ;外部中断 P3.2 脚0地址AJMP;转入外部中断服务子程序(程序);以下为主程序进行CPU 中断方式设置MAIN:SETB EA ;打开 CPU 总中断请求SETB IT0 ;设定SETB EX0 ;打开0 的触发方式为脉冲负边沿触发0 中断请求;以下对单片机的所有引脚进行初始化,全部设置成MOV P2,#11100111BAJMP $;以下为进入 P3.2 脚外部中断子程序,也就是: CLR EA ;暂时关闭 CPU 的所有中断请求MOV R6,#10SB: ACALL YS1;调
7、用 882 微秒延时子程序程序 JB P3.2,EXIT;延时 882 微秒后判断 P3.2 脚是否出现如果有就退出程序 DJNZ R6, SB;重复 10 次,目的是检测在 8820 微秒内如果出现就退出程序;以上完成对信号的 9000 微秒的初始低电平信号的识别。JNB P3.2, $ ;等待避开 9 毫秒低电平引导脉冲ACALL YS2 ;延时 4.74 毫秒避开 4.5 毫秒的结果码MOV R7,#26;忽略前 26 位系统识别码JJJJA:JNB P3.2,$;等待地址码第一位的信号 LCALL YS1;开始后用 882 微秒的时间尺去判断信号此时的高低电平状态MOV C,P3.2;
8、将 P3.2 引脚此时的电平状态 0 或 1 存入C 中JNC UUUA;如果为 0 就跳转到 UUUA LCALL YS3;检测到1 的话延时 1 毫秒等待脉冲结束UUUA: DJNZ R7,JJJJAMOV R1,#1AH ;设定 1AH 为起始 RAM 区MOV R2,#2;接收从 1AH 到 1BH 的 2 个内存,用于存放操作码和操作反码PP: MOV R3,#8;每组数据为 8 位 JJJJ: JNB P3.2,$;等待地址码第一位的信号 LCALL YS1;开始后用 882 微秒的时间尺去判断信号此时的高低电平状态MOV C,P3.2;将 P3.2 引脚此时的电平状态 0 或 1
9、 存入C 中JNC UUU;如果为 0 就跳转到 UUU LCALL YS3;检测到1 的话延时 1 毫秒等待脉冲结束UUU: MOV A,R1;将 R1 中地址的给 ARRC A;将C 中的值 0 或 1 移入A 中的最低位MOV R1,A;将 A 中的数暂时存放在 R1 数值的内存中DJNZ R3,JJJJ;接收满 8 位换一个内存INC R1;对 R1 中的值加 1,换下一个 RAMDJNZ R2,PP ;接收完 8 位数据码和 8 位数据反码,存放在 1AH/1BH 中MOV A,1AHCPL A;对 1AH 取反后和 1BH 比较CJNE A,1BH,EXIT;如果不等表示接收数据发
10、生错误,放弃MOV P1,1AH;将按键的键值通过 P1 口的 8 个LED 显示出来!CLR P2.5;蜂鸣器鸣响嘀嘀嘀 LCALL YS2LCALL YS2 LCALL YS2SETB P2.5;蜂鸣器停止EXIT: SETB EA ;允许中断,表示成功 RETI ;退出子程序YS1: MOV R4,#20 ;延时子程序 1,精确延时 882 微秒D1: MOV R5,#20 DJNZ R5,$DJNZ R4,D1 RETYS2: MOV R4,#10 ;延时子程序 2,精确延时 4740 微秒D2: MOV R5,#235 DJNZ R5,$DJNZ R4,D2RETYS3: MOV R
11、4,#2;延时程序 3,精确延时 1000 微秒D3:MOV R5,#248 DJNZ R5,$DJNZ R4,D3 RETEND0A0111 12 13 1415A 1B 0E 02 03 1C06 04 05 0C0D 08 09 1D00 1F 1E 0B070F按键的实际位置给出的 32 个按键的键值(16 进制)这是按照红外 Last edited by sina3228 on 2005-1-14 at 19:35 0000H AJMP MAIN0003H ;外部中断0地址AJMP;转中断服务子程序MAIN: MOV SP,#40H MOV P1,#00HSETB EA ;开 CPU
12、 中断SETB IT0 ;设定0 触发方式SETB EX0 ;0 请求中断DSP: MOV R2,#9 ;将MOV DPTR,#TAB1 VV: MOV A,R2键值转化成 A(09)MOVC A, XRL A,1CH JZ ABC DJNZ R2,VVABC: MOV A,R2TRMOV DPTR,#TAB ;将A 的值通过数码管显示出来MOVC A,TRRX1: MOV P1,ACLR P0.1 AJMP DSP: CLR EA MOV R6,#10 SB: ACALL YS1 JB P3.2,EXIT DJNZ R6, SBJNB P3.2, $ ;等待避开 9 毫秒低电平引导脉冲ACA
13、LL YS2 ;延时 4。74 毫秒判断是否连发JB P3.2,EXIT CPL P0.0MOV R1,#1AH ;将 32 位代码分别放在 1AH/1BH/1CH/1DH 中MOV R2,#4 PP: MOV R3,#8JJJJ: JNB P3.2,$ LCALL YS1MOV C,P3.2 JNC UUU JB P3.2,$UUU: MOV A,R1 RRC AMOV R1,A DJNZ R3,JJJJ INC R1 DJNZ R2,PPMOV P2,1CHMOV A,1AH ;进行代码识别XRL A,#0 ;判断 1AH 的值是否等于 00000000 JNZ EXI ;如果不同则无效将
14、 1CH 清零CLR P0.1 MOV A,1BHXRL A,#11110111B ;再判断高 8 位地址是否正确JNZ EXI MOV A,1CH CPL AXRL A,1DH ;将 1CH 的值取反后和 1DH 比较 不同则无效丢弃核对数据是否准确JNZ EXI AJMP EXITEXI: MOV 1CH,#0EXIT: SETB EA ;允许中断RETIYS1: MOV R4,#20 ;精确延时 882 微秒D1: MOV R5,#20 DJNZ R5,$DJNZ R4,D1 RETYS2: MOV R4,#10 ;精确延时 4740 微秒D2: MOV R5,#235 DJNZ R5,
15、$DJNZ R4,D2 RETTAB: DB 60H,7DH,0D0H,58H,4DHDB 4AH,42H,7CH,40H,48HTAB1B 0CH,09H,1DH,1FH,0DHDB 19H,1BH,11H,15H,17HEND;TAB LED 数码管显示表 TAB1键值表2005-1-14#219:37sina3228高级会员红外线程序编码为uPD6121G(或者是 HT622、7461 等)为例来说明这里以红外线用单片机实现红外的详细过程,站长琢磨这个程序花了相当多的精力,期间几经修改逐步完善,后来还用它开发了几个小产品,希望能对网友学习单片机有所帮助。红外线是目前使用最广泛的一种通信和
16、。由于红外线机之后,在装置具有体积小、功耗低、功能强、成本特点,因而,继彩电、机、音响设备、积分 354发贴 67空凋机以及玩具等其它小型电器装置上也纷纷采用红外线。工业设备中,在高压、辐射、气体、粉尘等环境下,采用红外线不仅完全可靠而且能有效地电气男2004-9-8来自 理工学院电子 2 班状态 离线干扰。1 红外系统系统由发射和接收两大部分组成,应用编/通用红外集成电路来进行控 制操作,如图 1 所示。发射部分包括键盘矩阵、编码调制、LED 红外发送器;接收部分包括光、电转换放大器、解调、电路。2及其编码很多,根据编码格式可以分成两大类,这里以运用比较广泛,比较容易的一类来加以说明,现以
17、NEC 的uPD6121G 组成发射电路为例说明编 码原理。当按键按下后,即有码发出,所按的键不同编码也不同。这种码具有以下特征:采用脉宽调制的串行码,以脉宽为 0.565ms、间隔 0.56ms、周期为 1.125ms 的组合表示二进制的“0”;以脉宽为 0.565ms、间隔 1.685ms、周期为 2.25ms 的组合表示二进制的“1”其波形如图 2 所示。上述“0”和“1”组成的 32 位二进制码经 38kHz 的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空间发射,如图 3 所示UPD6121G 产生的编码是连续的 32 位二进制码组,其
18、中前 16 位为用户识别码,能区别不同的电器设备,防止不同机种码互相干扰。该的用户识别码固定为十六 进制 01H;后 16 位为 8 位操作码(功能码)及其反码。UPD6121G 最多额 128 种不同组合的编码。在按键按下后,周期性地发出同一种 32 位二进制码,周期约为 108ms。一组码本身的持续时间随它包含的二进制“0”和“1”的个数不同而不同,大4563ms 之间,图4 为发射波形图。当一个键按下超过 36ms,振荡器使激活,将发射一组 108ms 的编码脉冲,这 108ms发射代码由一个起始码(9ms),一个结果码(4.5ms),低 8 位地址码(9ms18ms),高8 位地址码(
19、9ms18ms),8 位数据码(9ms18ms)和这 8 位数据的反码(9ms18ms组成。如果键按下超过 108ms 仍未松开,接下来发射的代码(连发代码)将仅由起始码(9ms)和结束码(2.5ms)组成。代码格式(以接收代码为准,接收代码与发射代码反向)位定义单发代码格式连发代码格式注:代码宽度算法:16 位地址码的最短宽度:1.1216=18ms 16 位地址码的最长宽度:2.24ms16=36ms8 位数据代码及其 8 位反代码的宽度和不变:(1.12ms+2.24ms)8=27ms32 位代码的宽度为(18ms+27ms)(36ms+27ms)1 的关键是如何识别“0”和“1”,从位
20、的定义 可以发现“0”、“1”均以 0.56ms 的低电平开始,不同的是 的宽度不同,“0”为 0.56ms,“1”为 1.68ms,所以必须根据高电平的宽度区别“0”和“1”。如果从 0.56ms 低电平过后,开始延时,0.56ms 以后,若读到的电平为低,说明该位为“0”,反之则为“1”,为了可靠起见,延时必须比 0.56ms 长些但又 过 1.12ms, 否则如果该位为“0”,读到的已是下一位的 ,因此取(1.12ms+0.56ms)/2=0.84ms 最为可靠,一般取 0.84ms 左右均可。2 根据码的格式,应该等待 9ms 的起始码和 4.5ms 的结果码完成后才能读码。如果邮购
21、开发的 51 单片机试验板和扩展元件的网友,可以获得如上图所示的红外遥控手柄,这种 的编码格式符合上面的描述规律,而且价格低廉,有 32 个按键,按键外形比较 ,如果用于批量开发,可以把 上贴膜换成你需要的字符,这为开发产品提供了便利。及红外线 是一种集红外线接收和放大于一体,不需要任何外接元件,就能完成从红外线接收到输出与 TTL 电平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线 和红外线数据传输。下面是一个对 51 实验板配套的红外线的程序,它可以把上图 32 键的红外遥控器每一个按键的键值读出来,并且通过实验板上 P1 口的 8 个 LED 显示出来,在成功的
22、同时并且能发出“嘀嘀嘀”的提示音。这是站长用单片机AT89C51 制作的 30 路红外,就是自家的VCD器,接收板用了 5 片CD4069 作为输出缓冲,当按下30 个按键中的一个,接收板对应的一个触点会变成,松开按键,立即恢复成低电平,和 TTL 兼容。2005-1-1 #4 19:423sina3228红外原理及程序高级会员积分 354发贴 67 男2004-9-8来自 理工学院 电子红外一开始发送一段 13.5ms 的引导码,引导码由 9ms 的和 4.5ms 的低电平组成,跟着引导码是系统码,系统反码,按键码,按键反码,如果按着键不放则则发送一段重复码,重复码由 9ms 的,2.25m
23、s 的低电平,跟着是一个短脉冲,本程序经过试用,能解大部分的编码!#include at89x52.h#define NULL 0 x00/数据无效 #define RESET 0X01/程序复位 #define REQUEST 0X02/请求信号#define ACK 0 x03/应答信号,在接收数据后发送 ACK 信号表示数据接收正确,也位请求信号的应答信号#define NACK 0 x04/应答信号,表示接收数据错误 #define BUSY 0 x05/忙信号,表示正在忙2 班#define FREE 0 x06/空闲信号,表示处于空闲状态 #define READ_IR 0 x0b
24、/红外#define STORE_IR 0 x0c/保存数据 #define READ_KEY 0 x0d/键值#define RECEIVE 0Xf400/接收缓冲开始地址 #defiND 0 xfa00/发送缓冲开始地址 #define IR 0 x50/红外接收缓冲开始地址 #define HEAD 0 xaa/数据帧头#define TAIL 0 x55/数据帧尾 #define SDA P1_7#define SCL P1_6unsigned char xdata *buf1; /接受数据缓冲 unsignedbuf1_length; /接收到的数据实际长度 unsigned cha
25、r xdata *buf2; /发送数据缓冲 unsignedbuf2_length; /要发送的数据实际长度bit buf1_flag; /接收标志,1 表示接受到一个数据帧,0 表示没有接受到数据帧或数据帧为空bit buf2_flag; /发送标志,1 表示需要发送或没发送完毕,0 表示没有要发送的数据或发送完毕unsigned char se1,se2; /用来标志接收字符的状态,se1 用来表示接收状态 离线状态,se2 用来表示发送状态unsigned char data *ir; unionunsigned char a2;unsigned b; unsigned char da
26、ta *p12;unsigneddata *p22;unsigned char xdata *p3; /红外缓冲的指针 unsignedxdata *p4;p;/union / unsigned char a2; / unsigned b;/ unsigned char data *p12;/ unsigneddata *p22;/ unsigned char xdata *p3;/ unsignedxdata *p4; /地址指针/q; /unionunsigned char a2;unsignedcount; unionunsigned char a2; unsignedb;temp; u
27、nionunsigned char a4; unsignedb2; unsigned long c;ir_code;unionunsigned char a4;unsigned b2; unsigned long c;unsigned char data *p14; unsigneddata *p24; unsigned char xdata *p32;unsigned xdata *p42;i;unsigned char ir_key;bit ir_flag; /红外接收标志,0 为缓冲区空,1 为接收成功,2 为缓冲溢出void sub(void); void delay(void); v
28、oid ie_0(void); void tf_0(void); void ie_1(void); void tf_1(void); void tf_2(void); void read_ir(void); void ir_jiema(void); void ir_init(void); void ir_exit(void); void store_ir(void);void read_key(void); void reset_iic(void);unsigned char read_byte_ack_iic(void); unsigned char read_byte_nack_iic(v
29、oid); bit write_byte_iic(unsigned char a);void send_ack_iic(void); void send_nack_iic(void); bit receive_ack_iic(void); void start_iic(void);b;void stop_iic(void);void write_key_data(unsigned char a);unsignedread_key_data(unsigned char a);void ie0(void) void tf0(void) void ie1(void) void tf1(void)vo
30、id tf2(void)errupt 0ie_0();errupt 1tf_0();errupt 2ie_1(); errupt 3tf_1();tf_2();errupt 5 /采用中断方式跟查询方式相结合的办法EA=0; /中断if(TF2) /判断是否是溢出还是电平变化产生的中断TF2=0; /如果是溢出产生的中断则清除溢出位,重新开放中断退出 EA=1;goto end;EXF2=0; /清除电平变化产生的中断位*ir=RCAP2H; /把捕捉的数保存起来 ir+;*ir=RCAP2L;*ir+; F0=1;TR0=1; /开启计数器 0 loop:TL0=0; /将计数器 0 重新置
31、为零TH0=0;while(!EXF2) /查询等待 EXF2 变为 1if(TF0)goto exit; /检查有没超时,如果超时则退出;EXF2=0; /将EXF2 清零if(!TH0) /判断是否是长低电平脉冲过来了 /不是长低电平脉冲而是短低电平 if(F0)count.b+; /短脉冲数加一 temp.a0=RCAP2H; /将捕捉数临时存放起来 temp.a1=RCAP2L;goto loop; /返回继续查询else /是低电平脉冲,则进行处理F0=0; *ir=temp.a0; /把连续的短脉冲总时间下来ir+;*ir=temp.a1; ir+; *ir=RCAP2H; /把长
32、电平脉冲时间下来ir+;*ir=RCAP2L;ir+; if(ir=0 xda) goto exit; /判断是否溢出缓冲,如果溢出则失败退出goto loop; /返回继续查询exit:ir_flag=1; /置 ir_flag 为 1 表示接收成功end:;void rs232(void)errupt 4sic unsigned char sbuf1,sbuf2,rsbuf1,rsbuf2; /sbuf1,sbuf2 用来接收发送临时用,rsbuf1,rsbuf2 用来分别用来存放接收发送的半字节EA=0; /中断if(RI)RI=0; /清除接收中断标志位sbuf1=SBUF; /将接收
33、缓冲的字符到sbuf1if(sbuf1=HEAD) /判断是否帧开头se1=10; /是则把 se 赋值为 10buf1=RECEIVE; /初始化接收地址elseswitch(se1)case 10:sbuf2=sbuf14; /把高半字节右移到的半字节 sbuf2=sbuf2; /把低半字节取反 if(sbuf2&0 x0f)!=(sbuf1&0 x0f) /判断接收是否正确 /接收错误,有可能接收的是数据帧尾,也有可能是接收错误 if(sbuf1=TAIL) /判断是否接收到数据帧尾 /是接收到数据帧尾 buf1=RECEIVE; /初始化接收的地址if(*buf1=RESET) /判断
34、是否为复位命令 ES=0;sbuf2=SP+1;for(p.p10=SP-0 x10;p.p104; /把高半字节右移到的半字节 sbuf2=sbuf2; /将低半字节取反 if(sbuf2&0 x0f)!=(sbuf1&0 x0f) /判断接收是否正确 /接受错误se1=0; / 将接收状态标志置为零,重新接收buf1=RECEIVE; /初始化接收的地址*buf1=NACK; /把NACK 信号存入发送缓冲里buf1_flag=1; /置标志位为 1,使主程序能对接收错误进行处理REN=0; /接收elsesbuf1&=0 x0f; /仅保留低半字节,去掉高半字节 rsbuf1|=sbuf
35、1; /高低半字节合并*buf1+=rsbuf1; /将接收的数据保存至接收缓冲里,并且数据指针加一 buf1_length+; /接收数据长度加一se1=10; /将se1 置为 10,准备接收下个字节的高半字节break;elseTI=0; /清除发送中断标志 if(buf2_length) /判断发送长度是否为零 /发送长度不为零if(se2=0) /判断是否发送高半字节 /发送高半字节sbuf2=*buf2; /将要发送的字节送到 sbuf2 rsbuf2=sbuf2; /取反,使高半字节变为反码 sbuf2=4; /将高半字节右移到低半字节 rsbuf2&=0 xf0; /保留高半字
36、节,去掉低半字节 sbuf2&=0 x0f; /保留低半字节,去掉高半字节 rsbuf2|=sbuf2; /合并高低半字节 SBUF=rsbuf2; /发送出去se2=10; /将se2 置为 10 准备发送下半字节else /发送低半字节sbuf2=*buf2; /将要发送的字节送到 sbuf2 buf2+; /指针加一buf2_length-; /发送数据长度减一 rsbuf2=sbuf2; /取反,使低半字节变为反码rsbuf2=4; /将低半字节反码到高半字节rsbuf2&=0 xf0; /保留高半字节,去掉低半字节 sbuf2&=0 x0f; /保留低半字节,去掉高半字节 rsbuf
37、2|=sbuf2; /合并高低半字节 SBUF=rsbuf2; /发送出se2=0;else /如果发送数据长度为零则发送数据帧尾 if(buf2_flag) /判断是否发过数据帧尾 SBUF=TAIL; /将数据帧尾发送出去 while(TI=0);TI=0;buf2_flag=0; /置发送标志为零,表示发送完毕EA=1; /开放中断void ack(void) /发送ACK 信号子程序buf1_flag=0; /置接收标志位位零表示已经相应了,可以接收下一帧数据 REN=1; /接收使能whiuf2_flag); /判断上一帧有没发送完,没有则继续等待 buf2=SEND; /初始化发送
38、地址*buf2=ACK; /将 ACK 信号存入发送缓冲里 buf2_length=1; /存入发送数据长度 buf2_flag=1; /置发送长度为 1 SBUF=HEAD; /发送数据帧头void nack(void) /发送 NACK 信号子程序buf1_flag=0; /置接收标志位位零表示已经相应了,可以接收下一帧数据 REN=1; /接收使能whibuf2=S*buf2= buf2_len buf2_fl SBUF=void frebuf1_fl REN=1whi buf2=S*buf2= buf2_len buf2_fl SBUF=void bubuf1_fl REN=1whiu
39、f2_flag); /判断上一帧有没发送完,没有则继续等待END; /初始化发送地址NACK; /将NACK 信号存入发送缓冲里gth=1; /存入发送数据长度 ag=1; /置发送长度为 1 HEAD; /发送数据帧头e(void) /发送FREE 信号子程序ag=0; /置接收标志位位零表示已经相应了,可以接收下一帧数据; /接收使能uf2_flag); /判断上一帧有没发送完,没有则继续等待 END; /初始化发送地址FREE; /将 FREE 信号存入发送缓冲里gth=1; /存入发送数据长度 ag=1; /置发送长度为 1 HEAD; /发送数据帧头sy(void) /发送BUSY
40、信号子程序ag=0; /置接收标志位位零表示已经相应了,可以接收下一帧数据; /接收使能uf2_flag); /判断上一帧有没发送完,没有则继续等待buf2=SEND; /初始化发送地址*buf2=BUSY; /将BUSY 信号存入发送缓冲里 buf2_length=1; /存入发送数据长度 buf2_flag=1; /置发送长度为 1 SBUF=HEAD; /发送数据帧头void download(void)i; /用于循环计数i=buf1_length-3; /数据长度等于数据包长度减去一个字节控制字和两个字节地址buf1=RECEIVE+1; /使指针指向地址 p.a0=*buf1+;
41、/读入目标地址高字节 p.a1=*buf1+; /读入目标地址低字节 while(i-) /长度减一直至为零*p.p3+=*buf1+; /将接受缓冲里数据送到目标地址,并且两个指针加一REN=1; /数据处理完,允许接收下一帧数据 buf1_flag=0; /置接收标志为零,表示已经处理完 free(); /发送 FREE 信号表示已经处理完处于空闲状态void upload(void)i; / whiuf2_flag); /判断上一帧有没发送完,没有则继续等待buf1=RECEIVE+1; /将指针指向地址 buf2=SEND; /初始化发送地址*buf2+=UPLOAD; /把控制字存进
42、去并且指针加一*buf2+=*buf1+; /把地址高字节过去*buf2+=*buf1+; /把地址低字节过去p.a0=*buf1+; /把数据长度高字节过去p.a1=*buf1+; /把数据长度低字节过去i=p.b; /把数据长度过去buf1-=4; /将指针减 4,使其指向地址处 p.a0=*buf1+; /把地址高字节过去 p.a1=*buf1+; /把地址低字节过去 buf1_flag=0; /已经对接受数据处理完毕 REN=1; /允许接收buf2_length=i+3; /数据包长度等于数据长度加 3while(i-) /判断数据长度是否为零,为零则不执行循环语句,同时长度减一*b
43、uf2+=*p.p3+; /把数据到发送缓冲区buf2=SEND;buf2_flag=1; /置发送标志为 1 SBUF=HEAD; /发送数据帧头void run(void) /运行的程序sub();void delay1s(void)for(i.b0=0;i.b00 x f;i.b0+)i.b0=i.b0+; i.b0=i.b0-;void ir_init(void)ir_flag=0; /将红外接收标志置为零 for(ir=IR;iri.b1)i.b0=0 x f-i.b0;i.b0+=i.b1; i.b0+;elsei.b0=i.b1-i.b0;*p.p20=i.b0; p.p20+;
44、i.b0=*p.p20;p.p21+;i.b1=*p.p21;*p.p20=0;p.p20=IR;temp.b=*p.p20; ir_code.c=count.b;ir_code.b0=(ir_code.c*1536000)/temp.b;for(;temp.b!=0*p.p20=temp.b/154; p.p20+;temp.b=*p.p20;ir_code.b1=0; if(p.p20=IR+132) p.p20=IR;p.p20+=3;i.c=0; temp.b=*p.p20;for(;temp.b!=0 i.c=11) i.a3+; p.p20+=2;temp.b=*p.p20;if(
45、i.a0=(i.a1)&i.a2=(i.a3) ir_code.a2=i.a0;ir_code.a3=i.a2;else ir_code.b0=0;else if(p.p20=IR+4) p.p20=IR;p.p20+;temp.b=*p.p20; if(temp.b=30) ir_code.b0=1;else ir_code.b0=0;else ir_code.b0=2;/if(ir_flag=2)ir_code.b0=3;void read_ir(void) buf1_flag=0; REN=1;buf2_length=4;whiuf2_flag); ir_init();while(!ir
46、_flag); ir_exit(); ir_jiema(); buf2=SEND;*buf2+=ir_code.a0;*buf2+=ir_code.a1;*buf2+=ir_code.a2;*buf2=ir_code.a3; buf2=SEND; buf2_flag=1; SBUF=HEAD;void delay(void)void start_iic(void) SCL=0;SDA=1;delay();delay(); SCL=1;delay(); SDA=0;delay(); SCL=0;delay();void stop_iic(void) SDA=0;delay(); SCL=1;de
47、lay(); SDA=1;delay(); SCL=0;delay();delay(); SCL=1;delay();void send_ack_iic(void) SDA=0;delay(); SCL=1;delay();delay(); SCL=0;delay();void send_nack_iic(void) SDA=1;delay(); SCL=1;delay();delay(); SCL=0;delay();bit receive_ack_iic(void) bit a;SDA=1;delay(); SCL=1;delay(); if(SDA) a=1;else a=0; dela
48、y(); SCL=0;delay(); return a;unsigned char read_byte_ack_iic(void) unsigned char a;SDA=1; for(p.a0=0;p.a08;p.a0+)a=1;delay(); SCL=1;delay(); if(SDA) a+;delay(); SCL=0;delay();send_ack_iic(); return a;unsigned char read_byte_nack_iic(void) unsigned char a;SDA=1; for(p.a0=0;p.a08;p.a0+) a=1;delay(); S
49、CL=1;delay(); if(SDA) a+;delay(); SCL=0;delay();send_nack_iic(); return a;void reset_iic(void) SDA=1;for(p.a0=0;p.a010;p.a0+) SCL=0;delay();delay(); SCL=1;delay();delay();bit write_byte_iic(unsigned char a) for(p.a0=0;p.a08;p.a0+)if(a&0 x80) SDA=1;else SDA=0;delay(); SCL=1;delay();delay(); SCL=0;del
50、ay(); a=1;return receive_ack_iic(); unsigned read_key_data(unsigned char a) unionunsigned char a2; unsigned b;key_data; reset_iic(); start_iic(); write_byte_iic(0 xa0); write_byte_iic(a); start_iic(); write_byte_iic(0 xa1);key_data.a0=read_byte_ack_iic(); key_data.a1=read_byte_nack_iic(); stop_iic()
51、;return key_data.b;void write_key_data(unsigned char a) reset_iic();start_iic(); write_byte_iic(0 xa0); write_byte_iic(a); write_byte_iic(ir_code.a2); write_byte_iic(ir_code.a3); stop_iic();void store_ir(void) buf1_flag=0; REN=1; buf1=RECEIVE+1;*buf1=(*buf1)1; write_key_data(*buf1);unsigned char yim
52、a(void) unsigned char a;for(a=0;a=1;return a;void read_key() unsigned char a; buf1_flag=0; REN=1;ir_init(); while(!ir_flag); ir_exit(); ir_jiema(); buf2=SEND; a=yima(); if(a=50)*buf2=0 xff;else *buf2=a; buf2_length=1; buf2_flag=1; SBUF=HEAD;main()unsigned char ctr; delay1s(); P0=0 xff; P1=0 xff; P2=
53、0 xff; P3=0 xff;ctr=0; buf1=RECEIVE; buf2=SEND; buf1_length=0; buf2_length=0; buf1_flag=0; buf2_flag=0;se1=0; se2=0;SP=0 xe0; /将堆栈指针指向高端TL2=0 xfb;TH2=0 xff; /溢出值为 5,波特率为 115.2Kbps; RCAP2H=0 xff;RCAP2L=0 xfb;SCON=0 x50; /方式 1,8 位方式,SM0=0,SM1=1,SM2=0,REN=1 允许接收IE=0 x10; /串行中断允许,全局中断不允许 T2CON=0 x34; /R
54、CLK=1,TCLK=1,TR2=1 启动计数器EA=1; /开放全局中断 free();while(1)/ir_init();/while(!ir_flag);/ir_exit();/ir_jiema();/if(yima()=0) P1_0=1;/if(yima()=1) P1_0=0;if(buf1_flag) buf1=RECEIVE;ctr=*buf1;switch(ctr) case ACK: ack(); break;case NACK: nack(); break;case FREE: free(); break;case BUSY: busy(); break;case DO
55、WNLOAD: download(); break;case UPLOAD: upload(); break;case RUN: run(); break;case READ_IR: read_ir(); break;case READ_KEY: read_key(); break;case STORE_IR: store_ir(); break;default: buf1_flag=0; REN=1;break;void sub(void)void ie_0(void)void tf_0(void)void ie_1(void)void tf_1(void)void tf_2(void)20
56、05-1-14#419:45sina3228高级会员红外线读码机源程序和说明;红外线读码机,用本实例配合 PIC 单片机的 ST 套件可读出任何 6121 或6122(CD6121/CD6122/SC6121/SC6122)及其兼容码。的红外线的用户码、键;本例是一个红外线扫描程序,程序中数码管显示用的是定时器中断法的动态接收 ;动态显示二位数码管的方法,中断法,流点亮。 ;对准实验板红外线接收头轻按要测定的码管将显示该键的键码,以 3MS 中断一次从而交换两位数码管轮的待测按键一次,此时实验板的两位数积分 354发贴 67男2004-9-8来自 理工学院 电子 2 班状态 离线 ;(显示为1
57、6 进制的),轻触实验板的S2 此时显示器切换为显示当前用户码的低8位, 再次轻触实验板的 S2 此时显示器切换为显示当前用户码的高 8 位,;再一次轻触实验板的 S2 此时显示又回到显示当前键的键码,用按键 S2 可反复循环显示用户码低 8 位、高 8 位、键码。;注意:所有的显示均为 16 进制,A显示为A,B显示为b,C显示为c,D显示为d,E显示为E,F显示为F.;注意6121 的发射码依次为:同步头(引导码)+32 位数据码(用户码低8 位+用户码高 8 位+键码+键码的反码);引导码是由 9MS 的低电平加 4.5MS 的加 4.5MS 的低电平,接收到的刚好反相为 9MS 的.;
58、数据码0是由 560US 的电平加 560US 的;数据码1是由 560US 的电平加 1.69MS 的加 560US 的低电平,接收时反相为 560US 的低.加 1.69MS 的,接收时反相为 560US 的低.;PIC 单片机;程序文件名:“ST-RMT.ASMht;烧写时应注意:配置位已经在程序中写明,加载HEX 文件时会自动加载,烧写时不用再手动设置配置位。;实验时请注意套件跳线选择;;* LIST P=16F84A,R=DEC ;定义器件为 16F84,默认数制为十进制; CONFIG B11111111110001;_CP_OFF&_WDT_OFF&_PWRITE_ON&_XT_
59、OSC;没有代码保护;看门狗关闭;上电廷时器开启;振荡器模式为 XT;RTCCEQU 01HPCEQU 02H;定义定时器 0 地址;定义程序计数器低字节寄存器地址;定义状态寄存器地址;定义RA 口数据寄存器地址;定义RB 口数据寄存器地址SUS EQU 03HPORTA EQU 05HPORTB EQU 06HCON EQU 0BH;定义中断控制寄存器OPTION_REG EQU 81H;定义 RA 口方向控制寄存器;定义RB 口方向控制寄存器TRISATRISBEQU 85HEQU 86H;SUS;定义进位标志位位地址;定义 0 标志位位地址;寄存器体选 CON;定时器 0 溢出中断标志位
60、;定时器 0 溢出中断允许/;总中断允许/C ZRP0;EQU 0EQU 2EQU 5T0IF T0IE GIE;EQU 2EQU 5EQU 7RMT;EQU 4;接收输入脚位地址(RA。4)BITIN;EQU 7;接收数据位位标志CNT0 CNT1 CNT2 CNT3 TABADD FLAGSDISPBUF_H DISPBUF_LW_TEMPEQU 20H EQU 21H EQU 22H EQU 23HEQU 24H EQU 25HEQU 26H EQU 27HEQU 2BH;用户临时寄存器 1;用户临时寄存器 2;用户临时寄存器 3;用户临时寄存器 4;数码管显示码取码用寄存器;显示位选标
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- PHP基础综合试题及答案
- Photoshop 2026 期末考试试题及详细参考答案
- 2025-2026学年内蒙古自治区满洲里市初中政治七年级期末上册高分专项攻坚题(附答案)
- PCR检验技术考核试题(含详细答案)
- 景观水体循环及水质维护方案
- 环境水质检测安全操作规程
- 2025-2026学年黑龙江省伊春市初中生物七年级期末上册模考黑金试题详细参考解析
- PaaS面试题及详细答案(实操完整版)
- 三叉神经痛微创术后复发预警监测共识
- 医疗器械不良事件培训试题及答案
- 长征胜利纪念日综合实践活动课件
- 2026年福建省高考物理试卷真题(含答案及解析)
- 2026年全国新闻记者职业资格考试(新闻采编实务)冲刺试题及答案
- DB65T5067-2026村庄规划编制技术规程
- 2026年全国保密教育线上培训考试试题库(全优)附答案详解
- 新版部编人教版六年级上册道德与法治全册教案(完整版)教学设计
- 《热学(第二版)》杨体强编-李椿 第9章 相变学习资料
- 《基于SPSS的物流服务质量对生鲜产品复购意愿的影响实证探究(附问卷)》20000字(论文)
- 国家自然科学基金申报培训
- 电机与电气控制技术 - 期末考试题库及答案
- 《基于Tanner的集成电路版图设计技术》课件第三章 Tanner的S-Edit(电路图编辑器)
评论
0/150
提交评论