还有几小时比赛了,做个模拟练练手感
先看原题
#include "reg51.h"
#include "absacc.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit TX = P1^0;
sbit RX = P1^1;
//矩阵按键配置
sbit R1=P3^0;//第一排初始化(如果跳线帽模式是BTN,则只有最左侧一列能用)
sbit R2=P3^1;//第二排初始化
sbit R3=P3^2;//第三排初始化
sbit R4=P3^3;//第四排初始化
sbit C1=P4^4;//第一列初始化
sbit C2=P4^2;//第二列初始化
sbit C3=P3^5;//第三列初始化
sbit C4=P3^4;//第四列初始化
sbit Buzz=P0^6;//蜂鸣器
unsigned int distance = 0;
uchar mode;
uchar mode_k;
uint high=50;
uint low=0;
uchar count_b;
uchar mode_led;
0 1 2 3 4 5 6 7 8 9 - 全灭 .
unsigned char code shuzi[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90,0xbf,0xff,0x7f};
/// A b C d E F H L P U n
unsigned char code zimu[]={0x88,0x83,0xc6,0xa1,0x86,0x8e,0x89,0xc7,0x8c,0xc1,0xc8};
0 1 2 3 4 5 6 7
unsigned char code weizhi[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00};
// 1 2 3 4 5 6 7 8 灭
unsigned char ledweizhi[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};
void delay_ms(int ms)
{
int q,w;
for(q=0;q<ms;q++)
{
for(w=845;w>0;w--);
}
}
void shumaguan_shuzi(uchar a,uchar b)
{
delay_ms(1);
P2=(P2&0X1f)|0xC0;P0=weizhi[a];
P2=(P2&0X1f)|0xE0;P0=shuzi[b];
delay_ms(1);
//消隐
P2 = (P2 & 0x1f) | 0xc0;
P0 = 0x00;
P2 = P2 & 0x1f;
}
//数码管字母显示
void shumaguan_zimu(uchar a,uchar b)
{
delay_ms(1);
P2=(P2&0X1f)|0xC0;P0=weizhi[a];
P2=(P2&0X1f)|0xE0;P0=zimu[b];
delay_ms(1);
//消隐
P2 = (P2 & 0x1f) | 0xc0;
P0 = 0x00;
P2 = P2 & 0x1f;
}
void ledlight(uchar x)
{
P2=(P2&0X1f)|0x80;
P0=ledweizhi[x];
}
void Init_Keys()
{
R1=R2=R3=R4=1;
C1=C2=C3=C4=1;
}
void Init_timer0()//定时器配置
{
TMOD = 0x01;
TH0 = (65535 - 50000) / 256; //50ms技术
TL0 = (65535 - 50000) % 256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void Service_timer0() interrupt 1//定时器0,中断
{
count_b++;//全局变量
if(count_b==4)//计算了1s
{
count_b=0;
if(mode_led==0)//mode_smg也是全局变量
{
mode_led=1;
}
else if(mode_led==1)
{
mode_led=0;
}
}
}
void L3_blink()//显示小时以1s的间隔显示一次
{
if(mode_led==1)
{
ledlight(2);
}
if(mode_led==0)
{
ledlight(8);
}
}
void display_d()
{
if(distance == 999)
{
shumaguan_zimu(0,5); //超出测量范围标志:F
}
else
{
shumaguan_shuzi(5, distance / 100);
shumaguan_shuzi(5,12);
shumaguan_shuzi(6, (distance % 100) / 10);
shumaguan_shuzi(7, distance % 10);
}
P2=0x80;
P0=0x00;
}
void Delay12us() //@12.000MHz 延时12us
{
unsigned char i;
_nop_();
_nop_();
i = 33;
while (--i);
}
void Send_Wave() //产生8个40KHx超声波信号
{
unsigned char i;
for(i = 0; i < 8; i++)
{
TX = 1;
Delay12us();
TX = 0;
Delay12us();
}
}
void Measure_Distance() //超声波测距
{
unsigned int time = 0;
TMOD &= 0x0f; //定时器1模式0,13位,最大8192个计数脉冲
TL1 = 0x00;
TH1 = 0x00;
Send_Wave(); //发送超声波信号
TR1 = 1; //启动定时器
while((RX == 1) && (TF1 == 0)); //等待超声波信号返回或者等到测量超出范围
TR1 = 0; //停止定时器
if(TF1 == 0) //正常测量范围
{
time = TH1;
time = (time << 8) | TL1;
distance = ((time / 10) * 17) / 100 + 3;
}
else //超出测量范围
{
TF1 = 0;
distance = 999;
}
}
void display_h()
{
mode_k=0;
shumaguan_zimu(0,9);
shumaguan_shuzi(6,high/10);
shumaguan_shuzi(7,high%10);
ledlight(0);
}
void display_l()
{
mode_k=1;
shumaguan_zimu(0,10);
shumaguan_shuzi(6,low/10);
shumaguan_shuzi(7,low%10);
ledlight(1);
}
void select_mode()
{
switch(mode)
{
case(0):display_d();break;
case(1):display_h();break;
case(2):display_l();break;
}
}
void alarm()
{
if(distance<=low||distance>=high)
{
P2 = ((P2 & 0x1F) | 0xA0);
Buzz=1;
L3_blink();
}
else
{
P2 = ((P2 & 0x1F) | 0xA0);
Buzz=0;
}
}
void Scan_S4()
{
R1=1;R2=1;R3=1;R4=0;
C2=1;C3=1;C4=1;
if(C1==0)
{
while(C1==0);
mode++;
if(mode==3) mode=0;
}
}
void Scan_S8()
{
R1=1;R2=1;R3=1;R4=0;
C3=1;C4=1;C1=1;
if(C2==0)
{
while(C2==0);
if(mode_k==0)
{
high=high+10;
}
if(mode_k==1)
{
low=low+10;
}
}
}
void Scan_S12()
{
R1=1;R2=1;R3=1;R4=0;
C4=1;C1=1;C2=1;
if(C3==0)
{
while(C3==0);
if(mode_k==0)
{
high=high-10;
}
if(mode_k==1)
{
low=low-10;
}
}
}
void main()
{
Init_Keys();
Init_timer0();
while(1)
{
Measure_Distance();
select_mode();
Scan_S12();
Scan_S8();
Scan_S4();
alarm();
}
}