红外解码 程序 c51
红外遥控编码原理及C程序,51单片机红外遥控
![红外遥控编码原理及C程序,51单片机红外遥控](https://img.taocdn.com/s3/m/0c9f5450c1c708a1294a4485.png)
case 0x19:j=1;//100+
break;
case 0x0d:k=1;//200+
break;
case 0x16:l=1;//0
break;
case 0x0c:m=1;//1
{
temp=temp>>1; //最先读出的是高位数据
dingshiqi();//定时器记高低电平时间,数据码
if((HighTime>300)&&(HighTime<900)) //说明该位是0
temp=temp&0x7f;
if((HighTime>1200)&&(HighTime<2200)) //说明该位是1
uchar code table1[]={"User Code:"};
void delay(uint x)
{
uint i,j;
for(i=x;i>0;i--)//i=xms即延时约xms毫秒
for(j=100;j>0;j--);
}
void write_com(uchar com)
{//写液晶命令函数
{
a=0;b=0;c=0;d=0;
e=0;f=0;g=0;h=0;
i=0;j=0;k=0;l=0;
m=0;n=0;o=0;p=0;
q=0;r=0;s=0;t=0;
u=0;
}
void init_1602()
{//初始化函数
uchar num;
lcden=0;
rs=0;
write_com(0x38);//1602液晶初始化
while(1)
基于51单片机的NEC红外解码C语言程序
![基于51单片机的NEC红外解码C语言程序](https://img.taocdn.com/s3/m/ee0879b3dc3383c4bb4cf7ec4afe04a1b071b0d9.png)
基于51单片机的NEC红外解码C语言程序#includetypedef unsigned intuint ;typedef unsigned char uchar ;#define Main_fosc 11059200ULsbitIR_test = P3^2;sbit du = P2^6;sbit we = P2^7;ucharDat[33],Number[4],counter,Receive_ok;/*-----------函数声明------------*/voidIR_init();void translate();void display(uchar *n);voidDelay_ms(uintnum);/*-------------------------------*/uchar table[]={0x3F, //"0"0x06, //"1"0x5B, //"2"0x4F, //"3"0x66, //"4"0x6D, //"5"0x7D, //"6"0x07, //"7"0x7F, //"8"0x6F, //"9"0x77, //"A"0x7C, //"B"0x39, //"C"0x5E, //"D"0x79, //"E"0x71, //"F"};void main(){IR_init();while(1){if(Receive_ok)translate();display(Number);}}voidIR_init(){TMOD = 0X02;TH0 = 0xa4;TL0 = 0xa4;EA = 1;ET0 = 1;TR0 = 1;EX0 = 1;IT0 = 1; //下降沿触发}void timer0()interrupt 1 {counter++; // 100us}/*------红外接收中断------*/voidIR_read() interrupt 0{static bit start_flag = 0;static char i=1;if(start_flag){if(counter>=125&&counter<=145) {counter = 0;Dat[0] = 1;}else if(Dat[0] == 1){if(counter>14)Dat[i] = 1;elseDat[i] = 0;counter = 0;i++;if(i==33){Dat[0] = 0;Receive_ok = 1;start_flag = 0;i = 1;}}else{start_flag = 0;}}else{counter = 0;start_flag = 1;}}/*----------解码---------*/ void translate(){uchari,j;for(i=0;i<4;i++)for(j=0;j<8;j++){Number[i]>>=1;if(Dat[i*8+j+1]) Number[i] |= 0x80;}Receive_ok = 0;}/*------数码管显示------*/ void display(uchar *n) {uchar a[8],i;a[0] = n[0]/16;a[1] = n[0]%16;a[2] = n[1]/16;a[3] = n[1]%16;a[4] = n[2]/16;a[5] = n[2]%16;a[6] = n[3]/16;a[7] = n[3]%16;for(i=0;i<8;i++){we = 1;switch(i){case 0:P0 = 0xfe;break; //1111 1110 case 1:P0 = 0xfd;break; //1111 1101 case 2:P0 = 0xfb;break; //1111 1011 case 3:P0 = 0xf7;break; //1111 0111 case 4:P0 = 0xef;break; //1110 1111 case 5:P0 = 0xdf;break; //1101 1111 case 6:P0 = 0xbf;break; //1011 1111 case 7:P0 = 0x7f;break; //0111 1111 }we = 0;du = 1;P0 = table[a[i]];du = 0;Delay_ms(1);}}/*---------延时1MS----------*/ voidDelay_ms(uintnum){uint i;do{i = Main_fosc/96000;while(i--);}while(--num); }。
学习型红外线遥控程序——C51
![学习型红外线遥控程序——C51](https://img.taocdn.com/s3/m/b94becf777a20029bd64783e0912a21614797fa1.png)
学习型红外线遥控程序——C51学习型红外线遥控程序——C51/*************晶体为11.0592M,波特率9600bps***************学习型红外线遥控程序*******/#include <AT89X51.H>void Ewen(void);void Ewds(void);void Delay(void);void Irda(void);void Study(void);void Output(unsigned int h);void Comput(unsigned char outdata);void Erase(unsigned char Address);unsigned int Read(unsigned char Address);unsigned char Display(unsigned char inAddress);void Write(unsigned char Address,unsigned int InData);unsigned int Both(unsigned char data1,unsigned char data2);unsigned char data e1 _at_ 0x1A; //分别存放红外线译码后的数据unsigned char data w1 _at_ 0x1B;unsigned char data e2 _at_ 0x1C;unsigned char data w2 _at_ 0x1D;sbit IrInput=P3^2; //红外线输入引脚,可自定义sbit Study1=P3^6; //学习按键,可自定义sbit Led2=P2^5; //接收成功、学习成功指示sbit Led1=P2^6; //空闲指示sbit Dout=P2^3; //at93c16--DOsbit Din=P2^2; //at93c16--DIsbit sk=P2^1; //at93c16--SKsbit cs=P2^0; //at93c16--CS/*********************主程序***************************/ void main(void){unsigned int i;SCON = 0x50; //串口方式1,允许接收TMOD = 0x20; //定时器1定时方式2TH1 = 0xFD; //波特率9600TL1 = 0xFD;IT0 = 1; //INT0下降沿有效EX0 = 1; //开INT0中断;TR1 = 1; //启动定时器P2_7=0; //初始化引脚P1=0xff;EA = 1; //允许CPU中断while(1){for (i=0; i<20000; i++){ Led1=1;if(!Study1) Study();}for (i=0; i<20000; i++){ Led1=0;if(!Study1) Study();}}}/***********************串口输出**********************/ void Comput(unsigned char outdata){SBUF = outdata;while(!TI);TI = 0;}/*******************红外线查询子程序*******************/ void Irda(void){#pragma asmMOV R6,#10SB:MOV R4,#19 ;延时880微秒D1:MOV R5,#19DJNZ R5,$DJNZ R4,D1JB P3.2,EXIT ;延时882微秒后判断P3.2脚是为1DJNZ R6, SB ;在8820微秒内如P3.2为1就退出JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲MOV R4,#10 ;延时4740微秒D2: MOV R5,#218DJNZ R5,$DJNZ R4,D2;延时4.74毫秒避开4.5毫秒的结果码MOV R1,#1AH ;设定1AH为起始RAM区MOV R2,#4 ;接收从1AH到1DH,用于存放操作码和操作反码PP:MOV R3,#8 ;每组数据为8位SS:JNB P3.2,$ ;等待地址码第一位的高电平信号MOV R4,#19 ;延时880微秒D5:MOV R5,#19DJNZ R5,$DJNZ R4,D5;高电平开始后882微秒判断信号的高低电平MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中JNC TT ;如果为0就跳转到TTMOV R4,#2 ;延时1000微秒D6:MOV R5,#248DJNZ R5,$DJNZ R4,D6;检测到高电平1的话延时1毫秒等待脉冲高电平结束TT:MOV A,@R1 ;将R1中地址的给ARRC A ;将C中的值0或1移入A中的最低位MOV @R1,A ;DJNZ R3,SS ;接收满8位换一个内存INC R1 ;对R1中的值加1,换下一个RAMDJNZ R2,PP ;接收完所有数据EXIT:#pragma endasm}。
51单片机红外遥控解码程序
![51单片机红外遥控解码程序](https://img.taocdn.com/s3/m/5c056a020740be1e650e9a01.png)
51单片机红外遥控解码程序类别:单片机/DSP 阅读:2975编者按:以下是网友编写的遥控解码程序!一种用延时等待的解码方法,比较容易理解,但缺点是占用CPU运行时间,第二种方法用定时器和外中断的解码方法,初学不易理解,但优点也很明显,第二种方法如果能解决连发解码就比较完美,更完善的红外遥控解码程序,请参考本站TOPA V-2008,TOP51-2005所配程序。
解码方法一;//单片机接收红外解读程序\\;硬件结构:8951,P0口数码管段码,P2.0-P2.3为位,P1为8个LED;P3.2为红外接收头,P2.7蜂鸣器,晶振12M;适用UPD6121 6122芯片接收;---------------------------------------------------------ORG 0000HAJMP MAIN ;转入主程序ORG 0003H ;外部中断P3.2脚INT0入口地址AJMP INT ;转入外部中断服务子程序(解码程序);以下为主程序进行CPU中断方式设置MAIN: SETB EA ;打开CPU总中断请求SETB IT0 ;设定INT0的触发方式为脉冲下降沿触发SETB EX0 ;打开INT0中断请求AJMP $;以下为进入P3.2脚外部中断子程序,也就是解码程序INT: CLR EA ;暂时关闭CPU的所有中断请求MOV R6,#10SB: ACALL YS1 ;调用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 R1,#1AH ;设定1AH为起始RAM区MOV R2,#4;PP: MOV R3,#8JJJJ: JNB P3.2,$ ;等待地址码第一位的高电平信号LCALL YS1 ;高电平开始后用882微秒的时间尺去判断信;号此时的高低电平状态MOV C,P3.2 ;将P3.2引脚此时的电平状态0或1存入C中JNC UUU ;如果为0就跳转到UUULCALL YS3;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 ;接收完16位地址码和8位数据码和8位数据反; 码,存放在1AH/1BH/1CH/1DH的RAM中MOV A,1CH ;比较数据码和数据反码是否正确?CPL AXRL A,1DH ;将1CH的值取反后和1DH比较不同则无效丢弃,核对数据是否准确JNZ EXITMOV DPTR,#TAB ;表头地址送指针MOV A,1DHANL A,#0FH ;相与,得到低四位码MOVC A,@A+DPTRMOV 1EH,A ;查表得表码存入1EHMOV A,1DHSWAP AANL A,#0FHMOVC A,@A+DPTRMOV 1FH,A ;查表得高四位码存入1FMOV R7,#20HDISP:MOV P0,1FH ;送数码管显示CLR P2.1ACALL YS2SETB P2.1MOV P0,1EHCLR P2.2ACALL YS2SETB P2.2MOV P1,1DH ;将按键的键值通过P1口的8个LED显示出来!CLR P2.7 ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功LCALL YS2SETB P2.7 ;蜂鸣器停止DJNZ R7,DISPEXIT: SETB EA ;允许中断RETI ;退出解码子程序YS1: MOV R4,#20 ;延时子程序1,精确延时882微秒D1: MOV R5,#20DJNZ R5,$DJNZ R4,D1RETYS2: MOV R4,#10 ;延时子程序2,精确延时4740微秒D2: MOV R5,#235DJNZ R5,$DJNZ R4,D2RETYS3: MOV R4,#2 ;延时程序3,精确延时1000微秒D3:MOV R5,#248DJNZ R5,$DJNZ R4,D3RETTAB: DB 0C0H,0DEH,0A2H,8AH,9CH,89H,81H,0DAH,80H,88H,90H,85H,0E1H,86H,0A1H,0B1H;数据表,0-9-A-FEND解码方法二你的解码程序和我现在用的解码程序大体是一样的,我自己实际做了一下,发现按下遥控器,接收到红外信号后,数码管闪的厉害。
基于c51的红外解码源代码
![基于c51的红外解码源代码](https://img.taocdn.com/s3/m/cfa51d647e21af45b307a8eb.png)
#include<reg52.h>sbit DQ=P3^2; //接收头的数据输出引脚sbit FM=P2^3; //蜂鸣器的控制端unsigned char dat[4]; //用于接收4个字节的红外数据unsigned char data_code; //用于保存按键值sbit L0=P1^0;sbit L1=P1^1;sbit L2=P1^2;sbit L3=P1^3;sbit L4=P1^4;sbit L5=P1^5;sbit L6=P1^6;sbit L7=P1^7;bit key_on; //定义一个按键闭合标志位,如果按键被按下了,该位置1/*--毫秒级延时函数,参数为多少则延时多少毫秒--*/void delay_ms(unsigned int t){unsigned int a,b;for(a=0;a<t;a++){for(b=0;b<113;b++){;}}}/*定时器0和中断0的初始化函数*/void init(){TMOD=0x01; //定时器0工作在方式1,为16位的定时器EX0=1; //开中断1IT0=1; //低电平触发中断0EA=1; //开总中断}/*对4个字节的红外遥控数据进行解码操作的函数这4个字节数据保存在了dat[i]的数组中返回值为dat[2],它是我们需要的的按键值如果解码成功,会返回正确的dat[2],如果解码失败那么返回的dat[2]=0 */unsigned char de_code(){unsigned char i,j;unsigned char temp; //用于暂存接收到的数据unsigned int high_time,low_time; //分别用于保存高低电平的时间值for(i=0;i<4;i++) //循环4次才能接收完毕4个字节的数据{for(j=8;j>0;j--) //循环8次才能接收完毕一个字节的数据{temp=temp>>1; //数据整体右移一位,用于接收一个位数据TL0=0x00; //定时器0赋初值0TH0=0x00;TR0=1; //打开定时器0,对低电平时间进行计数while(DQ==0) //如果为低电平就一直while语句中此循环{if(TH0>0x03) //如果低电平时间远超过0.56ms了,说明不是0或者1return dat[2]=0x00; //跳出中断并返回一个值为0的按键码,表明本次解码失败}TR0=0; //关闭定时器0low_time=TH0*256+TL0; //计算低电平时间TL0=0x00; //重新装初值0TH0=0x00;TR0=1; //开定时器0,对高电平时间进行计数while(DQ==1){if(TH0>0x08) //如果高电平时间远超过1.69ms了,说明不是0或者1return dat[2]=0xff; //跳出中断并返回一个值为0的按键码,表明本次解码失败}TR0=0; //关定时器0,计算高电平时间high_time=TH0*256+TL0; //计算高电平时间if((low_time<370)||(low_time>640)) //如果高电平时间不是0.56ms左右(远离这个区间)return dat[2]=0x00; //那么返回0,说明解码失败if((high_time>420)&&(high_time<620)) //如果高电平时间在0.56ms左右(在这个区间即可)temp=temp&0x7f; //说明这个位数据为0,保存数据0else if((high_time>1300)&&(high_time<1800)) //如果高电平时间在1.69ms左右(在这个区间即可)temp=temp|0x80; //说明这个位数据为1,保存数据1else return dat[2]=0x00; //如果高电平时间不是1.69ms左右,那么返回0,说明解码失败}dat[i]=temp; //每解码完成一个字节后,对这个字节进行保存}if(dat[2]==~dat[3]) //解码得到的按键值与按键值的反码取反后进行比较{ //如果一致,则说明解码成功FM=0; //蜂鸣器发声,播报解码成功key_on=1; //置1,表明按键被按下return dat[2]; //返回这个解码成功的按键值}else return dat[2]=0x00; //如果不一致,那么返回0,说明解码失败}void int0_ISR() interrupt 0{unsigned int high_time,low_time; //分别用于保存高低电平的时间值EX0=0; //关闭中断TL0=0x00; //装初值0TH0=0x00;TR0=1; //开定时器0while(DQ==0) //{if(TH0>0x25) //如果低电平时间远超过9ms了,说明不是引导码{EX0=1; //开中断0,准备下次中断return; //跳出此次中断}}TR0=0;low_time=TH0*256+TL0;TL0=0x00;TH0=0x00;TR0=1;while(DQ==1){if(TH0>0x20) //如果高电平时间远超过4.5ms了,说明不是引导码{EX0=1; //开中断0,准备下次中断return; //跳出此次中断}}TR0=0; //关定时器0,计算电平时间high_time=TH0*256+TL0; //计算高电平时间if((low_time>7800)&&(low_time<8800)&&(high_time>3600)&&(high_time<4700))//如果低电平在9ms左右,高电平在4.5ms左右,说明为引导码data_code=de_code(); //对引导码后面的32位数据进行解码接收,并获得按键值EX0=1; //解码接收完成后,开中断delay_ms(30); //延时30ms,让蜂鸣器发声30msFM=1; //停止发声}void main(){init();while(1){if(key_on==1) //如果按键被按下了,那么就执行相应按键的操作{key_on=0; //按键标志位清0switch(data_code){case 0x45: L0=~L0; break; //此按键被按下,就对L0进行控制case 0x46: L1=~L1; break; //此按键被按下,就对L1进行控制case 0x47: L2=~L2; break; //此按键被按下,就对L2进行控制case 0x44: L3=~L3; break; //此按键被按下,就对L3进行控制case 0x40: L4=~L4; break; //此按键被按下,就对L4进行控制case 0x43: L5=~L5; break; //此按键被按下,就对L5进行控制case 0x07: L6=~L6; break; //此按键被按下,就对L6进行控制case 0x15: L7=~L7; break; //此按键被按下,就对L7进行控制default:break;}}}}。
电视遥控器的C51解码程序及其控制的电动遥控玩具车举例
![电视遥控器的C51解码程序及其控制的电动遥控玩具车举例](https://img.taocdn.com/s3/m/30e90797fab069dc502201f1.png)
电视遥控器的C51解码程序及其控制的电动遥控玩具车举例彩色电视红外线遥控器小巧方便,抗干扰能力强,遥控距离远,得到广泛应用。
其基本原理是通过键盘产生编码,对38K 载波调制,经放大,形成一串串脉冲由红外线发射管发射出去,现以M50462AP 集成电路的遥控器为例,介绍其编码及其用C 语言实现的解码程序。
彩电遥控器由键盘、M50462AP 和红外发射管等组成,电原理图如图1:图1脉冲宽度0.25MS ,编码为“1”时,脉冲间隔为1MS ,编码为“0”时,脉冲间隔为2MS ,如图3: 编码“0” 编码“1”图3指令前8位为引导码,后8位为功能码,M50462AP 中的引导码C0~C7由1110XX10组成,C4、C5由外引脚C4、C5控制,当C4、C5悬空或为“1”时,C4、C5为0,反之为1,如以熊猫牌遥控器为例,其引导码为“11100010”即十六进制“E2H ”,按键时间必须大于18MS 才能被确认,具有自动消抖功能,按键22MS 后开始发送指令,指令周期为44MS ,如此循环发送,直到按键被释放。
其编码及其对应的功能按键如表一:表一电视遥控器的解码由一片目前广泛使用、体积小而功能极强的AT89C2051单片机作解码芯片,该单片机内含128B RAM,2K Flash ROM,15根I/O口线,5个中断源,一个全双工串口,2个定时器/计数器,2个外部中断,时钟频率最高可达24M HZ,而外部引脚仅为20个。
遥控接收头直接接89C2051的INT0端,解码利用了定时器T0的门控位GA TE位功能捕捉脉冲间隔宽度,即定时器工作不仅要允许位TR0置位,还要INT0引脚为高电平才能开始定时,定时器T0工作在十六位定时器方式,解码如图4:图4至于定时数值的判定,初值为0,以逻辑“1”为例,晶振f=6M HZ,脉宽T=1.75MS,由计算知:count:=T/(1/f)=875=36BH 由于本文为实验,故仅判定TH0的值,而又因有误差,认为只要TH0大于等于3即为“1”,否则为“0”,详细见中断流程图。
NEC格式红外发射C程序 C51
![NEC格式红外发射C程序 C51](https://img.taocdn.com/s3/m/55d228c9846a561252d380eb6294dd88d1d23d44.png)
NEC格式红外发射C程序 C51nec格式红外发射c程序c51//**********************************************////**********nec格式红外遥控发射程序*************////*******************idwrok*******************////************* **20210315_zxq*******************////****20s-m-1s-40eb728d-3s-idwr(40ee6699)******////**********************************************//#inclu de#defineuintunsignedint#defineucharunsignedcharstaticbitopt;sbitir=p3^4;//sbi tkey=p1^7;staticuintcount;staticuintendcount;staticucharflag;staticucharsyscod e_h;staticucharsyscode_l;ucharir_bufdata[4];voidinit(void);voidsend_ir(ucharcustomcode);//voiddelay_ms(uintms);voiddelay_s(uchars);voidmain(void){init();delay_s(20);syscode_l=0xee;send_ir(0x01);delay_s(1);sysc ode_l=0xeb;send_ir(0x72);delay_s(3);syscode_l=0xee;send_ir(0x66);delay_s(17);w hile(1){delay_s(1);syscode_l=0xee;send_ir(0x67);}}//红外发射管的状态十一位0,1//红外升空端口//延时计数器//中止延时计数//红外传送标志//系统码点低8十一位//系统码点高8十一位//遥控代码放置缓冲区//升空数据码//ms延后子程序//s延后子程序//起始//等候开机//系统码设置//传送遥控代码m//系统码设置//传送遥控代码//系统码设置//传送遥控代码idwr//系统码设置//传送遥控代码led提示信息voidtimeint(void)interrupt1{th0=0xff;tl0=0xe6;count++;if(flag==1){opt=~opt;}else{opt=0;}ir=opt;}voidinit(void){count=0;flag=0;opt=0;ir=0;syscode_h=0x40;syscode_l=0xbf;ea=1;tm od=0x01;et0=1;th0=0xff;tl0=0xe6;tr0=1;}voidsend_ir(ucharcustomcode){uinti,j;ir_bufdata[0]=syscode_h;ir_bufdata[1]=sys code_l;ir_bufdata[2]=customcode;ir_bufdata[3]=~customcode;endcount=223;flag=1;count=0;//定时器0中断处理//26us中断一次,频率为38khz//cpu开总中断//设立定时器0为16十一位模式1//定时器0中断容许//26us中断一次频率为38khz//开始计数//syscode数据迁移至ir_bufdata[]内//发送9ms的起始码while(countendcount=117;//传送4.5ms的结果码flag=0;count=0;while(count>1;}}endcount=10;//每个代码传送完后的延时flag=1;count=0;while(countvoiddelay_ms(uintms)//ms延后子程序{for(;ms>0;ms--){flag=0;count=0;while(count<24);}}*/voiddelay_s(uchars){for(;s>0;s--){flag=0;count=0;while(count<27772);}}//1ms//s延后子程序//1s。
51单片机红外遥控解码,很详细(汇编语言,C语言等)
![51单片机红外遥控解码,很详细(汇编语言,C语言等)](https://img.taocdn.com/s3/m/9912cc3958eef8c75fbfc77da26925c52cc591c6.png)
//i++;
if(TH0<3)
b=1;
else b=0;
TH0=0;
TL0=0;
}
uchar hw_key()
{
uchar j,m;
//i=0;
hw_start(); //等待低电平到来
hw_pulse();
for(j=0;j<24;j++) //测试用户码脉冲宽度
{
hw_pulse();
}
for(j=0;j<8;j++) //测试键码脉冲宽度
{
hw_pulse();
if(b==1)
m=(m<<1)|1;
else
m<<=1;
}
return m; //键码
}
while(in==0); //高电平到了,
TR0=0; //关闭定+;
TH0=0;
TL0=0;
TR0=1; //高电平到了,启动定时器1,测试高电平宽度
while(in==1); //低电平到了,
TR0=0; //关闭定时器1,高电平宽度测试完
请注意甄别内容中的联系方式诱导购买等信息谨防诈骗
51单片机红外遥控解码,很详细(汇编语言,C语言等)
单片机源程序如下:
#include
#define hw_hs0038_ENTITY
#include "hw_hs0038.h"
sbit in=P3^2;
//uchar i=0;
//uchar k[2];
bit bdata b=0;
/*
void timer0(void) interrupt 1 using 1
51单片机红外解码、超声波测距程序(详细解释程序)
![51单片机红外解码、超声波测距程序(详细解释程序)](https://img.taocdn.com/s3/m/f456cdb2561252d381eb6e92.png)
// c51红外解码、超声波测距程序#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define count 4uchar data IRcode[4]; //定义一个4字节的数组用来存储代码uchar table[4];uchar enled[4]={0x1f,0x2f,0x4f,0x8f};uchar CodeTemp,temp,tt; //编码字节缓存变量uchari,j,k,temp,timeH,timeL,succeed_flag,flag,h,h1,h2,a,key,key1,key2; //延时用的循环变量uint distance,distance1,time; //距离,timesbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)sbit come=P3^3;sbit d=P1^1;//发送码sbit BZ=P1^0;sbit s=P3^7;//38ksbit ss=P3^6;//38kuchar m;// 开关控制//sbit n=P2;//电机反转code unsigned charseg7code[10]={0xa0,0xbb,0x62,0x2a,0x39,0x2c,0x24,0xba,0x20,0x28}; //显示段码/**************************** 定时器0中断************************/void timer0() interrupt 1{TH0=(65536-count)/256;TL0=(65536-count)%256;s=~s;//产生38K信号ss=~ss;//tt++;//发送超声波个数}/**************************** 延时0.9ms子程序************************/void Delay0_9ms(void){uchar j,k;for(j=18;j>0;j--)for(k=20;k>0;k--);}/***************************延时1ms子程序**********************/void Delay1ms(void){uchar i,j;for(i=2;i>0;i--)for(j=230;j>0;j--);}/***************************延时4.5ms子程序**********************/ void Delay4_5ms(void){uchar i,j;for(i=10;i>0;i--)for(j=225;j>0;j--);}/**************************** 解码延时子程序************************/ void Delay(void){uchar i,j,k;for(i=100;i>0;i--)for(j=100;j>0;j--)for(k=3;k>0;k--);}/**************************** 显示延时子程序************************/ void ledDelay(unsigned int tc) //延时程序{unsigned int i,j;for(i=0;i<10;i++)for(j=0;j<tc;j++);}/************************************************ ****************///定时器1中断,用做超声波测距无回波void timer1() interrupt 3{TR1=0;ET1=0;EX1=0;TH1=0;TL1=0;}/***********************显示程序*********************/ void Led(int date) //显示函数{ int i;table[0]=date/1000;table[1]=date/100%10;table[2]=date/10%10;table[3]=date%10;date=0;for(i=0;i<120;i++){P2=enled[i%4]&m;//P2口高四位控制数码管,低位陪分控制继电器P0=seg7code[table[i%4]]; //取出千位数,查表,输出。
c51单片机红外解码程序-汇总版和c语言版
![c51单片机红外解码程序-汇总版和c语言版](https://img.taocdn.com/s3/m/2d3d9b54763231126fdb114a.png)
精心整理纯软件解码---汇编版利用程序判电平和时间进行解码,缺点是浪费系统软件资源;优点是对系统硬件要求稍低ORG0000HT0ZDBIT20H.2XHBITP3.3;红外接收头数据接口RSBITP2.3RWBITP2.4============================================================JBXH,$;等待电平变低,解码从这开始CLRP2.0;开信号指示灯,表示正在接收信号MOVP0,#8EHSETBTR0;开T0中断LCALLYS3MSJBXH,DDXH;干扰检测LCALLYS3MSJBXH,DDXH;干扰检测DD1:JBT0ZD,DDXH;是否超出接收允许时间JNBXH,DD1;等待电平变高LCALLYS3MSJNBXH,DDXH;干扰检测DD2:JBT0ZD,DDXH;是否超出接收允许时间JBXH,DD2;等待电平变低JSSJ:;信号确认,开始接收数据ZJ:;MOVR7,#100;TSY:MOVR6,#255DJNZR6,$CPLBBDJNZR7,TSYMOVA,#0CDH;键值高位输出LCALLYJP_XZLMOVA,R4MOVB,#10HDIVABMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0CEH;键值低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTR LCALLYJP_XSJ; LCALLDYBF;调用灯控制子程序LJMPDDXH;返还等待下一次信号YS845:;延时845微秒MOVR7,#255RETRETDIVABMOVCA,@A+DPTR LCALLYJP_XSJMOVA,#0C1H;用户码前低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTR LCALLYJP_XSJMOVA,#0C4H;用户码后高位输出LCALLYJP_XZLMOVA,31HMOVB,#10HDIVABMOVCA,@A+DPTRLCALLYJP_XSJMOVA,#0C5H;用户码后低位输出LCALLYJP_XZLMOVA,BMOVCA,@A+DPTRLCALLYJP_XSJ;============此处专门针对我的开发板和遥控,不是解码的关键,只是一种应用举例BA7:CJNEA,#52H,BAB;是否8号键按下CPLP1.7;点亮1号灯BAB:RETCSH:;=============液晶初始化===============MOVA,#00111000B;8位数据,双行显示,5-7字型LCALLYJP_XZL;调用写液晶指令MOVA,#00001100B;显示屏开启,光标出现在地址计数器位置,光标不闪烁LCALLYJP_XZL;调用写液晶指令MOVA,#00000110B;光标右移一格,AC值加一,字符全部不动LCALLYJP_XZL;调用写液晶指令MOVA,#81H;LCALLYJP_XZLMOVA,#4CH;L的ASCII码LCALLYJP_XSJMOVA,#83H;LCALLYJP_XZLLCALLYJP_XZLMOVA,#61H;a的ASCII码LCALLYJP_XSJMOVA,#8EH;LCALLYJP_XZLMOVA,#6FH;o的ASCII码LCALLYJP_XSJMOVA,#0C2H;LCALLYJP_XZLMOVA,#48H;H的ASCII码LCALLYJP_XSJMOVA,#0C6H;LCALLYJP_XZLMOVA,#48H;H的ASCII码LCALLYJP_XSJMOVA,#0CAH;LCALLYJP_XZLMOVA,#4AH;J的ASCII码LCALLYJP_XSJMOVA,#0CBH;LCALLYJP_XZLMOVA,#5AH;Z的ASCII码RETRETCLRESETBRSCLRRWSETBEMOVP0,A;写数据CLRERET;=========查询忙碌标志============ CHECK_BUSY:PUSHACCBUSY_LOOP:CLRESETBRWCLRRSSETBEMOVA,P0;读取状态JBp0.7,BUSY_LOOPPOPACCLCALLDELRETDEL:MOVR6,#5RET/////////#definezd_cffsIT0///中断触发方式设置#definezd_dkEX0///中断打开设置////#definestc_dsqszAUXR&=0x7F;//定时器时钟12T模式,不需要可在AUXR....前加// ///**************************************************/****************************************************************** *****本程序使用外部中断加定时器来实现红外解码,占用系统软件资******** *****源极少,硬件方面占用了一个外部中断,定时器中断还可以进行******** *****一些简单的运用,软件部分可以做很多的动作,就看你发挥了!**************************************************************************/ #defineshi_jian定时器设置,请勿更改unsignedcharhwyhmh,hwyhml,hwjz,hwsj,hwjmws;///全局变量bithwjmok,yxjm;///全局变量,红外解码OK,允许解码voidmain(void){EA=1;//总中断打开zd_cffs=1;//外部中断_边沿触发方式zd_dk=1;//外部中断_打开ET0=1;//while(1)}}}定时器0{hwjz=0;TR0=0;//}voidZDhwjsCX(void)zd_rkdzusing3{unsignedinta=TH0*256+TL0;TL0=0;TH0=0;TR0=1;///开启T0if(a>shi_jian_*13000&&a<shi_jian_*14000)///if1分支2.判引导码13-14ms {hwsj=0;hwjmws=32;yxjm=1;}elseif(yxjm)///if1分支1.已收到引导码,允许解码{if(a>shi_jian_*11000&&a<shi_jian_*12000&&hwjmws==0)///if2分支1。
keilc51红外遥控解码程序
![keilc51红外遥控解码程序](https://img.taocdn.com/s3/m/b6462287b1717fd5360cba1aa8114431b90d8e8e.png)
keilc51红外遥控解码程序keil c51红外遥控解码程序本keil c51程序适用uPC1621/uPC1622及兼容的红外遥控器芯片,占用外部中断0和定时器1,以中断方式解码,节省系统资源,以查询方式检测遥控信号是否有效.解码思路:红外线经一体化接受头解码放到后送到单片机的外部中断0,单片机设置外部中断下降沿触发,T0和T1为16位定时器,T0在系统启动后定时5ms.T1在外部中断0启动后开始定时,初值为0,每次在INT0中断后先读T1计数值,并重设初值为0,而且判断T1的计数值,18.unsigned char IR_repeat=0;19.unsigned char IR_ready=0;20.unsigned char IR_poweron=0;21.//bit ir_done=0;22.// time constants23.unsigned int IRtimer=0; // IR timeout24.25.//cpu初始化26.void cpu_init(void)27.{28.TMOD=0X11; // T0 and T1 十六位定时29.TH0=0xee; //fosc=11.0592M,timer=5ms30.TL0=0x00;31.TR0=1; // run timer 0;32.TF0=0;33.34.ET0=1; // enable tmr 0 overflow interrupt35.IT0=1; // int0 edge sensitive36.EX0=1; // enable "int0"37.EA=1; // global interupt enable38.}39.40.//T0中断41.void tmrint() interrupt 142.{43.TH0=0xee;44.TL0=0x00;45.if (IRtimer) //IR接收超时46.--IRtimer; //47.else48.{49.IRstate=IR_idle;50.// IR_poweron=0;51.}52.}53.54.//Fosc=11.0592MHz55.#define msec_12p5 0x2d0056.#define msec_15 0x360057.#define msec_9 0x206658.//#define msec_9 0x106659.#define msec_2p5 0x90060.#define msec_0p9 0x33d61.#define msec_1p68 0x61062.63.64.//void IRint() interrupt 0(void)65.66.//When the IR receive pin goes low and interrupt is ge nerated67.// IR is collected by starting timer 2 in the first falling edge of the pin68.// then on every other falling edge, the timer value i s saved and the timer restarted .69.// the captured time is then used to get the IR data70.// a "start of data" is 13.5Msec,a "1" is 2.25Msec,a "0" i s 1.12 msec and a "repeat" is 11.25msec.71.// the counter increments at 1.085 Usec72.// I allow a fairly large tolerance to time jitter but there are no false triggers seen.73.74.void IRint() interrupt 075.{76.static unsigned char bits;77.unsigned short time;78.switch(IRstate)79.{80.case IR_idle:81.TL1=0;82.TH1=0;83.TR1=1;84.IRstate=IR_waitstart;85.IRtimer=26;86.break;87.case IR_waitstart: //P2_4=!P2_4;88.TR1=0;89.time=TH1;90.time =(time <<8)+TL1;;91.TL1=0;92.TH1=0;93.TR1=1;94.if ((time > msec_12p5)&&(time < msec_15)) // greate r than 12.5Msec & less than 15 msec = start code95.{96.IRaddr=0;97._IRaddr=0;98.IRdata=0;99._IRdata=0;100.bits=1;101.IRstate=IR_getaddr;102.}103.else if ((time > msec_9)&&(time < msec_12p5))// les s than 12.5Msec and greater than 9 msec =Repeat code 104.{105.IR_repeat=2;106.IRstate=IR_idle;107.}108.else109.{ // to short, bad data just go to idle110.IRstate=IR_idle;111.}112.break;113.case IR_getaddr: // P2_4=!P2_4;114.TR1=0;115.time=TH1;116.time =(time <<8)+TL1;;117.TL1=0;118.TH1=0;119.TR1=1;120.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle121.{122.IRstate=IR_idle;123.break;124.}125.if (time>msec_1p68)// greater than 1.68Msec is a 1126.{127.IRaddr|= bits;128.}129.bits=bits<<1;130.if (!bits)131.{132.IRstate=IR_getaddrinv;133.bits=1;134.}135.break;136.case IR_getaddrinv: //P2_4=!P2_4;137.TR1=0;138.time=TH1;139.time =(time <<8)+TL1;;140.TL1=0;141.TH1=0;142.TR1=1;143.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle144.{145.IRstate=IR_idle;146.break;147.}148.if (time>msec_1p68)// greater than 1.68Msec is a 1 149.{150._IRaddr|= bits;151.}152.bits=bits<<1;153.if (!bits)154.{155.IRstate=IR_getdata;;156.bits=1;157.}158.break;159.case IR_getdata:160.TR1=0;161.time=TH1;162.time =(time <<8)+TL1;;163.TL1=0;164.TH1=0;165.TR1=1;166.if ((time>msec_2p5)||(time<msec_0p9))// if > 2.5mse c or shorter than .9Msec bad data , go to idle167.{168.IRstate=IR_idle;169.break;170.}171.if (time>msec_1p68)// greater than 1.68Msec is a 1172.{173.IRdata|= bits;174.}175.bits=bits<<1;176.if (!bits)177.{178.IRstate=IR_getdatainv;179.bits=1;180.}181.break;182.case IR_getdatainv:183.TR1=0;184.time=TH1;185.time =(time <<8)+TL1;;186.TL1=0;187.TH1=0;188.TR1=1;189.if ((time>msec_2p5)||(time<msec_0p9)) // if > 2.5mse c or shorter than .9Msec bad data , go to idle190.{191.IRstate=IR_idle;192.break;193.}194.if (time>msec_1p68)// greater than 1.68Msec is a 1 195.{196._IRdata|= bits;197.}198.bits=bits<<1;199.if (!bits) // we have it all , now we make sure it i s a NEC code from the CHS IR transmitter200.{ // make sure address,~address are correc t , data ,~data are correct and address is 0.201.IR_ready=((IRaddr^_IRaddr)==0xff)&&((IRdata^_IRda ta)==0xff)&&(IRaddr==0);202.if(IR_ready)203.{204.IRstate=IR_idle;205.}206.}207.break;208.default:209.IRstate=IR_idle;210.break;211.}212.}213.214.void main(void) 215.{216.cpu_init();217.while(1)218.{219.if(IR_ready)220.{221.IR_ready=0;222.switch(IRdata) 223.{224.case 0x45: //1 225.//your code226.break;227.case 0x44: //3 228.//your code229.break;230.case 0x43: //4 231.//your code232.break;233.case 0x08: //prev 234.//your code235.break;236.case 0x5a: //next 237.//your code238.break;239.default:240.break;241.&n bsp; } 242.}243.}。
c51解密红外 + c语言红外解码xy
![c51解密红外 + c语言红外解码xy](https://img.taocdn.com/s3/m/937d13d076a20029bd642dfb.png)
首先说一下想写这个帖子看到论坛上有关于遥控器方面的帖子但是都没有很详细的介绍而且是已经有完整的波形仅仅介绍了解码部分而没有分析波形数据方面的介绍,因此有了写一篇完整的关于遥控器方面的文章的冲动此贴对新手可能有点困难不过不要紧我会以最通俗的方式来解释如果有不明白的建议去看看书,自己努力没有不可能的事别人能做到你也一定行,关于红外遥控的基础理论,大家可以到这个贴去看下/mcu/184.html,里面有详细的介绍。
在这里我仅把一些关键的带出来关于硬件电路那么抛开那么多文字介绍最后意思就是说你家里的遥控板也就是发射部分是把所有的封装好了的比如键盘矩阵、编码调制、LED红外发送器等等那么接受部分SM00383个脚一个脚地一个脚电源一个脚信号脚接到单片机随便个P口上(此处是P3。
6)OK 硬件部分就搞定了当然还有数码管显示,这些肯定不用说你都能搞定吧,我这刚好有一块51hei单片机学习板是在的论坛买的,这些东东都有,所以就不用自己去搭电路那么麻烦了),那么我们想我们按一下遥控板大家看到有个灯闪了一下然后OVER 那么我们现在要做的就是在灯闪了那一下之后让单片机来读它的键码然后不同的键码来干不同的事,本文是向大家解释一种方法当然如果你知道遥控器的编码那么我想写解码程序应该是很简单的事而我的意思是说我们现在从0开始拿到任何一种遥控板那怕不知道它的型号但是大家想即使它什么型号都没写但是按一下不同的键它的发射的脉冲肯定不一样无非就是引导码然后地址码键码验证码因为不同的遥控板它所定义的规则不一样(这里说一点题外话其实在读出波型后大家就可以看出这个遥控板最开始设计时的人的意思或者说考虑它的这个设计方式是否是最好的是否稳定是否具有通用性或者说日本的和中国的设计师在设计时他们所考虑的名牌和杂牌的他们在设计时所考虑的等等这些其实也是件很有意思的事就像偷窥到一个人的内心世界一样扯远了。
--)下面我们来说说本问利用51单片机软件解密的方法首先大家看了我刚才贴出来的连接应该知道了编码无非就是低电平高电平。
51单片机 红外接收数码管显示解码实验
![51单片机 红外接收数码管显示解码实验](https://img.taocdn.com/s3/m/b91d3dfd700abb68a982fb24.png)
#include <reg51.h>#define c(x) (x*120000/120000)sbit Ir_Pin=P3^3;//接红外sbit beep=P3^6;unsigned char code Led_Tab[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x8E}; //共阳极数码显示码0-F.unsigned char code Led_Sel[]={0x00,0x01,0x02,0x03};unsigned char Led_Buf[4]; //显示缓冲区char Led_Index;//位选unsigned char Ir_Buf[4]; //用于保存解码结果void delay_50ms(unsigned int t){unsigned int j;for(;t>0;t--)for(j=6245;j>0;j--){;}}//==============================================================//数码管扫描timer0() interrupt 1 using 1{TL0=65536-1000;TH0=(65536-1000)/256; //定时器0设定约1000us中断一次,用于数码管扫描P0=0xff;P2=Led_Sel[Led_Index]; //位选P0=Led_Tab[Led_Buf[Led_Index]]; //段选if(++Led_Index>3) Led_Index=0; //四个扫描完了,到第一个数码管}//============================================================== unsigned int Ir_Get_Low(){TL1=0;TH1=0;TR1=1;while(!Ir_Pin && (TH1&0x80)==0);TR1=0;return TH1*256+TL1;}//============================================================= unsigned int Ir_Get_High(){TL1=0;TH1=0;TR1=1;while(Ir_Pin && (TH1&0x80)==0);TR1=0;return TH1*256+TL1;}//============================================================== main(){unsigned int temp;char i,j;Led_Index=1;TMOD=0x11;TL0=65536-1000;TH0=(65536-1000)/256; //定时器0设定约1000us中断一次,用于数码管扫描EA=1;ET0=1;TR0=1;Led_Buf[0]=0;Led_Buf[1]=0;Led_Buf[2]=0;Led_Buf[3]=0; //显示区设成0do{ restart:while(Ir_Pin);temp=Ir_Get_Low();if(temp<c(8500) || temp>c(9500)) continue;//引导脉冲低电平9000temp=Ir_Get_High();if(temp<c(4000) || temp>c(5000)) continue;//引导脉冲高电平4500for(i=0;i<4;i++) //4个字节for(j=0;j<8;j++) //每个字节8位{temp=Ir_Get_Low();if(temp<c(200) || temp>c(800)) goto restart;temp=Ir_Get_High();if(temp<c(200) || temp>c(2000)) goto restart;Ir_Buf[i]>>=1;if(temp>c(1120)) Ir_Buf[i]|=0x80;}Led_Buf[0]=Ir_Buf[2]&0xf;Led_Buf[1]=(Ir_Buf[2]/16)&0xf;Led_Buf[2]=Ir_Buf[3]&0xf;Led_Buf[3]=(Ir_Buf[3]/16)&0xf; //显示结果P1=Ir_Buf[2];beep=0;delay_50ms(2);beep=1;}while(1);}。
红外循迹c51程序
![红外循迹c51程序](https://img.taocdn.com/s3/m/5c7c99ec760bf78a6529647d27284b73f2423621.png)
#inclu de<re g52.h>#de fineuintunsig ned i nt#defin e uch ar un signe d cha ruin t i,t;lon g cou nter;//编码器脉冲数值u charfinis h=0;//停车标志//--------传感器变量------------s bit r i1=P0^0; //*左边传感器*//sbit ri2=P0^1;sbit ri3=P0^2;sbit mid=P0^3;//*中间传感器*//sbi t le3=P0^4;sbi t le2=P0^5;sbi t le1=P0^6;//*右边传感器*//sb it bz=P2^7;//蔽障管//-------电机舵机控制变量-----------sbit ENA=P1^0; //驱动电机pwm//sb it mo to1=P1^1;//电机控制//s bit m oto2=P1^2;sbit PWM=P1^4; //舵机pwm////---------转角变量---------uint angl e;ui nt ab solut e(int);//--------速度变量----------ui nt pr o; //驱动电机调速uin t car_driv er; //驱动力参数ui nt pu lse_s peed; //电机当前速度uintideal_spee d; //理想状态下的速度i nt sp eed_e rror; //理想速度与当前速度的差值intpre_e rror=0; //PID控制的速度差值intpre_d_erro r=0;//PID控制的速度上一次的差值int pk=0,erro r=0;//速度的PID值int s peedm ax;//----------表格值----------uintcodespeed_tabl e[]={50,40,40};uint code angl e_tab le[]={110,75,110};#defin e kp213#defin e ki7#de finekd 15//-----------函数定义-------void init();v oid d elay(uint);voi d qct yp();void duoj i();voidcarpo sitio n();voidspeed();v oid p id();//=============主函数==========voidmain(){init();while(1){q ctyp();carp ositi on();sp eed();}}//===========子函数============//-----------初始化-----------voi d ini t(){TMO D=0x11;//设定双定时器EA=1;//EX0=1;//开外部中断0// T CON=0x01;TR0=1;T R1=1;TH0=(65536-20000)/256;TL0=(65536-20000)%256;//设定定时初始值,可去下载个定时器计算软件,20m sTH1=(65536-1000)/256;TL1=(65536-1000)%256;E T0=1;ET1=1;ENA=1;pu lse_s peed=0;s peedm ax=0;}//---------延时函数----------v oid d elay(uintn){ucha r a,b,c;for(c=1;c>0;c--)f or(b=n;b>0;b--)f or(a=2;a>0;a--);}//-------光电管全无状态时(脱离轨道),读取前次状态---------voidqctyp(){ri1=P0^0;r i2=P0^1;ri3=P0^2;mid=P0^3;le3=P0^4;l e2=P0^5;le1=P0^6;}//-------循迹函数,读取光电管状态------------vo id ca rposi tion(){if(!le1&&!le2&&!le3&&mid&&!ri3&&!r i2&&!ri1){angle=0;}el se if(le3&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(le2&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(le1&&!mid&&!ri3&&!r i2&&!ri1){angle=1;}el se if(ri1&&!mid&&!le3&&!l e2&&!le1){angle=2;}el se if(ri2&&!mid&&!le3&&!l e2&&!le1){angle=2;}el se if(ri3&&!mid&&!le3&&!l e2&&!le1){angle=2;}}//-----------舵机控制-------------void duoj i() //舵机控制{P WM=1;del ay(an gle_t able[angle]); //可改变舵机转向角度PW M=0;}//-----------------计算车的速度-----------------voi d spe ed(){ /*if(speed max<=pulse_spee d) speed max=p ulse_speed;if(sp eedma x>=40) s peedm ax=40;pi d();pro=car_d river;//变量y是改变小车速度这里范围是0--39*/p ro=sp eed_t able[angle];m oto1=1;m oto2=0; }//------------PID控制----------------/*void pid(){signe d int d_e rror, dd_e rror; //e rror=speed_erro rid eal_s peed=speed_tabl e[ang le];erro r=ide al_sp eed-p ulse_speed;d_error=erro r-pre_erro r; //d_er ror 当前速度差与上一次速度差之差dd_er ror=d_erro r-pre_d_er ror;pre_error=erro r; //存储当前偏差pre_d_err or=d_error;pk+=kp*d_err or+ki*erro r+kd*dd_er ror;if(p k<=0)p k=0;else if(p k>=40) pk=40;car_drive r=pk;}//-----------中断---------------voi d ext er0() inte rrupt 0{coun ter++;}*/vo id ti mer0() int errup t 1//产生pwm信号控制舵机,周期20ms{TH0=(65536-20000)/256;//1011 0001 即TH O=(65536-20000)/256TL0=(65536-20000)%256; //1110 0000即TLO=(65536-20000)%256duoji();}void time r1()inter rupt3//产生pwm信号控制驱动电机速度{TH1=(65536-1000)/256;TL1=(65536-1000)%256;i++;i f(i<=pro){ ENA=1;}el se{EN A=0;}i f(i==50){E NA=~E NA;i=0;}/* t++;if(t==1000){t=0;pul se_sp eed=4*coun ter/500; //速度=编码器主动轮周长(M)*脉冲/分辨率coun ter=0;} */}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include<reg52.h>unsigned char finish;//解码标志位unsigned char address1,address2,data1,data2;//地址位,反地址位,数据位,反数据位unsigned char tt[32];//32位码unsigned char d[9];//数据缓冲sbit P32=P3^2;/**********************Modbus通讯**************************/unsigned char code auchCRCHi[] = {0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40} ;/* CRC低位字节值表*/unsigned char code auchCRCLo[] = {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,0x43, 0x83, 0x41, 0x81, 0x80, 0x40} ;unsigned char code Re_code[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; #define Time_L 0x00 // 定时器初始值11.0592M 定时10ms 初始值#define Time_H 0xDCsbit DE = P3^4; //?sbit DEF = P3^5;//?unsigned char Address;unsigned char Buf[20]; // 接收缓存区unsigned char xdata Sbuf[20]; // 发送缓存区unsigned short receive_count = 0; // 接收计数union Check //定义地址共用体把CRC校验码高位和低位分开{ // CRC.Chdata[0]为低位CRC.Chdata[1]为高位unsigned int CRCdata;unsigned char Chdata[2]; // [0] 为高位[1] 为低位} CRC;unsigned short CRC16(unsigned char *puchMsg,unsigned short usDataLen){//unsigned char *puchMsg ; /* 要进行CRC校验的消息*///unsigned short usDataLen ; /* 消息中字节数*/unsigned char uchCRCHi = 0xFF ; /* 高CRC字节初始化*/unsigned char uchCRCLo = 0xFF ; /* 低CRC 字节初始化*/unsigned uIndex ; /* CRC循环中的索引*/while (usDataLen--) /* 传输消息缓冲区*/{uIndex = uchCRCHi ^ *puchMsg++ ; /* 计算CRC */uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];uchCRCLo = auchCRCLo[uIndex] ;}return (uchCRCHi << 8 | uchCRCLo) ;}void System_Init(){TMOD=0x20; // 串口初始化9600 None 8 1(11.0592MHZ)SCON = 0x50;ES=1;TH1=0xFD;TL1=0xFD;TR1=1;TMOD=0x21;TH0=0;TL0=0;EX0=1; //开外部中断0//ET0=1;IT0=1;//下降沿产生中断// EA=1;TR0=0;//定时器0关闭// TMOD=TMOD&0xf0; //定时器初始化// TMOD=TMOD|0x01;// TH0=Time_H;// TL0=Time_L;// ET0=1; //允许定时器中断DE = 0;Address = 0xFF; // Set AdrressEA=1; // allowed interrupt}void Send_Data(unsigned char dat){ES = 0;SBUF = dat;while(!TI);TI = 0;ES = 1;}void Key_delay(unsigned int z)//延时函数{unsigned int x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void add(void) //转换成10进制数子函数{unsigned char i;address1=0;address2=0;data1=0;data2=0;for(i=0;i<8;i++) //位{address1=(tt[i]<<7)|(address1>>1);address2=(tt[8+i]<<7)|(address2>>1);data1=(tt[16+i]<<7)|(data1>>1);data2=(tt[24+i]<<7)|(data2>>1);}}void main(){unsigned char i;System_Init();while(1){if(finish==1){finish = 0;add();Sbuf[0] = 0x45;Sbuf[1] = address1;Sbuf[2] = address2;Sbuf[3] = data1;Sbuf[4] = data2;CRC.CRCdata = CRC16(Sbuf,5);Sbuf[5] = CRC.Chdata[0];Sbuf[6] = CRC.Chdata[1];DE = 0; // 485 发送允许DEF= ~DE;Key_delay(1);for(i=0;i<7;i++){Send_Data(Sbuf[i]);}Key_delay(10);DE = 1; // 485 接收允许DEF= ~DE;}}}void rese() interrupt 4{if(RI){RI = 0;TR0 = 1;Buf[receive_count++] = SBUF;if(receive_count>=20)receive_count = 0;TH0 = Time_H;TL0 = Time_L;}if(TI)TI = 0;}void int0(void) interrupt 0 //外部中断0{unsigned char i,t;EX0=0;//关外部中断0TR0=1;//定时器0开始记数while(P32==0);TR0=0;//定时器0关t=(TH0*256+TL0)/921;//低电平9 MSTH0=0;TL0=0;if(t>=8){TR0=1;while(P32==1);TR0=0;t=(TH0*256+TL0)/921;//高电平3 MSTH0=0;TL0=0;if(t>=3){for(i=0;i<32;i++){TR0=1;while(P32==0);//等待TR0=0;t=(TH0*256+TL0)/921;TH0=0;TL0=0;if(t==0) //0跟1的低电平的时间相同{TR0=1;//定时器0开while(P32==1);TR0=0;//定时器0关//while(P32==1);//{if(TH0>10) break;}//如果高电平的时间大于2.5ms,跳出while 循环//TR0=0;//定时器0关t=(TH0*256+TL0)/921;TH0=0;TL0=0;//循环一次重新付初值tt[i]=t;}}finish=1;}}EX0=1;//外部中断开}。