300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > 单片机测量脉宽c语言程序 51单片机hc-sr04超声波测距(脉宽测量)DEMO程序

单片机测量脉宽c语言程序 51单片机hc-sr04超声波测距(脉宽测量)DEMO程序

时间:2020-03-23 20:00:15

相关推荐

单片机测量脉宽c语言程序 51单片机hc-sr04超声波测距(脉宽测量)DEMO程序

/***********************************************************************************************************/

//hc-sr04 超声波测距模块DEMO程序

//晶振:11。0592

//接线:模块TRIG接 P0.2ECH0 接P0.1

//数码管:共阳数码管P1接数据口,P2.5 P2.4 P2.3接选通数码管

/***********************************************************************************************************/

#include //器件配置文件

#include

#define uchar unsigned char

#define uint unsigned int

unsigned inttime=0;

unsigned inttimer=0;

unsigned char posit=0;

unsigned long S=0,S1,S2;

bit flag =0;

sbitTX123=P3^4; //T

sbitRX123=P3^5; //E

sbitKJA=P3^6; //近距离存储按钮

sbitKJAN=P3^7; //远距离存储按钮

sbitS1J=P3^3; //近距离动作继电器

sbitS2J=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; //中断溢出标志

}

/********************************************************/

voidzd3()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++);

}

}

/*********************************************************/

voidmain(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;

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。