题目要求:

程序实现:
main.c
/*头文件声明区*/
#include <STC15F2K60S2.H>
#include <Init.h>
#include <Key.h>
#include <Led.h>
#include <Seg.h>
#include <Uart.h>
#include <stdio.h>
#include <Wave.h>
#include <String.h>
/*头文件变量声明区*/
unsigned char Key_Val,Key_Dwon,Key_Up,Key_Old;
unsigned char Key_Slow_Down;
idata unsigned char Seg_Buf[8] = {16,16,16,16,16,16,16,16};
idata unsigned char Seg_Point[8] = {0,0,0,0,0,0,0,0};
unsigned char Seg_Pos;
unsigned int Seg_Slow_Down;
unsigned char ucLed[8] = {0,0,0,0,0,0,0,0};
/*串口数据*/
idata unsigned char Uart_Recv[10]; // 串口接收数据缓冲区
unsigned char Uart_Recv_Index; // 串口接收数据索引
bit Uart_flag; // 串口标志位
unsigned char Sys_Tick; // 系统时钟计数
bit Seg_Disp_Mode;//0-距离显示界面 1-参数显示界面
unsigned int dat;
unsigned int Can_Disp;
unsigned int Can_Ctrol = 30;
unsigned char Timer_200ms;
bit Timer_200ms_flag;//0
/*键盘处理函数*/
void Key_Proc()
{
if(Key_Slow_Down) return;
Key_Slow_Down = 1;
Key_Val = Key_Read();
Key_Dwon = Key_Val & (Key_Val ^ Key_Old);
Key_Up = ~Key_Val & (Key_Val ^ Key_Old);
Key_Old = Key_Val;
switch(Key_Dwon)
{
case 4://切换界面按键
Seg_Disp_Mode ^= 1;
if(Seg_Disp_Mode == 1)
Can_Disp = Can_Ctrol;
if(Seg_Disp_Mode == 0)
Can_Ctrol = Can_Disp;
break;
case 8://参数按键
if(Seg_Disp_Mode == 0)
{
Can_Ctrol = dat;
}
break;
case 12:
if(Seg_Disp_Mode == 1)
{
Can_Disp = Can_Disp + 10;
if(Can_Disp > 999)
Can_Disp = 999;
}
break;
case 16:
if(Seg_Disp_Mode == 1)
{
Can_Disp = Can_Disp - 10;
if(Can_Disp > 10000)
Can_Disp = 0;
}
break;
case 9:
printf("Distance:%dcm\r\n",(unsigned int)dat);
break;
}
}
/*信息处理函数*/
void Seg_Proc()
{
if(Seg_Slow_Down) return;
Seg_Slow_Down = 1;
/*信息获取区域*/
dat = Ut_Wave_String();
if(Seg_Disp_Mode == 0)//距离显示界面
{
Seg_Buf[0] = 18;
Seg_Buf[1] = 1;
Seg_Buf[5] = dat / 100 % 10;
Seg_Buf[6] = dat / 10 % 10;
Seg_Buf[7] = dat % 10;
if(Seg_Buf[5] == 0)
{
Seg_Buf[5] = 16;
if(Seg_Buf[6] == 0)
Seg_Buf[6] = 16;
}
}
if(Seg_Disp_Mode == 1)//参数显示界面
{
Seg_Buf[0] = 18;
Seg_Buf[1] = 2;
Seg_Buf[5] = Can_Disp / 100 % 10;
Seg_Buf[6] = Can_Disp / 10 % 10;
Seg_Buf[7] = Can_Disp % 10;
if(Seg_Buf[5] == 0)
{
Seg_Buf[5] = 16;
if(Seg_Buf[6] == 0)
Seg_Buf[6] = 16;
}
}
}
/*其他显示函数*/
void Led_Proc()
{
if(Seg_Disp_Mode == 0)
{
ucLed[0] = 1;
}
else
ucLed[0] = 0;
if(Seg_Disp_Mode == 1)
{
ucLed[1] = 1;
}
else
ucLed[1] = 0;
ucLed[2] = Timer_200ms_flag;
}
/*串口处理函数*/
// 处理串口接收到的数据,当接收到数据时更新接收索引和缓冲区。
void Uart_Proc()
{
if(Uart_Recv_Index == 0) return;
if(Sys_Tick >= 10)
{
Sys_Tick = Uart_flag = 0;
//逻辑函数
memset(Uart_Recv,0,Uart_Recv_Index);//清空Uart_Recv数组中的数据
Uart_Recv_Index = 0;//重置接收索引
}
}
/*定时器1初始化*/
void Timer1Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初值
TH1 = 0xFC; //设置定时初值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1;
EA = 1;
}
/*定时器1中断服务函数*/
void Timer1server() interrupt 3
{
if(++Key_Slow_Down == 10) Key_Slow_Down = 0;
if(++Seg_Slow_Down == 500) Seg_Slow_Down = 0;
if(Uart_flag) Sys_Tick++;
if(++Seg_Pos == 8) Seg_Pos = 0;
Seg_Disp(Seg_Pos,Seg_Buf[Seg_Pos],Seg_Point[Seg_Pos]);
Led_Disp(Seg_Pos,ucLed[Seg_Pos]);
//dat = Ut_Wave_String();
if(dat > Can_Ctrol)
{
if(++Timer_200ms == 200)
{
Timer_200ms = 0;
Timer_200ms_flag ^= 1;
}
}
}
/*串口1中断服务函数*/
void Uart1server() interrupt 4
{
if(RI == 1)// 检测到串口接收中断
{
Uart_flag = 1; // 设置串口标志位
Sys_Tick = 0; // 重置系统时钟
Uart_Recv[Uart_Recv_Index] = SBUF; // 保存接收到的数据
Uart_Recv_Index++; // 更新接收索引
RI = 0; // 清除中断标志位
}
if(Uart_Recv_Index > 10)
Uart_Recv_Index = 0;
}
/*主函数*/
void main()
{
System_Init();
Timer1Init();
UartInit();
while(1)
{
Key_Proc();
Seg_Proc();
Led_Proc();
Uart_Proc();
}
}
Uart.c
#include <Uart.h>
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x01; //串口1选择定时器2为波特率发生器
AUXR |= 0x04; //定时器2时钟为Fosc,即1T
T2L = 0xC7; //设定定时初值
T2H = 0xFE; //设定定时初值
AUXR |= 0x10; //启动定时器2
ES = 1;
EA = 1;
}
extern char putchar (char ch)
{
SBUF = ch; // 将ch写入SBUF,发出数据
while(TI == 0); // 等待发送完成
TI = 0; // 清除发送完成标志
return ch;
}
Wave.c
#include <Wave.h>
void Delay12us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 38;//38
while (--i);
}
void Ut_Wave_Init()
{
unsigned char i;
for(i=0;i<8;i++)
{
Tx = 1;
Delay12us();
Tx = 0;
Delay12us();
}
}
unsigned char Ut_Wave_String()
{
unsigned int time;
CH = CL =0;
CMOD = 0x00;
EA = 0;
Ut_Wave_Init();
EA = 1;
CR = 1;
while(Rx && !CF);
CR = 0;
if(!CF)
{
time = CH << 8| CL;
return(0.017 * time + 3);
}
else
{
CF = 0;
return 0;
}
}
测试结果:
