单片机测距遇到问题
时间:10-02
整理:3721RD
点击:
小弟做了个距离测量电路,先用电压输入然后模数转换后乘以一个数后成为一个安全距离,然后与测距装置所测的距离比较,若是距离小于安全距离则灯亮蜂鸣器响。可是焊接起来后测试有问题,求大神指导
//晶振:11.0592
//接线:模块TRIG接 P2.4(控制端) ECH0 接2.3(接收端)
//数码管:共阳数码管P1接数据口,P2.1 P2.2 P2.3接选通数码管
#include<STC12C5A60S2.H>
#include<intrins.h> //51基本运算(包括_nop_空函数)
sbit RX=P2^3 ;
sbit TX=P2^4 ;
float v1; //电压
int v2; //电压1
int d1; //安全距离
unsigned int time=0;
unsigned int timer=0;
unsigned long S=0; //距离
bit flag =0; //超出
sbit c=P2^6;
sbit d=P2^7;
sbit e=P2^0;
sbit f=P2^1;
sbit g=P2^2;
char discode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9八个数字
/*------------------延时函数---------------------------*/
void DELAY_MS (unsigned int a){
unsigned int i;
while( --a != 0){
for(i = 0; i < 600; i++);
}
}
/*------------------AD初始化程序---------------------------*/
void ADC_init(unsigned char CHA)
{
unsigned char AD_FIN=0; //存储A/D转换标志
CHA&=0x07; //选择ADC的8个接口中的一个(0000 0111 清0高5位)
ADC_CONTR|=0x40; //ADC转换的速度(0XX0 0000 其中XX控制速度)
_nop_();
ADC_CONTR&=CHA; //选择A/D当前通道
ADC_CONTR|=0x80; //启动A/D电源
DELAY_MS(1); //使输入电压达到稳定(1ms即可)
}
/*--------------------AD转化函数---------------------------*/
unsigned int ADC_Read(void)
{
unsigned char AD_FIN; //存储A/D转换标志
ADC_CONTR|=0x80; //启动A/D转换(0000 1000 令ADCS = 1)
_nop_();
_nop_();
_nop_();
_nop_();
while(AD_FIN==0)
AD_FIN=ADC_CONTR&0x10; //0001 0000测试A/D转换结束否
ADC_CONTR&=0xe7; //1111 0111 清ADC_FLAG位, 关闭A/D转换,
return(ADC_RES); //返回A/D转换结果(ADC数据8位在ADC_RES中)
}
/*------------------测距函数------------------------------*/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/100; //算出来是CM
if((S>=700)||flag==1) //超出测量范围显示“-”
{
flag=0;
}
else
{
if(S>=d1)
{
c=0;
d=0;
DELAY_MS(500);
c=1;
d=1;
}
else{
c=1;
d=1;
}
}
}
/********************************************************/
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
flag=1; //中断溢出标志
}
/********************************************************/
void zd3() interrupt 3 //T1中断用来扫描数码管和计800MS启动模块
{
TH1=0xf8;
TL1=0x30;
timer++;
if(timer>=400)
{
timer=0;
TX=1; //800MS 启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
}
/*********************************************************/
/*-------------------主函数---------------------------*/
void main(void)
{
ADC_init(0);
P2M0=0xff; //设置P0口为推挽输出
P1M1=0xff; //设置P1口为高阻输入
while(1)
{
v1=ADC_Read()*(4.5/256.0); //取电压
v1=v1*100;
v2=(int)v1;
d1=v2*1.5; //计算安全距离
e=1;
f=0;
g=0;
P0=discode[v2/100]; //取百位
DELAY_MS(5);
e=0;
f=1;
g=0;
P0=discode[v2%100/10]; //取十位
DELAY_MS(5);
e=0;
g=0;
f=1;
P0=discode[v2%100%10]&0x7f; //取个位
DELAY_MS(5);
TMOD=0x11; //设T0为方式1,GATE=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; //开启总中断
while(1)
{
while(!RX); //当RX为零时等待
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
}
}
}
//晶振:11.0592
//接线:模块TRIG接 P2.4(控制端) ECH0 接2.3(接收端)
//数码管:共阳数码管P1接数据口,P2.1 P2.2 P2.3接选通数码管
#include<STC12C5A60S2.H>
#include<intrins.h> //51基本运算(包括_nop_空函数)
sbit RX=P2^3 ;
sbit TX=P2^4 ;
float v1; //电压
int v2; //电压1
int d1; //安全距离
unsigned int time=0;
unsigned int timer=0;
unsigned long S=0; //距离
bit flag =0; //超出
sbit c=P2^6;
sbit d=P2^7;
sbit e=P2^0;
sbit f=P2^1;
sbit g=P2^2;
char discode[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0-9八个数字
/*------------------延时函数---------------------------*/
void DELAY_MS (unsigned int a){
unsigned int i;
while( --a != 0){
for(i = 0; i < 600; i++);
}
}
/*------------------AD初始化程序---------------------------*/
void ADC_init(unsigned char CHA)
{
unsigned char AD_FIN=0; //存储A/D转换标志
CHA&=0x07; //选择ADC的8个接口中的一个(0000 0111 清0高5位)
ADC_CONTR|=0x40; //ADC转换的速度(0XX0 0000 其中XX控制速度)
_nop_();
ADC_CONTR&=CHA; //选择A/D当前通道
ADC_CONTR|=0x80; //启动A/D电源
DELAY_MS(1); //使输入电压达到稳定(1ms即可)
}
/*--------------------AD转化函数---------------------------*/
unsigned int ADC_Read(void)
{
unsigned char AD_FIN; //存储A/D转换标志
ADC_CONTR|=0x80; //启动A/D转换(0000 1000 令ADCS = 1)
_nop_();
_nop_();
_nop_();
_nop_();
while(AD_FIN==0)
AD_FIN=ADC_CONTR&0x10; //0001 0000测试A/D转换结束否
ADC_CONTR&=0xe7; //1111 0111 清ADC_FLAG位, 关闭A/D转换,
return(ADC_RES); //返回A/D转换结果(ADC数据8位在ADC_RES中)
}
/*------------------测距函数------------------------------*/
void Conut(void)
{
time=TH0*256+TL0;
TH0=0;
TL0=0;
S=(time*1.7)/100; //算出来是CM
if((S>=700)||flag==1) //超出测量范围显示“-”
{
flag=0;
}
else
{
if(S>=d1)
{
c=0;
d=0;
DELAY_MS(500);
c=1;
d=1;
}
else{
c=1;
d=1;
}
}
}
/********************************************************/
void zd0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
{
flag=1; //中断溢出标志
}
/********************************************************/
void zd3() interrupt 3 //T1中断用来扫描数码管和计800MS启动模块
{
TH1=0xf8;
TL1=0x30;
timer++;
if(timer>=400)
{
timer=0;
TX=1; //800MS 启动一次模块
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
TX=0;
}
}
/*********************************************************/
/*-------------------主函数---------------------------*/
void main(void)
{
ADC_init(0);
P2M0=0xff; //设置P0口为推挽输出
P1M1=0xff; //设置P1口为高阻输入
while(1)
{
v1=ADC_Read()*(4.5/256.0); //取电压
v1=v1*100;
v2=(int)v1;
d1=v2*1.5; //计算安全距离
e=1;
f=0;
g=0;
P0=discode[v2/100]; //取百位
DELAY_MS(5);
e=0;
f=1;
g=0;
P0=discode[v2%100/10]; //取十位
DELAY_MS(5);
e=0;
g=0;
f=1;
P0=discode[v2%100%10]&0x7f; //取个位
DELAY_MS(5);
TMOD=0x11; //设T0为方式1,GATE=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; //开启总中断
while(1)
{
while(!RX); //当RX为零时等待
TR0=1; //开启计数
while(RX); //当RX为1计数并等待
TR0=0; //关闭计数
Conut(); //计算
}
}
}
自己帮自己顶顶,求大神呀
你的程序很乱,建议检查下数据类型的统一性。
我本来是分成两个单片机做的,然后把两个程序合在了一起