c51单片机超声测距hcsr04在 rtos运行的 实验 基于陈明计先生的smallrtos

24 篇文章 0 订阅
7 篇文章 1 订阅

c51单片机超声测距hcsr04在  rtos运行的 实验  基于陈明计先生的smallrtos


主要代码

/********************************************************************************************************/
 /*位定义*/
sbit CHUFA=P2^1;    //位定义超声波触发端(10us以上高电平触发)
sbit JIESHOU=P2^3;    //接收端(接受高电平)
sbit OUT0=P3^2;        //外部中断0	INT0



uchar JS_FLAG;        //接收标志
uint CF_TIME,t0;


float 	t1;
uchar nn;

/*函数声明*/
void timer0();        
void int0();
void hcsr04(void);

        void hcsr04(void)
{
    while (1)
    {
	Reset_hcsr04:

	TR0=0;//关闭定时器0
	TH0=0;//0xd8;//(65536-10000)/256;    //装初值 10ms
	TL0=0;//0xd8;//(65536-10000)%256;    
	
	EX0=0; 


	t0=0;    
    JS_FLAG=0;   	
	CHUFA=0;        //初始化拉低触发端和接收端电平
    //JIESHOU=0;	//
	//OUT0=1;	//赋值会影响外部中断
    //JIESHOU=1;
    while(1){
	hcsr04_step1:
        //;      //外部中断0被赋值为接收端信号,当出现下降沿是触发外部中断0
        if(JS_FLAG==0){        //如果没有接收到高电平则触发
			//PutChar(0x30);
			JS_FLAG=1;
			//TR0=0;TR0=0; //关闭定时器0
			t0=0;
			while(JIESHOU){	//检查接收口是否存在问题
				OSWait(K_TMO,OS_TICKS_PER_SEC / 20);
				t0++;	
				if(t0>10){	 
					//硬件错误,收到尚未触发的接收信号。
					//系统调度等待
					 JS_FLAG=4;
					  goto hcsr04_step1;
				}
			}
		}else if(JS_FLAG==1){	
			//PutChar(0x31);
			OS_ENTER_CRITICAL(); //------------------------	测距禁止打断Begin
					
			CHUFA=1;
			//初始化触发时间(大于10us)						 
			//_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();    
			//_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
			//_nop_(); 
			
			CF_TIME=15;
			while(CF_TIME--);    //10us以上高电平触发传感器
			CHUFA=0;
			
			
			//8个40kHz周期电平,同时检测回波。一旦检测到有回波信号则输出回响信号
			//8个40kHz =200us
			//回响接收完200us
			//2cm距离=59us
			//400cm距离=11,764us
			t0=0 ;CF_TIME=0;
			while(JS_FLAG==1&&!JIESHOU){
				CF_TIME++;
				if(CF_TIME>=255){	 CF_TIME=0;
				  t0++;
				  if(t0>=100){
				  	 JS_FLAG=5;	//硬件错误,超时无响应。
					 CF_TIME=0; 
					 
				  }
				}
			}  /**/	
			t0=0;CF_TIME=0;
			//while(!JIESHOU);//			
			if(JIESHOU){
				
				//OUT0=1;
				//IT0=1;             //外部中断选择下降沿触发
				//EX0=1;			 使用外部中断控制计时器停止,系统切换需要时间,小距离<8cm误差大
				
				TR0=1;
								  
				// 	JS_FLAG=2;while(JIESHOU);TR0=0;JS_FLAG=3;//单纯的等待。延时不可控。
			   //*
				//新的解决方案,小距离等待可控延时,大距离开外部中断。使用了t0变量等待在一个计时器中断内。
				
				while(JIESHOU){
					CF_TIME++;
					if(CF_TIME>=250){	 CF_TIME=0;
					  t0++;
					  if(t0>=2){  t0=0;
						 goto _1_0;
					  }
					}
				}
				 t0=0;//以上循环使用计时器中断次数变量,记得清零
				TR0=0;
				JS_FLAG=3;	//*/
				
			}	

			goto _1_1;
			_1_0:
			
			JS_FLAG=2;	//短距离测量超时,长距离外部中断控制计时器。
			
			EX0=1;
			IT0=1;             //外部中断选择下降沿触发	
			_1_1:
			OS_EXIT_CRITICAL();	//------------------------	测距禁止打断End
				
		}else if(JS_FLAG==2){ //长距离接收中
			//PutChar(0xcc);	//PutChar(t0);			
			if(t0>10){ //超出有效距离			  
				//t1=max
				TR0=0;//关闭定时器0  
				EX0=0;
				t0=0;
				JS_FLAG=6;
					
			
			}
		
			OSWait(K_TMO,OS_TICKS_PER_SEC/20 );
		
		}else if(JS_FLAG==3){ //接收完成 
			 TR0=0;//关闭定时器0 
			 EX0=0;
			 JS_FLAG=10;
			 //PutChar(0xaa);	PutChar(t0);
			 t1=t0*65536+TH0*256+TL0;
			 t1=t1*17.2/1000;
			 	
			 if(t1/100>10){
			 	//距离超过10m
			 	JS_FLAG=7;
			 }
			 
			
			 //系统调度等待
        	 //OSWait(K_TMO,OS_TICKS_PER_SEC/10 );
			
		}else if(JS_FLAG==4){
			 //OSQPost(CommandData,4);
			 //OSQIntPost(SerialOutData,4);
			 //Send(4);
			 PutChar(0xee);
			 PutChar(0x04);
			 //	错误:未触发的接收信号
			 //系统调度等待
			 OSWait(K_TMO,OS_TICKS_PER_SEC / 10);
			 goto Reset_hcsr04;
		}else if(JS_FLAG==5){
			 //OSQPost(CommandData,5);
			 //OSQIntPost(SerialOutData,5);
			 //Send(5);
			 PutChar(0xee);
			 PutChar(0x05);
			 //错误:发送触发信号后,无响应。
			 //系统调度等待
			 OSWait(K_TMO,OS_TICKS_PER_SEC / 10);
			 goto Reset_hcsr04;
		}else if(JS_FLAG==6){
			 //OSQPost(CommandData,6);
			 //OSQIntPost(SerialOutData,6);
			 //Send(6);
			 PutChar(0xee);
			 PutChar(0x06);
			 //错误:硬件响应超时。
			 //系统调度等待
			 OSWait(K_TMO,OS_TICKS_PER_SEC / 10);
			 goto Reset_hcsr04;
		}else if(JS_FLAG==7){
			 //OSQPost(CommandData,6);
			 //OSQIntPost(SerialOutData,6);
			 //Send(7);
			 PutChar(0xee);
			 PutChar(0x07);
			 //错误:超出测量范围。
			 //系统调度等待
			 OSWait(K_TMO,OS_TICKS_PER_SEC / 10);
			 goto Reset_hcsr04;
		} else if(JS_FLAG==10){
			 //发送测量结果
			 PutChar(0xff);
			 PutChar((uchar)(t1/100));	 //0x04	m
			 while(t1>100){
			 	 t1	-=100;
			 }
			 nn=(uchar)(t1);
			 PutChar((((nn-(nn%10))/10)<<4)+nn%10);	 //0x99 cm
			 //系统调度等待
			 OSWait(K_TMO,OS_TICKS_PER_SEC / 10);
			 goto Reset_hcsr04;
		}

        
    }
    }
}
/*定时器0中断程序*/
#if EN_OS_INT_ENTER >0 
#pragma disable                                        /* 除非最高优先级中断,否则,必须加上这一句                 */
#endif
void timer0() interrupt 1{
	
 	t0++; //每进入一次中断t0加1  
	//PutChar(0x00);
	//	PutChar(0x00); 
	//TH0=0; 
	//TL0=0;
    //TH0=0xfd;//(65536-10000)/256;    //装初值 10ms
    //TL0=0xfd;//(65536-10000)%256;
                          
}


/*外部中断0中断程序*/
#if EN_OS_INT_ENTER >0 
#pragma disable                                        /* 除非最高优先级中断,否则,必须加上这一句                 */
#endif
void int0() interrupt 0{

	
	TR0=0; 
	//OUT0=1;
	EX0=0;
	IT0=0;             //外部中断选择低电平触发
	IE0=0;
	JS_FLAG=3;        //接收标志位置  
	/*if(JS_FLAG==2){
	   	            //一旦进入外部中断0,说明接收端收到下降沿信号。关闭定时器0
		   
		PutChar(0xbb);
		PutChar(0xdd);
		PutChar(TH0);
		PutChar(TL0);
	} */
	
}


/**********************end****************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值