51单片机8位数码管时钟c语言,51单片机8位7段数码管时钟Proteus仿真程序

#include

#include"intrins.h"

#define uint unsigned int

#define uchar unsigned char

sbit fmq=P3^0; //蜂鸣器控制

char  table[]={        0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,  0xff,  0xc6,  0xc7,  0x88,};                //共阳极数码管编码 “0-9”

//                0    1   2     3   4     5    6   7    8   9     不显示   C       L      A

uchar val[8]={0,0,0,0,0,0,11,12};          //数码管显示缓冲区

uint count=0;   //

char shi=0,fen=0,miao=0;   //时分秒变量

char nzshi=0,nzfen=0,nzmiao=0;        //闹钟时分秒变量

uchar wei=0x01,duan=0;       // 控制数码管段 和位显示的变量

void led() //数码管扫描函数

{

P0=0Xff;

P2=wei;

if((duan==1)||(duan==3))  //这里是加小数点用的

{

P0=(table[val[duan]]&0x7f);

}

else

{

P0=table[val[duan]];

}

duan++;

if(duan>7)

duan=0;

wei=_crol_(wei,1);

}

void time0init()  //定时器0初始化

{

TMOD=0X01;

TH0=(65536-2000)/256;

TL0=(65536-2000)%256;

ET0=1;

TR0=1;

EA=1;

}

uchar keytime=0;  //按键

uint bjtime=0;  //报警计时变量

bit  sjbs=0;  //按键A 控制时间走停的变量

void time0() interrupt 1  // 定时器0中断服务函数

{

TH0=(65536-2000)/256;

TL0=(65536-2000)%256;

if(sjbs)

{

count++;

}

bjtime++;

keytime++;

led();                //2ms扫描一次数码管显示

}

uchar key()          //按键扫描程序

{

static  uchar kzt=0;

uchar sb=25;

switch(kzt)

{

case 0:

P1=0xff;

if(P1!=0xff)

{

kzt=1;

return 25;

}

break;

case 1:

P1=0xff;

if(P1!=0xff)

{

switch(P1)

{

case 0xfe:

sb=1;

break;

case 0xfd:

sb=2;

break;

case 0xfb:

sb=3;

break;

case 0xf7:

sb=4;

break;

case 0xef:

sb=5;

break;

case 0xdf:

sb=6;

break;

case 0xbf:

sb=7;

break;

case 0x7f:

sb=8;

break;

}

kzt=2;

return sb;

}

else

{

kzt=0;

return 25;

}

break;

case 2:

P1=0xff;

if(P1==0xff)

{

kzt=0;

return 25;

}

break;

}

return 25;

}

void sj()         //时分秒时间更新

{

if(count>499)

{

count=0;

miao++;

if(miao>59)

{

miao=0;

fen++;

if(fen>59)

{

fen=0;

shi++;

if(shi>23)

{

shi=0;

}

}

}

}

}

void  main()

{

uchar keycode=25,zt=1;

bit bjbs=0;

fmq=1;

time0init();         //初始化定时器0

while(1)

{

if(keytime>9) //20ms 扫描一次按键

{

keytime=0;

keycode=key();

}

if(((fen==0)&&(miao==0))||((shi==nzshi)&&(fen==nzfen)&&(miao==nzmiao)))

{ //  判断整点                判断是否到闹钟时间

bjbs=1;

fmq=0;

bjtime=0;

}

if(bjbs)   //报警处理

{

if(bjtime>30000)

{

fmq=1;

bjbs=0;

}

if((keycode>1)&&(keycode<5)) //只要在鸣叫时调节就停止鸣叫

{

bjbs=0;

fmq=1;

}

}

switch(zt)

{

case 1:   // 时钟显示

val[0]=shi/10;  //显示数据更新

val[1]=shi%10;

val[2]=fen/10;

val[3]=fen%10;

val[4]=miao/10;

val[5]=miao%10;

val[6]=11;

val[7]=12;

if(keycode==1)  //A   时间运行与暂停

{

sjbs=!sjbs;

keycode=25;

}

sj();

if(keycode==2)  //B 秒加1

{

miao++;

if(miao>59)

{

miao=0;

}

keycode=25;

}

if(keycode==3)//C分 加1

{

fen++;

if(fen>59)

{

fen=0;

}

keycode=25;

}

if(keycode==4)//D 时加1

{

shi++;

if(shi>23)

{

shi=0;

}

keycode=25;

}

if(keycode==5) //E 进入闹钟设置状态

{

zt=2;

keycode=25;

}

break;

case 2: //闹钟显示与调节

sj();        //时间更新

val[0]=nzshi/10; //显示数据更新

val[1]=nzshi%10;

val[2]=nzfen/10;

val[3]=nzfen%10;

val[4]=nzmiao/10;

val[5]=nzmiao%10;

val[6]=13;

val[7]=12;

if(keycode==2) //B 闹钟秒加1

{

nzmiao++;

if(nzmiao>59)

{

nzmiao=0;

}

keycode=25;

}

if(keycode==3) //C  闹钟分加1

{

nzfen++;

if(nzfen>59)

{

nzfen=0;

}

keycode=25;

}

if(keycode==4) //D 闹钟时加1

{

nzshi++;

if(nzshi>23)

{

nzshi=0;

}

keycode=25;

}

if(keycode==5) //E 进入时钟显示状态

{

zt=1;

keycode=25;

}

break;

}

}

}

好的,下面是一个简单的6位数码管电子时钟C语言程序,可以在51单片机上运行: ```c #include <reg51.h> // 导入51单片机头文件 #define uchar unsigned char // 定义无符号字符类型 sbit DIO=P1^0; // 定义数码管数据线 sbit CLK=P1^1; // 定义数码管时钟线 sbit LATCH=P1^2; // 定义数码管锁存线 uchar code NumTab[]={ // 数码管显示数字编码数组 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f }; uchar hour=0,min=0,sec=0; // 定义小时、分钟、秒钟变量 void delay_ms(unsigned int ms) // 延时函数,单位毫秒 { unsigned int i,j; for(i=0;i<ms;i++) for(j=0;j<110;j++); } void WriteData(uchar dat) // 向数码管写入数据 { uchar i; for(i=0;i<8;i++) { CLK=0; DIO=dat&0x01; dat>>=1; CLK=1; } } void Display(uchar *p) // 在数码管上显示时间 { uchar i; LATCH=0; for(i=0;i<6;i++) { WriteData(NumTab[*(p+i)]); } LATCH=1; } void InitTimer() // 初始化定时器 { TMOD=0x01; // 定时器1,工作模式1 TH0=0x4c; // 初始值,每50ms中断一次 TL0=0x00; TR0=1; // 启动定时器 ET0=1; // 允许定时器1中断 EA=1; // 允许总中断 } void Timer0() interrupt 1 // 定时器1中断处理函数 { TH0=0x4c; // 重新赋初值 TL0=0x00; sec++; // 秒加1 if(sec==60) // 如果秒钟达到60 { sec=0; min++; // 分钟加1 if(min==60) // 如果分钟达到60 { min=0; hour++; // 小时加1 if(hour==24) // 如果小时达到24 { hour=0; // 回到0点 } } } } void main() // 程序入口 { InitTimer(); // 初始化定时器 while(1) // 无限循环 { uchar time[6]={hour/10,hour%10, // 将时间转换成数码管显示的数字 min/10,min%10, sec/10,sec%10}; Display(time); // 在数码管上显示时间 delay_ms(5); // 延时5ms } } ``` 这个程序使用了定时器中断来实现时间的计时和更新,在每秒钟定时器中断处理函数中将秒、分、时加1,然后将时间转换成数码管显示的数字,最后在数码管上显示。程序中使用了一个延时函数来控制数码管的刷新频率,可以根据需要调整该延时时间。 关于仿真,您可以使用Proteus仿真软件进行仿真。在仿真中,您需要添加51单片机、6位数码管等元件,并将单片机程序烧录到单片机中。然后运行仿真,观察数码管上的时间变化是否与预期一致。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值