📄 红外线遥控器解码程序 汇编语言 经典说明.htm
字号:
3{tf_1();tf_2();}<BR>void tf2(void) interrupt 5{
//采用中断方式跟查询方式相结合的办法解码<BR>EA=0; //禁止中断<BR>if(TF2){
//判断是否是溢出还是电平变化产生的中断<BR>TF2=0;
//如果是溢出产生的中断则清除溢出位,重新开放中断退出<BR>EA=1;<BR>goto
end;<BR>}<BR>EXF2=0; //清除电平变化产生的中断位<BR>*ir=RCAP2H;
//把捕捉的数保存起来<BR>ir++;<BR>*ir=RCAP2L;<BR>*ir++;<BR>F0=1;<BR>TR0=1;
//开启计数器0<BR>loop:<BR>TL0=0;
//将计数器0重新置为零<BR>TH0=0;<BR>while(!EXF2){
//查询等待EXF2变为1<BR>if(TF0)goto exit;
//检查有没超时,如果超时则退出<BR>};<BR>EXF2=0; //将EXF2清零<BR>if(!TH0)
//判断是否是长低电平脉冲过来了<BR>{
//不是长低电平脉冲而是短低电平<BR>if(F0)count.b++;
//短脉冲数加一<BR>temp.a[0]=RCAP2H;
//将捕捉数临时存放起来<BR>temp.a[1]=RCAP2L;<BR>goto loop;
//返回继续查询<BR>}<BR>else{
//是低电平脉冲,则进行处理<BR><BR>F0=0;<BR>*ir=temp.a[0];
//把连续的短脉冲总时间记录下来<BR>ir++;<BR>*ir=temp.a[1];<BR>ir++;<BR>*ir=RCAP2H;
//把长电平脉冲时间记录下来<BR>ir++;<BR>*ir=RCAP2L;<BR>ir++;<BR>if(ir>=0xda)
{<BR>goto exit; //判断是否溢出缓冲,如果溢出则失败退出<BR>}<BR>goto loop;
//返回继续查询<BR>}<BR>exit:<BR>ir_flag=1;
//置ir_flag为1表示接收成功<BR>end:<BR>;<BR>}<BR><BR><BR>void
rs232(void) interrupt 4{<BR>static unsigned char
sbuf1,sbuf2,rsbuf1,rsbuf2;
//sbuf1,sbuf2用来接收发送临时用,rsbuf1,rsbuf2用来分别用来存放接收发送的半字节<BR>EA=0;
//禁止中断<BR>if(RI){<BR>RI=0; //清除接收中断标志位<BR>sbuf1=SBUF;
//将接收缓冲的字符复制到sbuf1<BR>if(sbuf1==HEAD){
//判断是否帧开头<BR>state1=10; //是则把state赋值为10<BR>buf1=RECEIVE;
//初始化接收地址 <BR>}<BR>else{<BR>switch(state1){<BR>case
10:sbuf2=sbuf1>>4; //把高半字节右移到的半字节<BR>sbuf2=~sbuf2;
//把低半字节取反<BR>if((sbuf2&0x0f)!=(sbuf1&0x0f))
//判断接收是否正确<BR>{
//接收错误,有可能接收的是数据帧尾,也有可能是接收错误<BR>if(sbuf1==TAIL)
//判断是否接收到数据帧尾<BR>{ //是接收到数据帧尾<BR>buf1=RECEIVE;
//初始化接收的地址<BR>if(*buf1==RESET)
//判断是否为复位命令<BR>{<BR>ES=0;<BR>sbuf2=SP+1;<BR>for(p.p1[0]=SP-0x10;p.p1[0]<=sbuf2;p.p1[0]++)*p.p1[0]=0;<BR>}<BR>state1=0;
//将接收状态标志置为零,接收下一个数据帧<BR>buf1_flag=1;
//置接收标志为1,表示已经接收到一个数据帧<BR>REN=0;
//禁止接收<BR>}<BR>else<BR>{ //不是接受到数据帧尾,表明接收错误<BR>state1=0;
// 将接收状态标志置为零,重新接收<BR>buf1=RECEIVE;
//初始化发送的地址<BR>*buf1=NACK;
//把NACK信号存入接收缓冲里<BR>buf1_flag=1;
//置标志位为1,使主程序能对接收错误进行处理<BR>REN=0;
//禁止接收<BR>}<BR><BR>}<BR>else<BR>{
//接收正确<BR>rsbuf1=~sbuf1;
//按位取反,使高半字节变原码<BR>rsbuf1&=0xf0;
//仅保留高半字节,低半字节去掉<BR>state1=20;
//将状态标志置为20,准备接收低半字节<BR>}<BR>break;<BR>case
20:sbuf2=sbuf1>>4; //把高半字节右移到的半字节<BR>sbuf2=~sbuf2;
//将低半字节取反<BR>if((sbuf2&0x0f)!=(sbuf1&0x0f))
//判断接收是否正确<BR>{ //接受错误<BR>state1=0; //
将接收状态标志置为零,重新接收<BR>buf1=RECEIVE;
//初始化接收的地址<BR>*buf1=NACK;
//把NACK信号存入发送缓冲里<BR>buf1_flag=1;
//置标志位为1,使主程序能对接收错误进行处理<BR>REN=0;
//禁止接收<BR>}<BR>else<BR>{<BR>sbuf1&=0x0f;
//仅保留低半字节,去掉高半字节<BR>rsbuf1|=sbuf1;
//高低半字节合并<BR>*buf1++=rsbuf1;
//将接收的数据保存至接收缓冲里,并且数据指针加一<BR>buf1_length++;
//接收数据长度加一<BR>state1=10;
//将state1置为10,准备接收下个字节的高半字节<BR>}<BR>break;<BR><BR>}<BR>}<BR><BR><BR><BR>}<BR>else{<BR><BR>TI=0;
//清除发送中断标志<BR>if(buf2_length) //判断发送长度是否为零<BR>{
//发送长度不为零<BR>if(state2==0) //判断是否发送高半字节<BR>{
//发送高半字节<BR>sbuf2=*buf2;
//将要发送的字节送到sbuf2<BR>rsbuf2=~sbuf2;
//取反,使高半字节变为反码<BR>sbuf2>>=4;
//将高半字节右移到低半字节<BR>rsbuf2&=0xf0;
//保留高半字节,去掉低半字节<BR>sbuf2&=0x0f;
//保留低半字节,去掉高半字节<BR>rsbuf2|=sbuf2;
//合并高低半字节<BR>SBUF=rsbuf2; //发送出去<BR>state2=10;
//将state2置为10准备发送下半字节<BR>}<BR>else<BR>{
//发送低半字节<BR>sbuf2=*buf2; //将要发送的字节送到sbuf2<BR>buf2++;
//指针加一<BR>buf2_length--; //发送数据长度减一<BR>rsbuf2=~sbuf2;
//取反,使低半字节变为反码<BR>rsbuf2<<=4;
//将低半字节反码左移到高半字节<BR>rsbuf2&=0xf0;
//保留高半字节,去掉低半字节<BR>sbuf2&=0x0f;
//保留低半字节,去掉高半字节<BR>rsbuf2|=sbuf2;
//合并高低半字节<BR>SBUF=rsbuf2;
//发送出<BR>state2=0;<BR>}<BR>}<BR>else<BR>{
//如果发送数据长度为零则发送数据帧尾<BR>if(buf2_flag){
//判断是否发过数据帧尾<BR>SBUF=TAIL;
//将数据帧尾发送出去<BR>while(TI==0);<BR>TI=0;<BR>buf2_flag=0;
//置发送标志为零,表示发送完毕<BR>}<BR>}<BR>}<BR>EA=1;
//开放中断<BR>}<BR><BR><BR><BR><BR><BR><BR>void ack(void)
//发送ACK信号子程序<BR>{<BR>buf1_flag=0;
//置接收标志位位零表示已经相应了,可以接收下一帧数据<BR>REN=1;
//接收使能<BR>while(buf2_flag);
//判断上一帧有没发送完,没有则继续等待<BR>buf2=SEND;
//初始化发送地址<BR>*buf2=ACK;
//将ACK信号存入发送缓冲里<BR>buf2_length=1;
//存入发送数据长度<BR>buf2_flag=1; //置发送长度为1<BR>SBUF=HEAD;
//发送数据帧头<BR>}<BR><BR>void nack(void)
//发送NACK信号子程序<BR>{<BR>buf1_flag=0;
//置接收标志位位零表示已经相应了,可以接收下一帧数据<BR>REN=1;
//接收使能<BR>while(buf2_flag);
//判断上一帧有没发送完,没有则继续等待<BR>buf2=SEND;
//初始化发送地址<BR>*buf2=NACK;
//将NACK信号存入发送缓冲里<BR>buf2_length=1;
//存入发送数据长度<BR>buf2_flag=1; //置发送长度为1<BR>SBUF=HEAD;
//发送数据帧头<BR>}<BR><BR>void free(void)
//发送FREE信号子程序<BR>{<BR>buf1_flag=0;
//置接收标志位位零表示已经相应了,可以接收下一帧数据<BR>REN=1;
//接收使能<BR>while(buf2_flag);
//判断上一帧有没发送完,没有则继续等待<BR>buf2=SEND;
//初始化发送地址<BR>*buf2=FREE;
//将FREE信号存入发送缓冲里<BR>buf2_length=1;
//存入发送数据长度<BR>buf2_flag=1; //置发送长度为1<BR>SBUF=HEAD;
//发送数据帧头<BR>}<BR><BR>void busy(void)
//发送BUSY信号子程序<BR>{<BR>buf1_flag=0;
//置接收标志位位零表示已经相应了,可以接收下一帧数据<BR>REN=1;
//接收使能<BR>while(buf2_flag);
//判断上一帧有没发送完,没有则继续等待<BR>buf2=SEND;
//初始化发送地址<BR>*buf2=BUSY;
//将BUSY信号存入发送缓冲里<BR>buf2_length=1;
//存入发送数据长度<BR>buf2_flag=1; //置发送长度为1<BR>SBUF=HEAD;
//发送数据帧头<BR>}<BR><BR>void download(void)<BR>{<BR>int i;
//用于循环计数<BR>i=buf1_length-3;
//数据长度等于数据包长度减去一个字节控制字和两个字节地址<BR>buf1=RECEIVE+1;
//使指针指向地址<BR>p.a[0]=*buf1++;
//读入目标地址高字节<BR>p.a[1]=*buf1++;
//读入目标地址低字节<BR>while(i--){
//长度减一直至为零<BR>*p.p3++=*buf1++;
//将接受缓冲里数据送到目标地址,并且两个指针加一<BR>}<BR>REN=1;
//数据处理完,允许接收下一帧数据<BR>buf1_flag=0;
//置接收标志为零,表示已经处理完<BR>free();
//发送FREE信号表示已经处理完处于空闲状态<BR><BR>}<BR><BR>void
upload(void){<BR>int i; //<BR>while(buf2_flag);
//判断上一帧有没发送完,没有则继续等待<BR>buf1=RECEIVE+1;
//将指针指向地址<BR>buf2=SEND; //初始化发送地址<BR>*buf2++=UPLOAD;
//把控制字存进去并且指针加一<BR>*buf2++=*buf1++;
//把地址高字节复制过去<BR>*buf2++=*buf1++;
//把地址低字节复制过去<BR>p.a[0]=*buf1++;
//把数据长度高字节复制过去<BR>p.a[1]=*buf1++;
//把数据长度低字节复制过去<BR>i=p.b; //把数据长度复制过去<BR>buf1-=4;
//将指针减4,使其指向地址处<BR>p.a[0]=*buf1++;
//把地址高字节复制过去<BR>p.a[1]=*buf1++;
//把地址低字节复制过去<BR>buf1_flag=0; //已经对接受数据处理完毕<BR>REN=1;
//允许接收<BR>buf2_length=i+3;
//数据包长度等于数据长度加3<BR>while(i--){
//判断数据长度是否为零,为零则不执行循环语句,同时长度减一<BR>*buf2++=*p.p3++;
//把数据复制到发送缓冲区<BR>}<BR>buf2=SEND;<BR>buf2_flag=1;
//置发送标志为1<BR>SBUF=HEAD; //发送数据帧头<BR>}<BR><BR>void
run(void)
//运行下载的程序<BR>{<BR>sub();<BR>}<BR><BR><BR><BR>void
delay1s(void){<BR>for(i.b[0]=0;i.b[0]<0xffff;i.b[0]++){<BR>i.b[0]=i.b[0]++;<BR>i.b[0]=i.b[0]--;}<BR>}<BR><BR>void
ir_init(void)<BR>{<BR>ir_flag=0;
//将红外接收标志置为零<BR>for(ir=IR;ir<0xe0;ir++){<BR>*ir=0;
//将红外接收缓冲清零<BR>}<BR>EA=0; //禁止中断<BR>ES=0;
//禁止串行中断<BR>ET2=1; //允许T2中断<BR>ir=IR;
//初始化红外数据指针<BR>TR0=0; //禁止计数<BR>TH0=0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -