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****************************************/