📄 main.c
字号:
/--------------------------------------------------------------------------------
** 修改人: li
** 版 本: 2.0
** 日 期: 2009年3月20日
** 描 述: 在硬件上与原始版本不同的是超声波发射电路采用MAX232来提高发射电压
在软件上与原始版本不同的是打开接收超声波中断时间不同,比原始版本加了一点延时(做这个作品时仔细想下为什么)
注 意:超声波探头之间的距离与发射的振幅有关。
***********************************************************************************************************/
#include<STC12C5410AD.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define duan_ma P1
sbit H1 = P3^3;
sbit H2 = P3^4;
sbit H3 = P3^5;
sbit chaosb_t = P3^7;
uchar map[10]={0x14,0xf6,0x1a,0x52,0xf0,0x51,0x11,0x76,0x10,0x70}; //七段共阳LED显示数码转换为笔段码0--9。
uint juli=0; //juli用于存放距离值
uint t_no=0; //t_no用于存放发射到接受的T0的计数值
//uchar pulse_t = 0; //pulse_t用于存放发射的脉冲个数
uchar pulse_r = 0; //pulse_r用于存放接收的脉冲个数
bit b=1;
//uint dd=0;
//STC12C4052在11.0592MHz晶振下(1T时钟时)的1毫秒延时子程序
//---------------------延时------------------------
void delay1ms(uint time) //11.0592M晶振 1ms
{
uint i;
uint j;
// k=time*3; //修正值
for (i=0;i<time;i++)
{
j=690; //164 //j=680:1s==990ms;5s==4.940s;8s==7.910s j=690:100ms==101ms;500ms==501ms;1s==1.004s
while(j--);
}
}
///////////////////////////////////////////////------------------------------------
void display(uint number) //数码管显示程序,可以显示的数值范围为十进制的0~999。
{
uchar bai=0,shi=0,ge=0;
bai= number%1000/100;
shi= number%100/10;
ge = number%10;
duan_ma=map[bai];
H1=0;
H2=1;
H3=1;
delay1ms(1); //保证每一位都显示一定的时间,否则数码管会点不亮并且闪烁。
H1=1;H2=1;H3=1;
duan_ma=map[shi];
H2=0;
H1=1;
H3=1;
delay1ms(1); //
H1=1;H2=1;H3=1;
duan_ma=map[ge];
H3=0;
H1=1;
H2=1;
delay1ms(1); //
H1=1;H2=1;H3=1;
}
//---------------------------------------------------------------------------------
void IOinit() //复位时默认为传统的准双向I/O口。
{
P0M0 = 0; //PnM0 PnM1 :00 设置I/O口为准双向输出;01推挽输出,10仅为输入(高阻),11开漏
P0M1 = 0;
P1M0 = 0x00;
P1M1 = 0xff; //设P1口为推挽输出
P2M0 = 0;
P2M1 = 0;
P3M0 = 0x00;
P3M1 = 0xf8; //设P3.3、P3.4、P3.5、P3.7为推挽输出
P1=0xFF; //主要是向段码端口写入1初始化
P37=0; //
H1=1; //
H2=1;
H3=1;
}
//***********************************以下是中断等初始化程序**********************************
void INT_System_init() //外部中断初始化
{
// IT0=0; //外部中断0,低电平触发
IT0=1; //外部中断0,下降沿触发
EX0=1; //使能外部中断0
// IT1=0; //外部中断1,低电平触发
// IT1=1; //外部中断1,下降沿触发
EX1=0; //禁能外部中断1
//
}
//////////////////////
void T0init()
{
TMOD |= 0x01; //设置T0为十六位定时模式,
TH0 = 0x00; //
TL0 = 0x00; //
AUXR =0; // T0工作在12T模式,注意:系统指令周期依然是1T,0.0904224us,不能改变的。
TR0 = 0; //
ET0 = 0;
}
void T1init()
{
TMOD |= 0x20; //设置T1为八位自动重装模式,作为波特率发生器9600
TH1 = 0xFD; //
TL1 = 0xFD; //
AUXR =0; // T1工作在12T模式
TR1 = 1; //
ET1 = 0;
}
void UARTint()
{
SCON = 0x40; //串口工作在方式1,波特率可变的8位异步通信方式。串口不接收数据。
PCON = 0; // 波特率不倍增
}
///////////////////////////
void INT0_serve() interrupt 0 using 0 //IE0_VECTOR 外部INT0中断服务程序
{
pulse_r++;
if(pulse_r==5)
{
TR0=0;
// pulse_r=0;
b=0;
EA=0;
}
}
/*
void T0_serve() interrupt 1 using 1 //定时器T0中断服务程序,用于控制测量超时,若在测量的过程中T0溢出,则说明出错,中断本次测量。
{
EA = 0;
TL0 = 0; //
TH0 = 0; //
b=0;
pulse_r=0;
juli=888;
display(juli); //数码管显示程序
// EA = 1;
}
*/
//---------------------------------------------------------------------------
void send40K() //发40KHz脉冲函数,脉冲个数应大于或等于5个。
{uchar i,j;
uchar f=0;
uchar k=0;
pulse_r=0;
TH0 = 0x00; //
TL0 = 0x00; //
TR0=0;
b=1;
chaosb_t = 0;
EA=0;
for(f=0;f<5;f++) //发5个预测试脉冲距离
{
chaosb_t=~chaosb_t; //经过二次取反得到一个完整的40K方波信号。
for(k=0;k<17;k++);
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();
chaosb_t=~chaosb_t;
for(k=0;k<16;k++);
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();//
_nop_();_nop_();
}
TR0=1;
for(i=0;i<68;i++) {for(j=0;j<25;j++);};
EA=1;
for(i=0;i<33;i++) { display(juli); }; //数码管显示程序
TR0=0;
EA=0;
if(pulse_r!=5) //用于控制测量超时,若在以上延时过后还收不够脉冲则说明本次测量出错,距离显示为888,表示错误值。
juli=888; //测量有效距离不大于888cm,实际测量距离为2--300cm。
else
{
t_no=TH0;
t_no<<=8;
t_no|=TL0;
display(juli); //数码管显示程序 //
juli=((t_no*1.05)/1000000)*345*50-1; //计算距离值,单位是厘米
// juli=((t_no*1.0850694)/1000000)*345*50-1; //计算距离值,单位是厘米。
}
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
void main()
{
uint a=0;
uchar juli_h=0;
uchar juli_l=0;
IOinit(); //
INT_System_init(); //
T0init();
T1init();
UARTint();
EA =1;
while(1)
{
a++;
if(a==2) //
{
a=0;
juli_l=juli&0x00ff;
juli_h=juli>>8;
display(juli); //数码管显示程序 // // delay1ms(2); //
SBUF=juli_h; //先发高八位,后利用显示函数延时大概6ms后再发低八位。距离单位为厘米。
while(!TI);
TI=0;
SBUF=juli_l;
}
display(juli); //数码管显示程序
send40K(); // pulse_t
display(juli); //数码管显示程序
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -