设计要求
驱动超声波传感器,启动距离测量功能,并将其结果显示到数码管上。
距离数据单位为m,保留小数点后两位有效数字,数码管显示格式如下:
按键S9定义为“设置”按键,按下S9按键,设备自动将当前采集的距离数据设置为距离参数;
若实时距离数据超过距离参数,指示灯L1点亮,否则L1熄灭。
备注:
单片机IRC振荡器频率设置为12MHz。
按键模式:KBD;扩展方式:IO模式
个人代码
#include <STC15F2K60S2.H>
#include "intrins.h"
sbit TX=P1^0;
sbit RX=P1^1;
code unsigned char Seg_Table[] = {
0xc0, //0
0xf9, //1
0xa4, //2
0xb0, //3
0x99, //4
0x92, //5
0x82, //6
0xf8, //7
0x80, //8
0x90, //9
0xff
};
unsigned char Seg_Buff[]={10,10,10,10,10,10,10,10};
unsigned char keyval,keyold,keyup,keydown;
bit flag_seg=0,flag_key=0,flag_wave=0;
float distance_max=50.0; //当前距离
float distance=0.0; //设置的距离参数
//----------74HC138译码器控制----------
void init74hc138(unsigned char n){
P2=(P2&0x1f)|(n<<5);
P2&=0x1f;
}
//----------系统初始化----------
void init(){
P0=0x00;
init74hc138(5);
P0=0xff;
init74hc138(4);
//初始化蜂鸣器、LED等
}
//----------超声波延时----------
void delay() {
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
//----------发送超声波脉冲----------
void send_wave(){
unsigned char i=8;
do{
TX=1;
delay();
TX=0;
}while(i--);
}
//----------接收超声波并计算距离----------
void re_wave(){
send_wave();
TH1=0;
TL1=0;
TR1=1;
while((RX==1)&&(TF1==0));
TR1=0;
if(TF1){ //超时未收到回波
TF1=0;
distance=0.0;
}else{
distance=(float)(TH1<<8|TL1)*0.017;
if(distance > 500.0) distance = 0.0; //过滤无效值
}
}
//----------按键处理----------
void Key_Loop(){
P42=0;
keyval=0;
if(P32==0)keyval=1;
keydown=keyval&(keyold^keyval);
keyup=~keyval&(keyold^keyval);
if(keyval&&keyold!=keyval)distance_max=distance;
keyold=keyval;
}
//----------数码管动态扫描----------
void seg(unsigned char addr,num){
P0=0xff;
init74hc138(7);
P0=0x01<<addr;
init74hc138(6);
P0=Seg_Table[num];
if(addr==5)P0&=0x7f;
init74hc138(7);
}
void Seg_Loop(){
static unsigned char i=0;
seg(i,Seg_Buff[i]);
i++;
if(i==8)i=0;
}
//----------数码管显示处理----------
void seg_dis(){
unsigned char temp=(unsigned char)(distance+0.5);
Seg_Buff[7] = temp % 10; //小数第二位
Seg_Buff[6] = (temp / 10) % 10; //小数第一位
Seg_Buff[5] = (temp / 100) % 10; //个位
}
//----------LED状态更新----------
void led_max(){
P0 = (distance > distance_max) ? 0xfe : 0xff;
init74hc138(4);
}
void Timer0_Init(void) //100微秒@12.000MHz
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0x50; //设置定时初始值
TH0 = 0xFB; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0 = 1; //使能定时器0中断
EA = 1;
}
//void Timer1_Init(void) //1毫秒@12.000MHz
//{
// TMOD &= 0x0F; //设置定时器模式
// TL1 = 0x00; //设置定时初始值
// TH1 = 0x00; //设置定时初始值
//}
void main(){
init();
Timer0_Init();
// Timer1_Init();
TMOD |= 0x10; //定时器1模式1
while(1){
if(flag_seg){
flag_seg=0;
Seg_Loop();
}
if(flag_key){
flag_key=0;
Key_Loop();
led_max();
}
if(flag_wave){
flag_wave=0;
re_wave();
seg_dis();
}
}
}
void Timer0_Isr(void) interrupt 1
{
static unsigned int count=0;
count++;
flag_seg=1;
if(count==1000){
count=0;
flag_wave=1;
flag_key=1;
}
}
尚待解决的问题
测量距离有限,不超过40cm,一旦超过这个距离超声波接收装置就无法收到超声波,使得数码管不断闪烁。应该是我板子的问题,因为在平台测试结果显示正常。