c语言实现定时显示字符,c语言编程实现以下功能:同时驱动8位数码管显示数字时钟,并能动态改变,每隔1s自......

#include

#include

#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换

#define uchar unsigned char

#define uint unsigned int

sbit buzz=P0^6;//蜂鸣器

sbit relay=P0^4;//继电器

//  0    1    2    3    4    5    6     7    8    9   -   消隐

unsigned char code DuanMa[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};        //共阳

unsigned char code WeiMa[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};//分别对应相应的数码管点亮,即位码

uchar disData[8]={11,11,11,11,11,11,0,0};

uchar times=0;

uchar hour,minute,second;

//函数声明

void delay_50us(uint t);

void display(uchar *point);

void SEG_Latch(void);  //段码锁存子程序

void BIT_Latch(void);  //位码锁存子程序

void ULN2003_Latch(void);

//P2.7~P2.5=111段码锁存

//P2.7~P2.5=110位码锁存

main()

{

buzz=0;//关蜂鸣器

relay=0;//关继电器

ULN2003_Latch();

TMOD |=0x01;//T0 16位定时器

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

ET0=1;

TR0=1;

EA=1;

while(1)

{

if(second == 60 )

{

second = 0;

minute++;

if(minute == 60)

{

minute=0;

hour++;

if(hour==24)

{

hour=0;

}

}

}

disData[6]=second/10;

disData[7]=second%10;

disData[5]=10;

disData[3]=minute/10;

disData[4]=minute%10;

disData[2]=10;

disData[0]=hour/10;

disData[1]=hour%10;

display(disData);

}

}

void ISR_Timer0(void) interrupt 1

{

TH0=(65536-50000)/256;

TL0=(65536-50000)%256;

times++;

if (times == 20)

{

second++;

times=0;

}

}

void delay_50us(uint t)   //50us 延时

{

uchar j;

for(;t>0;t--)

for(j=19;j>0;j--)

;

}

void SEG_Latch(void)   //段码锁存子程序

{

P2 &= 0x1f;//清P2.7~P2.5

P2 |= 0xe0;//P2.7~P2.5=111,Y7=0,Y7C=1,即U7的LE=1,段码数据选通

_nop_();

P2 &= 0x1f;//P2.7~P2.5=000,Y7=1,Y7C=0,即U7的LE=0,段码数据被锁存

}

void BIT_Latch(void)  //位码锁存子程序

{

P2 &= 0x1f;//清P2.7~P2.5

P2 |= 0xC0;          //P2.7~P2.5=110,Y6=0,Y6C=1,即U8的LE=1,位码数据选通

_nop_();

P2 &= 0x1f;          //P2.7~P2.5=000,Y6=1,Y6C=0,即U8的LE=0,位码数据被锁存

}

void display(uchar *point)

{

unsigned char i=0;

for(i=0;i<8;i++)

{

DataPort=WeiMa[i];   //取位码

BIT_Latch();                        //数据锁存

DataPort=DuanMa[*(point+i)]; //取显示数据,段码

SEG_Latch();                        //数据锁存

delay_50us(20);   // 扫描间隙延时,时间太长会闪烁,太短不亮

DataPort=0xff;   //关显示,消除重影

SEG_Latch();            //数据锁存

}

}

void ULN2003_Latch(void)   // ULN2003锁存子程序

{

P2 &= 0x1f;//清P2.7~P2.5

P2 |= 0xa0;//P2.7~P2.5=101,Y5=0,Y5C=1,即U9的LE=1,数据选通

_nop_();

P2 &= 0x1f;//P2.7~P2.5=000,Y5=1,Y5C=0,即U9的LE=0,数据被锁存

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个挺常见的嵌入式应用的设计,我可以为你提供一些关键的代码实现。 同样的,我们需要使用定时器来控制时钟的计时。在AT89C51的设计中,我们可以使用Timer0来进行定时。为了方便代码编写,我们可以使用定时器中断。在中断服务程序中,将秒和分钟进行累加,最终在四位数码管上进行显示。 以下是基本实现代码: ```c #include <reg51.h> #define FREQ_SYSCLK 11059200L #define FREQ_TIMER0 1000L #define DIGIT_0 P2_0 #define DIGIT_1 P2_1 #define DIGIT_2 P2_2 #define DIGIT_3 P2_3 unsigned char second = 0; unsigned char minute = 0; unsigned int timer_count = 0; void Timer0_ISR (void) interrupt 1 { // 计器加1 timer_count++; // 每1000ms计算一次秒和分钟 if (timer_count == FREQ_TIMER0) { timer_count = 0; // 秒加1 second++; // 如果秒达到60,分钟加1 if (second == 60) { second = 0; minute++; // 如果分钟达到60,分钟清零 if (minute == 60) { minute = 0; } } } } void main (void) { // 初始化定时器0 TMOD &= 0xF0; TMOD |= 0x01; TH0 = (65536 - FREQ_SYSCLK / FREQ_TIMER0) / 256; TL0 = (65536 - FREQ_SYSCLK / FREQ_TIMER0) % 256; TR0 = 1; ET0 = 1; EA = 1; // 主循环 while (1) { // 显示分钟的十位数码管 DIGIT_0 = 1; DIGIT_1 = 0; DIGIT_2 = 0; DIGIT_3 = 0; P1 = minute / 10; // 稍微延时,以避免过快切换数码管导致闪烁 for (int i = 0; i < 10000; i++); // 显示分钟的个位数码管 DIGIT_0 = 0; DIGIT_1 = 1; DIGIT_2 = 0; DIGIT_3 = 0; P1 = minute % 10; for (int i = 0; i < 10000; i++); // 显示秒的十位数码管 DIGIT_0 = 0; DIGIT_1 = 0; DIGIT_2 = 1; DIGIT_3 = 0; P1 = second / 10; for (int i = 0; i < 10000; i++); // 显示秒的个位数码管 DIGIT_0 = 0; DIGIT_1 = 0; DIGIT_2 = 0; DIGIT_3 = 1; P1 = second % 10; for (int i = 0; i < 10000; i++); } } ``` 在这个例子中,我们使用了P1口来控制四位数码管的显示,使用了P2口来控制四个数码管的开启。在主循环中,我们通过不断切换数码管的开启状态,实现了四位数码管动态显示。 需要注意的是,由于数码管的刷新速度非常快,因此我们需要对数码管进行适当的延时,以避免过快切换数码管导致闪烁。在这个例子中,我们使用了一个简单的循环延时来实现。在实际应用中,可能需要根据具体情况进行调整。 希望这个例子能够对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值