?? 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 + -