📄 shi.c
字号:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar qianwei,baiwei,shiwei,gewei; //显示数据各个位置数字的临时变量
char led_seg_code[10]={0x3f,0x06,0x05b,0x04f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //段码表示0-9
uint tt,aa,round,distance,cost,price,wait; //定义路程、价钱、等待时间及一些全局的变量等;
uchar dengdai,second,minute;
unsigned long wait_ten_ms; //记录等待时间多少个10ms
//按键的定义,所有按键按下去为低电平
sbit key0=P1^0; //清零
sbit key1=P1^1; //切换路程与等待时间
sbit key2=P1^2; //单程还是往返设置
sbit key3=P1^3; //暂停按钮
sbit led1=P1^4; // 双程
sbit led2=P1^5; // 暂停
sbit led3=P1^6; // 堵车
sbit led4=P1^7; // 切换
bit key1_flag; //由于按键会自动复位,这个为标志位
bit key2_flag;
bit key3_flag;
bit flag;
//初始化函数
void initial_data(void)
{
distance=0;
cost=0;
second=0;
minute=0;
wait_ten_ms=0;
key1_flag=1; //
key2_flag=0; //单程or往返,接指示灯;
key3_flag=1; //暂停,接指示灯;
flag=0;
round=0;
dengdai=0;
led1=1; //双程指示
led2=1; //暂停指示
led3=1; //堵车指示
led4=1; // 等待时间切换标志
}
//暂停程序
void zanting(void)
{
if(key3_flag)
{
EX0=0; //关闭中断和定时器
TR0=0;
}
else
{
EX0=1;
TR0=1;
}
key3_flag=!key3_flag;
}
//计算数据处理
void jisuan()
{
distance=round/57+wait_ten_ms/3000; //车轮转57圈为100m,等待时间30s为100m
if(distance<=30)
cost=50;
price=20; //单程价格
if(key2_flag) price=15; //往返价格
if(distance>30)
cost=price*(distance-30)/10+50;
wait=minute*100+second;
}
//显示的辅助程序,分离一个数的各个数字
void fenli(uint temp) //数据的分离处理
{
if(temp>9999) temp=9999;
qianwei=temp/1000;
baiwei=temp/100%10;
shiwei=temp%100/10;
gewei=temp%10;
}
//延时约1ms,数码管显示时使用
void diplay_delay(void)
{
uint i;
for(i=0;i<290;i++);
}
//显示程序;
void led_show()
{
//-----显示路程或者等待时间----
if(key1_flag) fenli(distance);
else fenli(wait);
P2=0xfe;
P0=led_seg_code[gewei];
diplay_delay();
P2=0xfd;
if(key1_flag) P0=led_seg_code[shiwei]|0x80; //如果是路程,点亮小数点儿
else P0=led_seg_code[shiwei]; //如果是时间,不需要点亮小数点儿
diplay_delay();
P2=0xfb;
if(key1_flag) P0=led_seg_code[baiwei];
else P0=led_seg_code[baiwei]|0x80;
diplay_delay();
P2=0xf7;
P0=led_seg_code[qianwei];
diplay_delay();
//-----显示价格----
fenli(cost);
P2=0xef;
P0=led_seg_code[gewei];
diplay_delay();
P2=0xdf;
P0=led_seg_code[shiwei]|0x80;
diplay_delay();
P2=0xbf;
P0=led_seg_code[baiwei];
diplay_delay();
P2=0x7f;
P0=led_seg_code[qianwei];
diplay_delay();
P2=0xff;
}
//延时时基为1ms
void delay(uint x)
{
int i,j;
for(i=x;i>0;i--)
for(j=340;j>0;j--);
}
//键盘的扫描
void keyscan()
{ if(key1==0) // 按键消抖并判断按下去的次数为基数还是偶数
{ delay(5);
if(key1==0)
key1_flag=!key1_flag;
while(!key1)led_show();
delay(5);
while(!key1)led_show();
}
if(key0==0) // 清零
{ delay(5);
if(key0==0)
initial_data();
}
if(key3==0) // 暂停
{ delay(5);
if(key3==0)
zanting();
while(!key3)led_show();
delay(5);
while(!key3)led_show();
}
if(key2==0) // 单程还是往返
{ delay(5);
if(key2==0)
key2_flag=!key2_flag;
while(!key2)led_show();
delay(5);
while(!key2)led_show();
}
//指示等扫描
led1=!key2_flag; // 指示,单程还是往返,灯低电平点亮; 往返亮;
led2=key3_flag; // 指示,暂停时亮;
led3=flag; // 指示是否等待;
led4=key1_flag; //切换指示,显示路程还是等待时间;
diplay_delay();
}
//中断及定时器初始化
void initial_time()
{
TMOD=0x01; //工作在模式1
TH0=(65536-10000)/256;
TL0=(65536-10000)%256;
IE=0x83;
IT0=1; //外部边沿触发方式
TR0=1;
}
// 中断记录脉冲数
void zd() interrupt 0 //中断0
{
aa++;
if(flag) round++;
}
//********* 定时器 ********
void time0() interrupt 1 //定时0
{
TH0=(65536-10000)/256; //10ms
TL0=(65536-10000)%256;
tt++;
if(tt>=100) //1s采样
{
tt=0;
if(aa<=5) flag=0;
else flag=1;
aa=0;
}
if(!flag)
{
wait_ten_ms++;
dengdai++;
if(dengdai==100)
{ dengdai=0;
second++;
if(second==60)
{
minute++;
second=0;
}
}
}
}
//主程序
void main(void)
{
initial_data(); //初始化数据
initial_time(); //初始化定时器
while(1)
{
keyscan();
jisuan();
led_show();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -