⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 超声波测距,包括有pcb原理图
💻 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 + -