您的当前位置:首页正文

51单片机C语言可调时钟

2023-08-02 来源:钮旅网
程序介绍:六位共阳数码管显示,时·分·秒均可用按键调节。短按时选位的时间按一次加一下,长按不放时时间按一定的频率增加! 本程序的是我参考别人的基础上移植、再加上自己的想法做出来的,程序的亮点就是完全用单片机定时中断写的,避免了用延时写程序时,调节时间时其它未选择的位的的闪烁,使用中断使CPU得到释放,另外还可以具有长安连续增加的功能! 程序的不足之处:不能实现这样的功能,既::系统有四个按键,功能分别是 调整,加,减,确定。在按下调整键时候,显示时的两位数码管以1 Hz 频率闪烁。如果再次按下调整键,则分开始闪烁,时恢复正常显示,依次循环,直到按下确定键,恢复正常的显示。在数码管闪烁的时候,按下加或者减键可以调整相应的显示内容; 如果有哪位高数路过看到,请不吝赐教****************

过客与10年10月12日 #include

#define uint unsigned int #define uchar unsigned char bit dao1S=0; //到1秒标志位

bit dao2MS=0;// 到2毫秒标志位 bit dao10MS;// 到10毫秒标志位 sbit dula=P2^6;// 定义段选 sbit wela=P2^7;//定义位选

#define LED P0 //定义数据口 sbit key1=P3^4; //定义按键 sbit key2=P3^5; sbit key3=P3^6; sbit key4=P3^7;

#define KEY_1 0x0e //定义各按键键值 #define KEY_2 0x0d #define KEY_3 0x0b #define KEY_4 0x07 #define KEY_NULL 0x0f

#define KEY_PRESS 0x80 //定义各按键状态 #define KEY_LONG 0x40

#define KEY_STATE_INIT 0 //定义按键状态 #define KEY_STATE_PRESS 1 #define KEY_STATE_LONG 2 #define KEY_STATE_UP 3

#define KEY_LONG_PERIOD 50 //定义长按键的TICK数,以及连发间隔的TICK数

#define KEY_CONTINUE_PERIOD 25

uchar tab[]={0,0,0,0,0,0};//时间缓冲区

uchar weitable[]={0x01,0x02,0x04,0x08,0x10,0x20};//显示位

uchar tab1[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳极数码管编码0-9 void nint() //中断初始化 { TMOD=0X01; TH0=0XF8; TL0=0XCC; TR0=1; ET0=1; }

uchar KeyScan() //按键扫描函数 {

if(key1==0) return KEY_1; if(key2==0) return KEY_2; if(key3==0) return KEY_3; if(key4==0) return KEY_4; return KEY_NULL; }

uchar GetKey() {

uchar keyRetu=0,keyTemp=KEY_NULL; //返回的按键值,按键情况

static uchar s_keyState=KEY_STATE_INIT,keyTime=0,keyLast=KEY_NULL; //按键状态,按键按下的时间计数器,上次按键值

keyTemp=KeyScan(); switch (s_keyState) {

case KEY_STATE_INIT:

if(keyTemp!=KEY_NULL) //检测到有按键,转到状态1,相当于是消抖过程 {

s_keyState=KEY_STATE_PRESS; }

break;

case KEY_STATE_PRESS:

if(keyTemp!=KEY_NULL) //再次检测到有按键,转到状态2 {

s_keyState=KEY_STATE_LONG; keyTime=0; //清零按键时间计数器

keyLast=keyTemp; //保存键值,以便在释放按键状态返回键值 } else {

s_keyState=KEY_STATE_INIT; //没有检测到按键,说明初始状态检测到是一个抖动,重新转到状态0 }

break;

case KEY_STATE_LONG:

if(keyTemp==KEY_NULL) //检测到按键松开 {

s_keyState=KEY_STATE_INIT; //状态转到初始状态

keyRetu=(keyLast|KEY_PRESS); //输出\"单击\"的按键值 } else {

if(++keyTime>=KEY_LONG_PERIOD) //按下时间>1s {

s_keyState=KEY_STATE_UP; //转到松开状态 keyTime=0; //清零按键时间计数器 } }

break;

case KEY_STATE_UP:

if(keyTemp==KEY_NULL) //检测到按键松开 {

s_keyState=KEY_STATE_INIT; //状态转到初始状态 } else {

if(++keyTime>=KEY_CONTINUE_PERIOD) //按下时间>0.5s {

keyTime=0; //清零按键时间计数器

keyRetu=(keyLast|KEY_LONG); // 输出\"连击\"的按键值 } }

break; }

return keyRetu; }

void updatetime() //更新时间 {

if(dao1S) {dao1S=0;

if(++tab[5]==10) { tab[5]=0; if(++tab[4]==6) {tab[4]=0;

if(++tab[3]==10) { tab[3]=0; if(++tab[2]==6) { tab[2]=0; if(tab[0]<2) { if(++tab[1]==10) { tab[1]=0; tab[0]++; } } else { if(tab[1]==4) { tab[1]=0; tab[0]=0; } } } } } } } } void display()//时间显示 { static uchar k=0;

dula=1;//送段的数据 LED=tab1[tab[k]]; dula=0;

LED=0Xff;

wela=1;//送位的数据 LED=weitable[k]; wela=0;

if(++k>5) k=0; }

void sittime(uchar hour,uchar minute,uchar second )//赋除值 { uchar a1,a2,b1,b2,c1,c2; a1=hour/10; a2=hour%10;

b1=minute/10; b2=minute%10; c1=second/10; c2=second%10; tab[0]=a1; tab[1]=a2; tab[2]=b1; tab[3]=b2; tab[4]=c1; tab[5]=c2; } void main()//主函数 { nint(); EA=1;

sittime(15,20,15); while(1) {

updatetime(); if(dao2MS) {dao2MS=0; display(); } if(dao10MS) //每10ms扫描一次按键 {

dao10MS=0; switch (GetKey()) {

case (KEY_1|KEY_PRESS): if(tab[0]<2)

{ if (++tab[1]==10) { tab[1]=0; tab[0]++; } } else {if(++tab[1]==4) { tab[1]=0; tab[0]=0; } }

break;

case (KEY_1|KEY_LONG): if(tab[0]<2)

{ if (++tab[1]==10) { tab[1]=0; tab[0]++; } } else {if(++tab[1]==4) { tab[1]=0; tab[0]=0; } } break; case (KEY_2|KEY_PRESS): if(++tab[3]==10) { tab[3]=0; tab[2]++; if(tab[2]==6) { tab[2]=0; tab[3]=0; } } break;

case (KEY_2|KEY_LONG): if(++tab[3]==10) { tab[3]=0; tab[2]++; if(tab[2]==6) { tab[2]=0; tab[3]=0; } } break;

case (KEY_3|KEY_PRESS): if(++tab[5]==10) { tab[5]=0; tab[4]++; if(tab[4]==6) { tab[4]=0; tab[5]=0; } } break;

case (KEY_3|KEY_LONG): if(++tab[5]==10) { tab[5]=0; tab[4]++; if(tab[4]==6) { tab[4]=0; tab[5]=0; } } } } } }

void timer() interrupt 1 { static count=0; static count1=0;

TH0=0XF8; TL0=0XCC; dao2MS=1; count++;

if(++count1==10)

{ count1=0; dao10MS=1; }

if(count==500) //产生1S的时标 {

count=0; dao1S=1; } }

因篇幅问题不能全部显示,请点此查看更多更全内容