代码
main.c
#include <tim.h>
#include <seg.h>
#include <key.h>
#include <uart.h>
#include <sonic.h>
#include <stdio.h>
unsigned char ucStr[15],Uart_Buf[3],Uart_Num;
unsigned char Seg_Buf[9],Seg_Code[8],Seg_Pos;
unsigned int Seg_Dly,t;
unsigned char Key_Up,Key_Down,Key_Old,Key_Val,Key_Dly;
unsigned char Sys_Mod;
unsigned char ucDist,dist=30,ucLED,LED_Dly;
void Key_Proc(void);
void Seg_Proc(void);
void Sys_Proc(void);
void LED_Proc(void);
void main(void)
{
Close_Ws();
Timer0_Init();
Timer1_Init();
UartInit();
while(1)
{
Seg_Proc();
Key_Proc();
LED_Proc();
}
}
void Seg_Proc(void)
{
if(Seg_Dly) return;
Seg_Dly=1;
ucDist=Reas_Dist();
switch(Sys_Mod)
{
case 0:
sprintf(Seg_Buf,"U1 %3d",(unsigned int)ucDist);
Seg_Tran(Seg_Buf,Seg_Code);
break;
case 1:
sprintf(Seg_Buf,"U2 %3d",(unsigned int)dist);
Seg_Tran(Seg_Buf,Seg_Code);
break;
}
}
void LED_Proc(void)
{
if(LED_Dly) return;
LED_Dly=1;
LED_Disp(ucLED);
if(ucDist>dist) ucLED^=0x04;
else ucLED=ucLED&0xb0;
switch(Sys_Mod)
{
case 0:ucLED = ucLED&0xfc|0x01;break;
case 1:ucLED = ucLED&0xfc|0x02;break;
}
}
void Key_Proc(void)
{
if(Key_Dly) return;
Key_Dly=1;
Key_Val=Read_Key();
Key_Down=Key_Val&(Key_Old^Key_Val);
Key_Up=~Key_Val&(Key_Old^Key_Val);
Key_Old=Key_Val;
if(Key_Down==4)
if(++Sys_Mod==2) Sys_Mod=0;
if(Key_Down==9)
{
sprintf(ucStr,"Distance:%3dcm",(unsigned int)ucDist);
Send_UartStr(ucStr);
}
Sys_Proc();
}
void Sys_Proc(void)
{
if(Sys_Mod==0)
if(Key_Down==8) dist=ucDist;
if(Sys_Mod==1)
{
if(Key_Down==12) dist=dist+10;
if(Key_Down==16)
{
if(dist<10) dist=0;
else dist=dist-10;
}
}
}
void Timer1_Isr(void) interrupt 3
{
Seg_Disp(Seg_Code,Seg_Pos);
if(++Seg_Pos==8) Seg_Pos=0;
if(++Key_Dly==10) Key_Dly=0;
if(++Seg_Dly==500) Seg_Dly=0;
if(++LED_Dly==200) LED_Dly=0;
}
void Uart_Isr(void) interrupt 4
{
if(RI)
{
SBUF=Uart_Buf[Uart_Num++];
RI=0;
}
}
sonic.c
void Timer0_Init(void) //12微秒@12.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xF4; //设置定时初始值
TH0 = 0xFF; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 0; //定时器0开始计时
}
unsigned char Reas_Dist(void)
{
unsigned char dist,num=10;
TX=0;
TL0 = 0xF4;
TH0 = 0xFF;
TR0=1;
while(num--)
{
while(!TF0);
TX^=1;
TF0=0;
}
TR0=0;
TL0=0;
TH0=0;
TR0=1;
while(RX && (!TF0));
TR0=0;
if(TF0)
{
dist=255;
TF0=0;
}
else dist=((TH0<<8)+TL0)*0.017;
return dist;
}
题目
一、基本要求
使用大赛组委会提供的国信长天单片机竞赛实训平台,完成本试题的程序设计与调试。程序编写、调试完成后,选手需通过考试系统提交以准考证号命名的hex文件。不符合以上文件提交要求的作品将被评为零分或者被酌情扣分。
硬件设置:
将IAP15F2K61S2单片机内部振荡器频率设定为12MHz,串口波特率为9600bps。
键盘工作模式跳线J5配置为KBD矩阵按键模式。
扩展方式跳线J13配置为IO模式。
请注意:选手需严格按照以上要求配置竞赛板,编写和调试程序,不符合以上配置要求的作品将被评为零分或者被酌情扣分。
二、硬件框图
图1 系统硬件框图
三、功能描述
3.1 基本功能描述
1)通过超声波传感器采集距离数据,距离值保留整数。
2)通过数码管显示距离显示界面和参数显示界面,界面可以通过按键进行切换。
3)通过按键设置与调整距离参数。
4)通过串口向PC端发送当前距离数据。
5)通过LED指示灯进行报警功能。
3.2 数码管显示
1)距离显示界面
图2 距离显示界面(55cm)
2)参数显示界面
图3 参数显示界面(55cm)
3.3 按键功能
1)按键S4定义为“切换”按键,按下S4按键,能够切换“距离显示界面”、“参数显示界面”。
图4 按键S4‘切换’
2)按键S8定义为“参数”按键,在“距离显示界面”时,按下S8按键,可将当前距离数据设置为距离参数。
3)按键S12定义为“加”按键,在“参数显示界面”时,按下S12按键,当前距离参数加10cm。
图5 按键S12‘加’
4)按键S16定义为“减”按键,在“距离参数界面”时,按下S16按键,当前距离参数减10cm,参数值减到0为止。
图6 按键S16‘减’
5)按键S9定义为“发送”按键,每次按下,串口将当前检测的距离数据发送给PC端的串口调试工具。
注意:
(1)按键S12和按键S16仅在“距离参数界面”时有效
(2)按键S8仅在“距离显示界面”时有效,当按键S8按下后,参数显示界面参数值随之变化,但不会发生界面跳转。
(3)判断按键是否按下时,需进行消抖操作,避免单次按键操作,触发多次结果。
3.4 串口功能
串口发送格式
“Distance:55cm”
注意:
(1)D为大写字母,其余均为小写字母。
(2)距离数据保留整数。
3.5 LED指示灯功能
1)当前界面处于距离显示界面时,L1指示灯点亮,否则熄灭。
2)当前界面处于参数显示界面时,L2指示灯点亮,否则熄灭。
3)当实时距离超过距离参数时,L3指示灯以0.2s的时间间隔亮、灭,否则熄灭。
4)指示灯L4-L8处于常熄灭状态。
3.6 初始化
1)上电数码管处于距离显示界面。
2)距离参数值为30cm。