|
单片机源程序如下:
- /***********************************************************************************************************/
- //hc-sr04 超声波测距模块DEMO程序
- //晶振:11。0592
- //接线:模块TRIG接 P0.2 ECH0 接P0.1
- //数码管:共阳数码管P1接数据口,P2.5 P2.4 P2.3接选通数码管
- /***********************************************************************************************************/
- #include <reg51.h> //器件配置文件
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- unsigned int time=0;
- unsigned int timer=0;
- unsigned char posit=0;
- unsigned long S=0,S1,S2;
- bit flag =0;
- sbit TX123=P3^4; //T
- sbit RX123=P3^5; //E
- sbit KJA=P3^6; //近距离存储按钮
- sbit KJAN=P3^7; //远距离存储按钮
- sbit S1J=P3^3; //近距离动作继电器
- sbit S2J=P3^2; //远距离动作继电器
-
- unsigned char const discode[] ={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xBF,0xff/*-*/};
- unsigned char const positon[3]={ 0xdf,0xef,0xf7};
- unsigned char disbuff[4]={ 0,0,0,0,};
- /******************定义命令字节******************/
- #define Read_COM 0x01 //字节读数据命令
- #define Prog_COM 0x02 //字节编程数据命令
- #define Erase_COM 0x03 //扇区擦除数据命令
- #define En_Wait_TIME 0x81 //设置等待时间 ,并使能ISP/IAP
- #define Start_ADDRH 0x20 //扇区地址高位
- #define Start_ADDRL 0x00 //扇区地址低位
- /****************特殊功能寄存器声明****************/
- sfr ISP_DATA = 0xe2;
- sfr ISP_ADDRH = 0xe3;
- sfr ISP_ADDRL = 0xe4;
- sfr ISP_CMD = 0xe5;
- sfr ISP_TRIG = 0xe6;
- sfr ISP_CONTR = 0xe7;
- /*****************关闭ISP&IAP功能*****************/
- void ISP_IAP_disable(void)
- {
- ISP_CONTR = 0x00;
- ISP_CMD = 0x00;
- ISP_TRIG = 0x00;
- }
- /*********************字节读**********************/
- uchar Byte_read(uint byte_addr)
- {
- EA = 0; //关中断
- ISP_CONTR = En_Wait_TIME; //开启ISP&IAP,并送等待时间
- ISP_CMD = Read_COM; //送字节读命令字
- ISP_ADDRH = (uchar)(byte_addr >> 8); //送地址高字节
- ISP_ADDRL = (uchar)(byte_addr & 0x00ff); //送地址低字节
- ISP_TRIG = 0x46; //送触发命令字0x46
- ISP_TRIG = 0xB9; //送触发命令字0xB9
- _nop_();
- ISP_IAP_disable(); //关闭ISP&IAP功能
- EA = 1; //开中断
- return (ISP_DATA);
- }
- /*********************字节编程*********************/
- void Byte_program(uint byte_addr,uchar isp_iap_data)
- {
- EA = 0; //关中断
- ISP_CONTR = En_Wait_TIME; //开启ISP&IAP,并送等待时间
- ISP_CMD = Prog_COM; //送字节编程命令字
- ISP_ADDRH = (uchar)(byte_addr >> 8); //送地址高字节
- ISP_ADDRL = (uchar)(byte_addr & 0x00ff); //送地址低字节
- ISP_DATA = isp_iap_data; //送数据进ISP_DATA
- ISP_TRIG = 0x46; //送触发命令字0x46
- ISP_TRIG = 0xB9; //送触发命令字0xB9
- _nop_();
- ISP_IAP_disable(); //关闭ISP&IAP功能
- EA = 1; //开中断
- }
-
- /*********************扇区擦除*********************/
- void Sector_erase(uint sector_addr)
- {
- EA = 0; //关中断
- ISP_CONTR = En_Wait_TIME; //开启ISP&IAP;并送等待时间
- ISP_CMD = Erase_COM; //送扇区擦除命令字
- ISP_ADDRH = (uchar)(sector_addr >> 8); //送地址高字节
- ISP_ADDRL = (uchar)(sector_addr & 0X00FF); //送地址低字节
- ISP_TRIG = 0X46; //送触发命令字0x46
- ISP_TRIG = 0XB9; //送触发命令字0xB9
- _nop_();
- ISP_IAP_disable(); //关闭ISP&IAP功能
- EA = 1;
- }
- /********************************************************/
- void Display(void) //扫描数码管
- {
- if(posit==0)
- {P1=(discode[disbuff[posit]])&0x7f;}
- else
- {P2=discode[disbuff[2]];
- P0=discode[disbuff[1]];}
- if(++posit>=3)
- posit=0;
- }
- /********************************************************/
- void Conut(void)
- {
- time=TH0*256+TL0;
- TH0=0;
- TL0=0;
-
- S=(time*1.7)/100; //算出来是CM
- if((S>=250)||flag==1) //超出测量范围显示“-”
- {
- flag=0;
- S=250;
- }
- else
- {
- disbuff[0]=S%1000/100;
- disbuff[1]=S%1000%100/10;
- disbuff[2]=S%1000%10 %10;
- }
- }
- /********************************************************/
- void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
- {
- flag=1; //中断溢出标志
- }
- /********************************************************/
- void zd3() interrupt 3 //T1中断用来扫描数码管和计800MS启动模块
- {
- TH1=0xfc;
- TL1=0x30;
- Display();
- timer++;
- if(timer>=400) //调节测速频率
- {
- timer=0;
- TX123=1; //800MS 启动一次模块
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- TX123=0;
- }
- }
- /*****************************************************************************
- * 延时子程序 *
- * *
- ******************************************************************************/
- void delay(unsigned int ms)
- {
- unsigned char i;
- while(ms--)
- {
- for(i = 0; i < 120; i++);
- }
- }
- /*********************************************************/
- void main( void )
- {
- S1J=0;
- delay(1000);
- S1J=1;
- TMOD=0x11; //设T0为方式1,GATE=1;
- TH0=0;
- TL0=0;
- TH1=0xf8; //2MS定时
- TL1=0x30;
- ET0=1; //允许T0中断
- ET1=1; //允许T1中断
- TR1=1; //开启定时器
- EA=1; //开启总中断
-
- S1=Byte_read(0x2000);
- S2=Byte_read(0x2200); //读EEPROM
- disbuff[0]=S1%1000/100;
- disbuff[1]=S1%1000%100/10;
- disbuff[2]=S1%1000%10 %10;
- Display();
- delay(1000);
- disbuff[0]=S2%1000/100;
- disbuff[1]=S2%1000%100/10;
- disbuff[2]=S2%1000%10 %10;
- Display();
- delay(1000);
- while(1)
- {
- while(!RX123); //当RX为零时等待
- TR0=1; //开启计数
- while(RX123); //当RX为1计数并等待
- TR0=0; //关闭计数
- Conut(); //计算
- if(!KJA){Sector_erase(0x2000); //扇区擦除
- Byte_program(0x2000,S); //写EEPROM
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- S1=Byte_read(0x2000); }
- if(!KJAN){Sector_erase(0x2200); //扇区擦除
- Byte_program(0x2200,S); //写EEPROM
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- S2=Byte_read(0x2200); }
- if(S>=S1)S1J=0;
- else S1J=1;
- }
- }
复制代码
所有资料51hei提供下载:
|
|