个人感觉比往届的试题都难一点,且两套都涉及了串口,这里先传第一套
#include <STC15F2K60S2.H>
#include <intrins.h>
#include <stdio.h>
code unsigned char number[28] =
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
0xbf,0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10, // - 0.
0xc1
};//+17后为带.字 48 65 97
unsigned char uc_mod1,uc_value_distence = 30,uc_led = 0xff,uc_10ms;
unsigned int ui_distence;
sbit TX = P1^0;
sbit RX = P1^1;
bit b_200ms;
bit flag_10ms;
void smg_led();
void Timer2Init(void) //10毫秒@12.000MHz
{
AUXR &= 0xFB; //定时器时钟12T模式
T2L = 0xF0; //设置定时初值
T2H = 0xD8; //设置定时初值
AUXR |= 0x10; //定时器2开始计时
EA = 1;
IE2 = IE2 | 0x04; //用于计时,开关没有按位寻址,所以需要自己翻手册开启
}
void timer2() interrupt 12
{
uc_10ms++; //计时中断
if(uc_10ms == 20)
{
b_200ms = ~b_200ms;
uc_10ms = 0;
}
}
void Timer0Init(void) //超声波测距用
{
AUXR &= 0x7F;
TMOD &= 0xF0;
TL0 = 0x00;
TH0 = 0x00;
TF0 = 0;
TR0 = 0;
}
void UartInit(void) //9600bps@12.000MHz
{
SCON = 0x50; //8位数据,可变波特率
AUXR &= 0xBF; //定时器1时钟为Fosc/12,即12T
AUXR &= 0xFE; //串口1选择定时器1为波特率发生器
TMOD &= 0x0F; //设定定时器1为16位自动重装方式
TL1 = 0xE6; //设定定时初值
TH1 = 0xFF; //设定定时初值
ET1 = 0; //禁止定时器1中断
TR1 = 1; //启动定时器1
TI = 1; //注意,这里因为只要求了uart送,所以用这种写法
} //否则是需要开中断的
void Delay30ms() //@12.000MHz
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 2;
j = 95;
k = 43;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void Delay600us() //@12.000MHz
{
unsigned char i, j;
i = 7;
j = 254;
do
{
while (--j);
} while (--i);
}
void Delay14us() //@12.000MHz
{
unsigned char i;
_nop_();
_nop_();
i = 39;
while (--i);
}
void send_wave() //发送超声波
{
unsigned char i;
for(i = 1;i<=8;i++)
{
TX = 1;
Delay14us();
TX = 0;
Delay14us();
}
}
void HC138_choose(unsigned char l)
{
switch(l)
{
case 0:
{
P2 = (P2 & 0x1f) | 0x00;
break;
}
case 4:
{
P2 = (P2 & 0x1f) | 0x80;
break;
}
case 5:
{
P2 = (P2 & 0x1f) | 0xa0;
break;
}
case 6:
{
P2 = (P2 & 0x1f) | 0xc0;
break;
}
case 7:
{
P2 = (P2 & 0x1f) | 0xe0;
break;
}
}
}
void celiang()
{
unsigned int ui_time;
RX = 1;
TF0 = 0;
TL0 = 0x00;
TH0 = 0x00;
send_wave();
TR0 = 1;
while(TF0 == 0 && RX == 1)
{
if(ui_distence == 255)
{
smg_led();
}
}
TR0 = 0;
if(RX == 0 && TF0 == 0)
{
ui_time = (TH0 << 8) | TL0;
ui_distence = ui_time * 0.017;
}
else
{
ui_distence = 255; //超出设置为最大值
}
smg_led();
smg_led();
smg_led();
}
void smg_show(unsigned char wei,duan)
{
HC138_choose(6);
P0 = 0x01 << (wei - 1);
HC138_choose(7);
P0 = number[duan];
Delay600us();
P0 = 0xff;
}
void smg_led()
{
switch(uc_mod1)
{
case 0:
{
smg_show(6,ui_distence / 100);
smg_show(7,ui_distence / 10 % 10);
smg_show(8,ui_distence % 10);
smg_show(1,27);
smg_show(2,1);
HC138_choose(4);
P0 = uc_led;
P01 = 1;
P00 = 0;
uc_led = P0;
break;
}
case 1:
{
smg_show(6,uc_value_distence / 100);
smg_show(7,uc_value_distence / 10 % 10);
smg_show(8,uc_value_distence % 10);
smg_show(1,27);
smg_show(2,2);
HC138_choose(4);
P0 = uc_led; //led点灯
P00 = 1;
P01 = 0;
uc_led = P0; //记录LED状态
break;
}
}
if(ui_distence > uc_value_distence) //超出距离LED闪烁
{
if(flag_10ms == 0)
{
uc_10ms = 0;
flag_10ms = 1;
}
HC138_choose(4);
P0 = uc_led;
P02 = b_200ms;
uc_led = P0;
}
else //未超,关灯
{
flag_10ms = 0;
HC138_choose(4);
P0 = uc_led;
P02 = 1;
uc_led = P0;
}
}
void init()
{
HC138_choose(7);
P0 = 0xff;
HC138_choose(6);
P0 = 0x00;
HC138_choose(4);
P0 = 0xff;
HC138_choose(5);
P0 = 0x00;
}
void scan_key()
{
P44 = 1;
P33 = 0;
P30 = 1; //关闭相关干扰项
P31 = 1;
P32 = 1;
if(P44 == 0)
{
while(P44 == 0)
{
celiang();
smg_led();
}
Delay30ms();
uc_mod1++;
uc_mod1 %= 2;
}
P33 = 0;
P30 = 1;
P31 = 1; //关闭相关干扰项
P32 = 1;
P44 = 1;
P35 = 1;
P34 = 1;
P42 = 1;
if(uc_mod1 == 0)
{
if(P42 == 0)
{
while(P42 == 0)
{
celiang();
smg_led();
}
Delay30ms();
if(ui_distence != 255)
{
uc_value_distence = ui_distence;
}
}
}
else if(uc_mod1 == 1)
{
if(P35 == 0)
{
while(P35 == 0)
{
celiang();
smg_led();
}
Delay30ms();
uc_value_distence += 10;
}
if(P34 == 0)
{
while(P34 == 0)
{
celiang();
smg_led();
}
Delay30ms();
uc_value_distence -= 10;
}
}
P32 = 1;
P34 = 0;
P35 = 0; //关闭相关干扰项
P44 = 0;
P42 = 0;
if(P32 == 0)
{
while(P32 == 0)
{
celiang();
smg_led();
}
printf("Distance:%dcm\n",ui_distence); //利用了stdio.h的printf 具体用法可以站内搜索看看
Delay30ms();
}
}
void main()
{
init();
Timer0Init();
UartInit();
Timer2Init();
while(1)
{
scan_key();
celiang();
smg_led();
}
}
以上,感谢阅读,如有错误恳请指正,我会及时修改。