1、/#define ENABLE_ISP 0x86 /系统工作时钟2MHz 时,对ISP_CONTR 寄存器设置此值 /#define ENABLE_ISP 0x87 /系统工作时钟0;j-)/j是数据总长度,如此判断,不会存储多余的空位 Byte_Program(addr,a);/从本组数据对应扇区首地址开始写EEPROM m+; /数组下移 addr+; /地址下移 delayms(1); /for end m=Byte_Read(0xc00);/*/C编程技巧 :判断恒等于=时,把常量写前面可以防止写成赋值语句 /把“=”写成“=”,会报错,常量不能赋值 /*/ if(121=m)JIES
2、HOU=1;delayms(6000);m=0;/下面还要用,所以清0 addr=0;zu=0;EX1=1; /开外部中断1 IT1=1;/外部中断1边沿触发,不然按住的时候一直中断 EA=1;/等待按键时两个灯灭 while(1)if(receive)/外部按键中断1,正式进入接收函数 receive=0;/只用一次,先清0,免得忘了 /发射指示灯 delayms(3000);delayms(2);FASHE=1;jieshou(); /接收函数是T0定时开始后计数满溢出跳出的 if(!KEY) /KEY为0时进入发射模式 delayms(200);fashe(); /*/接收函数初始化 v
3、oid init1()/接收初始化 finish=1;flag=0;end=0;j=0;EA=0; /因为下面要写EEPROM,必须关闭EA TMOD=0x01;/T0方式1 TH0=0x00;TL0=0x00;TR0=0;EX0=1;EX1=0;/关闭外部中断1按键 ,一旦进入接收函数,就关闭按键防止干扰 ET0=1; /开T0中断 IT0=1; /外部中断0边沿触发 /*/ 红外接收子程序 void jieshou()/接收灯亮才可以开始按遥控 init1(); /接收初始化 /开中断 cin=1;/接收灯亮等待接收 while(finish) /退出接收循环检测 while(flag)/
4、T0已启动标志,用完记得清0,由外部中断0启动,初次启动检测 /第一次低电平测宽已经开始 while(!cin);/等待高电平到来,T0中断不会在这里发生,因为低电平宽度不会有65MS这么长 _nop_();aj=TH0; /低电平宽度 先存高8位数据 j+;aj=TL0;/存储的是低电平宽度 /数组下移 TH0=0;/重装T0 TL0=9;/补偿前面消耗的时间 TR0=1;/重新启动T0,计时高电平 /高电平测宽开始 while(cin&flag);/等待cin低电平到来。T0中断就是在这里等待的时候发生的,因为最后一个电平必然是高电平(无信号就是高)/flag=1表示T0还没中断,还是接收
5、有效 if(flag)/flag为1才表示计时有效,flag=0表示最后高电平很长结束了 /加个flag才能退出这个等待 /先存高8位数据 /存储的是低电平段 /重装T0 TL0=0;/重新启动T0,计时低电平 /判断是否退出接收 if(end)/用完接收启动标志要清0 delayms(122);/亮两个灯表示接收成功 finish=0;/接收完亮两个灯 /开外部按键中断1 /*/发射函数初始化 void init2()/发射初始化 /关闭发射端,由于它与38K输出端并联,所以拉低不输出 TMOD=0x21;/T0方式1,T1方式2 TH1=-(13%256);/定时13us翻转一次,即38K
6、HZ (26us)TL1=-(13%256);ET1=1; /T1中断 ET0=0;/禁止T0中断 TR1=1; /T1启动38K载波开始/ 红外发射子程序 void fashe() /发射程序里没有安排推出操作,所以只有重启才能重新进入选择模式 ADC();switch(k)case 1:for(j=0;jb0;j+)aj=Byte_Read(j); init2();led(b0);break; /必须先读EEPROM再开定时器中断 case 2:b1;j+)aj=Byte_Read(j+0x200);led(b1);case 3:b2;j+)aj=Byte_Read(j+0x400);le
7、d(b2);case 4:b3;j+)aj=Byte_Read(j+0x600);led(b3);case 5:b4;j+)aj=Byte_Read(j+0x800);led(b4);case 6:b5;j+)aj=Byte_Read(j+0xa00);led(b5);default:k=0;/发射完毕要关闭38K载波 TR1=0;/发射高电平。接收端就是低电平。而载波就是高电平有38KHZ载波,二极管反复38K亮灭。低电平什么也没有,二极管不通。void led(uchar x)x=x/2;/2个数组是一段电平,而且肯定是偶数个数组 2*N 是偶数嘛 while(x) _nop_(); /空
8、操作不废时序。就是没指令/因为共有2N个数据。第一个肯定是发射的高电平。因为接收端首位肯定是0./红外二极管亮表示发射高电平。接收的就是低电平。高电平就是有38K载波,低电平什么也没有,二极管不通。/所以,高电平发射38K波形,低电平不发射。时间由contrl控制/*数组里存的是要定时的时间。这里不能用256-aj,因为对没有存入数据的EEPROM, 读出来数据都是1,即aj=0xff, 用减法会定时65MS的,用负号就不会,已启动他就会溢出中断 */ TH0=-aj;/数组里存的是要定时的时间。这里不能用256-aj TL0=-aj;contrl=!contrl;/首次发射肯定是高电平,所以
9、要翻转。每个电平发完到第二个开始前多了一次翻转。/ TF0);/等待T0溢出,因为没有采用T0中断 /加空操作是为了防止在执行指令的时候发生中断,破坏38Khz频率。x-;/必须在清0溢出位TF之前关闭定时器。不然会自动启动的 就是没指令 TF0=0;/溢出位清0 /发射完毕,T0关闭 /*/中断函数要指定使用那组寄存器,使用同一组时可能会破坏了上次寄存器中的数据 /同一优先级的中断可以使用同一组寄存器 void time0() interrupt 1 using 1/定时器0中断 /有65MS以上了,表示接收完毕 EX0=0;bzu/0x200=j; /j是从0开始的,最后一次电平存完j自加
10、1了,总长度正好是当前值 addr=zu;/因为下面zu值还要用,所以下面不直接用ZU /zu是每个存储空间的起始地址 for(;if(zu0xa00)/第一组代码完毕后,转到第二组,每组都是200个空间 zu+=0x200; /测完一组 ,扇区地址指向下一个扇区 else zu=0x000; /超过6组代码,内存重新指向第1组 end=1;/退出接收函数最外层循环 / 发射频率38khz由T1产生 void time1() interrupt 3 using 1 /定时器1中断 ,因为默认是同优先级,所以可以使用同一组寄存器 /38K翻转产生 / 外部中断 存储高电平长度 void inte
11、rint0() interrupt 0 using 1 /外部中断0 if (0=flag)/flag=0表示是首次接收到脉冲 TL0=10;/前面延时函数消耗的时间补上 /关闭外部中断0,以后的计数都在接收函数里 flag=1;/表示启动T0 /*/ 外部按键中断 1 void interint1() interrupt 2 using 1 /外部中断1 receive=1;/等过抖动时间 /AD转换初始化 -打开ADC电源 void InitADC()P1=0xff;/这里对其他用到P1口的地方有影响 ADC_CONTR|=0x80;delayms(30);/这两个寄存器用来设置 P1口四种状态,每一位对应一个P1引脚 ,按状态组合操作 P1M0=0x08;P1M1=0x08;/设置 P1.3做AD / AD转换程序 void ADC() ADC_DATA = 0; /清除结果 ADC_CONTR = 0x60; /转换速度设置 0x60 最快速度 ADC_CONTR = 0xE0; /1110,0000 清 ADC_FLA
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1