📄 text2.c
字号:
//********************************/
//头文件定义
//********************************/
#include<reg52.h>
#include<absacc.h>
#include<assert.h>
#include<ctype.h>
#include<math.h>
#include<stdio.h>
#include<string.h>
//*********************************/
//类型定义
//*********************************/
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
sbit P00=P0^0;
sbit P01=P0^1;
sbit P02=P0^2;
sbit P03=P0^3;
sbit P04=P0^4;
sbit P05=P0^5;
sbit P06=P0^6;
sbit P07=P0^7;
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
sbit P17=P1^7;
sbit P20=P2^0;
sbit P21=P2^1;
sbit P22=P2^2;
sbit P23=P2^3;
sbit P24=P2^4;
sbit P25=P2^5;
sbit P26=P2^6;
sbit P27=P2^7;
sbit P30=P3^0;
sbit P31=P3^1;
sbit P32=P3^2;
sbit P33=P3^3;
sbit P34=P3^4;
sbit P35=P3^5;
sbit P36=P3^6;
sbit P37=P3^7;
/**********************************/
//内存分配表
/**********************************/
#define CNT 150 //定义延时时间1ms*/
uchar idata Ntime=15;
uchar idata Stime=15;
uchar idata lamp=1; //南北通行位指示
// uchar idata lampE=0; //东西通行位指示
uchar idata flag=0; //定时器计数标志
bit setrkey=0; //设置红灯参数
bit setgkey=0; //设置绿灯参数
uchar idata key_buf[2]={0,0};//键盘缓冲区
uchar idata dis_buf[4]={16,15,15,14};
uchar code dis_tab[]=
{
0x3f,// 0
0x06,// 1
0x5b,// 2
0x4f,// 3
0x66,// 4
0x6d,// 5
0x7d,// 6
0x07,// 7
0x7f,// 8
0x6f,// 9
0x50,// 10
0x40,// r 11
0x00,//消隐 12
0x79,//E 13
0x3d,//G 14
0x5c,//o 15
0x5e,//d 16
0x37,//n 17
};
uchar keyscan(void); //键盘扫描
uchar keyana(void); //键处理
void delay_ms(uint x); //1ms延时,x延演时时间
void display(void); //显示函数
void setlamp(void); //设置显示参数
void dislamp(void);
main()
{
TMOD=0x01;
TH0=0x2c; //(65536-54254)/256;11.0592MHz晶振,定时 50ms
TL0=0x12; // (65536-54254)%256;
IE=0x9A;
IP=0x00;
TR0=1; //启动T0
ES=1;
ET0=1; //允许T0中断
EA=1; //允许中断
while(1)
{
P1=0x0;
keyana(); //先进行一次键盘扫描
if(setrkey||setgkey) //如果是设置键(红或绿)
setlamp(); //调用设置灯参数
dislamp();
}
}
void setlamp(void) //设置红绿灯参数
{
uint i,j;
key_buf[0]=0;
key_buf[1]=0;
dis_buf[3]=5; //显示s,设置
if(setrkey)
dis_buf[2]=13; //显示E,东西通行时间
else
dis_buf[2]=17;//显示N,南北通行时间
dis_buf[1]=11; //低两位显示--
dis_buf[0]=11;
for(i=0;i<CNT;i++) //延时
{
display();
delay_ms(1);
}
key_buf[1]=keyana(); //取键盘值
dis_buf[0]=key_buf[1];
dis_buf[1]=11;
for(i=0;i<CNT;i++) //延时
{
display();
delay_ms(2);
}
key_buf[0]=keyana(); //再取第二个值
dis_buf[1]=dis_buf[0];// 将第一个值往前推一位,空出个位显示刚输入的值
dis_buf[0]=key_buf[0];
for(i=0;i<CNT;i++)
{
display();
delay_ms(2);
}
for(i=0;i<2;i++) //以0.5s一次的频率闪烁2次以表示设置完成
{
for(j=0;j<50;j++)
display();
delay_ms(500);
}
if(setrkey) //如果是红灯
{
Ntime=key_buf[1]*10+key_buf[0]; //将参数存入红灯值
setrkey=0; //将设置标志清零
lamp=1; //红灯亮
}
else //是绿灯
{
Stime=key_buf[1]*10+key_buf[0];//存入绿灯值
setgkey=0; //将设置标志清零
lamp=0; //绿灯亮
}
}
uchar keyana(void) //键盘解释函数,将扫描来的键值解析出值并返回
{
uchar idata key;
key=keyscan();
switch(key)
{
case(0x78)://0
return 0;
break;
case(0x74): //1
return 1;
break;
case(0x72): //2
return 2;
break;
case(0x71): //3
return 3;
break;
case(0x38): //4
return 4;
break;
case(0x34): //5
return 5;
break;
case(0x32): //6
return 6;
break;
case(0x31): //7
return 7;
break;
case(0x01): //8
return 8;
break;
case(0xfd): //9
return 9;
break;
case(0xfb): //10
setrkey=1;
break;
case(0xfa): //11
setgkey=1;
break;
case(0x00):
default:
break;
}
}
void delay_ms(uint x)//延时xms函数
{
uchar j;
while (x--)
{
for(j=0;j<125;j++)
{;}
}
}
void dislamp(void)//红绿灯显示函数,用显示器模拟红绿灯,
//同时用P10模拟红灯,P11模拟绿灯
{
uchar idata time;
if(lamp)/*若是南北红灯*/
{time=Ntime;/*将所设值赋给临时计数变量time*/
while(1)
{display();
keyana();/*扫描一次键盘,如果是设置命令,则进行设置*/
if(setrkey||setgkey)
{setlamp();break;}/*设置完成后跳出本次循环,重新开始。*/
if(flag>=18)/*定时1秒后将计数值减1,并显示*/
{time--;
dis_buf[0]=time%10;
dis_buf[1]=time/10;/*低两位显示倒计时秒数*/
dis_buf[2]=11;/*-*/
dis_buf[3]=13;/*东西*/
flag=0;
display();/*程序中穿插显示刷新*/
P1=0x21;//*P1.0口接红灯,此时南北红灯亮禁止
if(time<=5)
{P1=0x32;}
if(!time)//*时间回零后使lamp变成0,下次亮绿灯*/
{
lamp=0; //
// lampS=1; //东西禁止位
break;
}
}
}
}
else
{time=Stime;/*将所设值赋给临时计数变量time*/
display();
while(1)
{display();
keyana();/*扫描一次键盘,如果是设置命令,则进行设置*/
if(setrkey||setgkey)
{setlamp();break;}/*设置完成后跳出本次循环,重新开始。*/
if(flag>=18)/*定时1秒后将计数值减1,并显示*/
{time--;
dis_buf[0]=time%10;
dis_buf[1]=time/10;/*低两位显示倒计时秒数*/
dis_buf[2]=11;/*-*/
dis_buf[3]=17;/*南北*/
flag=0;
display();/*程序中穿插显示刷新*/
P1=0x0c;//*P1.0口接红灯,此时南北红灯亮禁止
if(time<=5)
{P1=0x16;}
if(!time) //*时间回零后使lamp变成0,下次亮绿灯*/
{
lamp=1; //
// lampS=1; //东西禁止位
break;
}
}
}
}
}
uchar keyscan(void)//键盘扫描
//行:P3.7,P3.6,P3.3
//列:P2.7,P2.6,P2.5,P2.4
{uchar idata lin,row,temp;
P2=0xff;
P3=0x00;//发全0行扫描,P3口为0
if((P2&0xf0)!=0xf0)//若有键按下
{display();//用显示代替延时10mS
if((P2&0xf0)!=0xf0)//仍按下
{lin=0xf7;//第一行,P3.3为0
P3=lin;
P2=0xff;
if((P2&0xf0)!=0xf0)//在该行
{row=(P2&0xf0)|0x0f;
row>>=4;
temp=(~lin+~row+1);
return temp;
}
lin=0xbf;//第二行,P3.6为0*/
P3=lin;
P2=0xff;
if((P2&0xf0)!=0xf0)//在该行*/
{row=(P2&0xf0)|0x0f;
row>>=4;
temp=(~lin+~row);
return temp;
}
lin=0x7f;//第三行,P3.7为0*/
P3=lin;
P2=0xff;
if((P2&0xf0)!=0xf0)//在该行*/
{row=(P2&0xf0)|0x0f;
row>>=4;
temp=(~lin+~row);
return temp;
}
}
else return 0;
}
else return 0;
}
void display(void)//显示函数,如果只用此函数,
//别忘了把程序开头的显示缓冲区(dis_buf[])定义上
{uchar idata ledsel=0xf7;//左边第一个LED
uchar idata i;
for(i=0;i<5;i++)//循环为4即可,为了便于计算,多循环一次,
// 取整数约10ms,对显示无明显影响
{P2=ledsel;
P0=dis_tab[dis_buf[i]];
delay_ms(1);
ledsel>>=1;//右移一位,选中下一个数码管。移出位舍弃,空位补1。
delay_ms(1);
}
}
void time0() interrupt 1 using 1//定时器0中断
{
flag++;
TH0=0x2c;
TL0=0x12;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -