谁能给我一个四位8段数码管时钟电路图,并附带C语言程序。

谁能给我一个四位8段数码管时钟电路图,并附带C语言程序。,第1张

前段时间用pcf8563芯片做了个电子时钟,这个芯片自动走时间,我只用去读和写就行了,pcf8563要加一个后备电池,这样就不怕单片机掉电了。这个不太符合你的要求,不过这是我现成的,我可不想在这里重新写代码。代码不是很规范,但是能正常运行。

你在Keil里建个工程,下面一段是display.c的代码:

#include "at89x51.h"

#include "PCF8563.h"

//#include "TG12232.h"

#define Key_Set P2_2

#define Key_Add P2_1

#define Key_Sub P2_0

//#define LCD_CS P2_5

//#define LCD_DATA P2_6

//#define LCD_CLK P2_7

void Key_down()

void Displaybuffer(char Location)

//void LCD_Display()

unsigned char LedTable[10]={0x3f,0x03,0x6d,0x67,0x53,0x76,0x7e,0x23,0x7f,0x77}

bit state=0

char set=0

void main()

{

unsigned char i,j,n=2

P1=0

TMOD=0x01

TH0=0x4c

TL0=0x00

ET0=1

EA=1

// P8563_init()

P2=0xff

P3=0x02

P1=LedTable[8]

// while(n--)

for(i=0i<250i++)

 for(j=0j<6j++)

 {

  delay(10)

  P3<<=1

  if(P3==0x80)

  P3=0x02

  delay(10)

 }

delay(5000)

// lcd_init()

// set_lcd_position(0,1)    //汉字定位到上行左端

// lcd_display(0,0,"Welcome to use!")

// lcd_display(1,0,"  Leo.Zheng  ")

// delay(1000)

// lcd_send_com(0x01)//清除

// lcd_display(0,0,"20  /  /")

while(1)

{

Key_down()

Displaybuffer(set)

// LCD_Display()

}

}

void Time0_H() interrupt 1

{

static unsigned char i=0

TH0=0x4c

TL0=0x00

i++

if(i==8)

i=0

state=~state

}

}

/*

void LCD_Display()

{

lcd_display_char(0,2,((g8563_Store[6]&0xf0)>>4)+0x30)//年

lcd_display_char(0,3,(g8563_Store[6]&0x0f)+0x30)//

}*/

void Key_down()

{

// static char set=0

unsigned char buffer

if(!Key_Set)

for(buffer=0buffer<250buffer++)

 _nop_()

if(!Key_Set)

{

if(set==0)

{

 writeData(0x0,0x20)//使时间停止

 TR0=1

}

set++

if(set==4)

{

 set=0

 TR0=0

 writeData(0x0,0x00)

}

while(!Key_Set)

 Displaybuffer(set)

}

if(!Key_Add)

for(buffer=0buffer<250buffer++)

 _nop_()

if(!Key_Add)

{

if(set==0)

 return

P8563_gettime()

buffer= g8563_Store[set-1]

buffer=((buffer&0xf0)>>4)*10+(buffer&0x0f)

if(buffer>=59)

 buffer=0

else if(buffer>=23 && set==3)

 buffer=0

else

 buffer++

buffer=(buffer/10<<4)+(buffer%10)

writeData(set+1,buffer)

while(!Key_Add)

 Displaybuffer(set)

}

if(!Key_Sub)

for(buffer=0buffer<250buffer++)

 _nop_()

if(!Key_Sub)

{

if(set==0)

 return

P8563_gettime()

buffer= g8563_Store[set-1]

buffer=((buffer&0xf0)>>4)*10+(buffer&0x0f)

if(buffer == 0)

{

 if(set==3)

  buffer=23

 else

  buffer=59

}

else

 buffer--

buffer=(buffer/10<<4)+(buffer%10)

writeData(set+1,buffer)

while(!Key_Sub)

 Displaybuffer(set)

}

}

void Displaybuffer(char Location)

{

unsigned char i

P8563_gettime()

/*****************************************/   

if(Location==1 && state==0)

{

P1=0

P3=0

goto sec_bit1

}

P3=0x02

P1=LedTable[g8563_Store[0]&0x0f] //sec

sec_bit1:

for(i=0i<250i++)

P1=0

if(Location==1 && state==0)

{

P1=0

P3=0

goto sec_bit2

}

P3=0x04

P1=LedTable[(g8563_Store[0]&0xf0)>>4]

sec_bit2:

for(i=0i<250i++)

P1=0

/*****************************************/

if(Location==2 && state==0)

{

P1=0

P3=0

goto min_bit1

}

P3=0x08

P1=LedTable[g8563_Store[1]&0x0f]  //min

min_bit1:

for(i=0i<250i++)

P1=0

if(Location==2 && state==0)

{

P1=0

P3=0

goto min_bit2

}

P3=0x10

P1=LedTable[(g8563_Store[1]&0xf0)>>4]

min_bit2:

for(i=0i<250i++)

P1=0

/*****************************************/

if(Location==3 && state==0)

{

P1=0

P3=0

goto hour_bit1

}

P3=0x20

P1=LedTable[g8563_Store[2]&0x0f]    //hour

hour_bit1:

for(i=0i<250i++)

P1=0

if(Location==3 && state==0)

{

P1=0

P3=0

goto hour_bit2

}

P3=0x40

P1=LedTable[(g8563_Store[2]&0xf0)>>4]

hour_bit2:

for(i=0i<250i++)

P1=0

P3=0x02

/*****************************************/

}

这下面一段是pcf8563.h的代码:

#ifndef __PFC8563_H__

#define __PFC8563_H__

#include <intrins.h>

#define uchar unsigned char

sbit SDA=P2^4

sbit SCL=P2^3

//extern void          _nop_     (void)

//extern void delay(unsigned int ms)

uchar g8563_Store[7] /*时间交换区,全局变量声明*/

uchar code c8563_Store[7]={0x01,0x02,0x07,0x09,0x04,0x02,0x12} /*写入时间初值:秒,分,时,日,周,月,年(BCD码)

07:59:00*/

void delay(long time)

{while(time--)

}

/********************************************

内部函数,延时1

********************************************/

void DD()

{

//delay(1)

// uchar i

//    for(i=0i<250i++)

_nop_()

  _nop_() /*根据晶振频率制定延时时间*/

}

/********************************************

内部函数,I2C开始

********************************************/

void Start()

{  EA=0

 SDA=1

 SCL=1

 DD()

 SDA=0

 DD()

 SCL=0

}

/********************************************

内部函数,I2C结束

********************************************/

void Stop()

{

 SDA=0

 SCL=0

 DD()

 SCL=1

 DD()

 SDA=1

 DD()

 EA=1

}

/********************************************

内部函数,输出ACK ,每个字节传输完成,输出ack=0,结束读数据,ack=1

********************************************/

void WriteACK(uchar ack)

{

 SDA=ack

 DD()

 SCL=1

 DD()

 SCL=0

}

/********************************************

内部函数,等待ACK

********************************************/

void WaitACK()

{  uchar errtime=20

 SDA=1

 DD() /*读ACK*/

 SCL=1

 DD()

 while(SDA)

 {  errtime--

    if(!errtime)

    {

Stop()

SDA=0  //自己加的******

    }

 }

 SDA=1 //自己加的******

 SCL=0

 DD()

}

/********************************************

内部函数.输出数据字节

入口:B=数据

********************************************/

void writebyte(uchar wdata)

{

 uchar i

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

 {

     if(wdata&0x80) SDA=1

     else SDA=0

     wdata<<=1

     SCL=1

     DD()

     SCL=0

 }

 WaitACK()     //I2C器件或通讯出错,将会退出I2C通讯

}

/********************************************

内部函数.输入数据

出口:B

********************************************/

uchar Readbyte()

{

 uchar i,bytedata

 SDA=1

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

 {

    SCL=1

    bytedata<<=1

    bytedata|=SDA

    SCL=0

    DD()

 }

 return(bytedata)

}

/********************************************

输出数据->pcf8563

********************************************/

void writeData(uchar address,uchar mdata)

{

 Start()

 writebyte(0xa2) /*写命令*/

 writebyte(address) /*写地址*/

 writebyte(mdata) /*写数据*/

 Stop()

}

/********************************************

输入数据<-pcf8563

********************************************/

uchar ReadData(uchar address) /*单字节*/

{  uchar rdata

 Start()

 writebyte(0xa2) /*写命令*/

 writebyte(address) /*写地址*/

 Start()

 writebyte(0xa3) /*读命令*/

 rdata=Readbyte()

 WriteACK(1)

 Stop()

 return(rdata)

}

void ReadData1(uchar address,uchar count,uchar * buff) /*多字节*/

{  uchar i

 Start()

 writebyte(0xa2) /*写命令*/

 writebyte(address) /*写地址*/

 Start()

 writebyte(0xa3) /*读命令*/

 for(i=0i<counti++)

 {

 buff[i]=Readbyte()

 if(i<count-1) WriteACK(0)

 }

WriteACK(1)

 Stop()

}

/********************************************

内部函数,读入时间到内部缓冲区

********************************************/

void P8563_Read()

{   uchar time[7]

  ReadData1(0x02,0x07,time)

  g8563_Store[0]=time[0]&0x7f /*秒*/

  g8563_Store[1]=time[1]&0x7f /*分*/

  g8563_Store[2]=time[2]&0x3f /*小时*/

  g8563_Store[3]=time[4]&0x07 /*星期*/

g8563_Store[4]=time[3]&0x3f /*日*/

g8563_Store[5]=time[5]&0x1f /*月*/

g8563_Store[6]=time[6] /*年*/

}

/********************************************

读入时间到内部缓冲区----外部调用

********************************************/

void P8563_gettime()

{

  P8563_Read()

  if(g8563_Store[0]==0)

    P8563_Read() /*如果为秒=0,为防止时间变化,再读一次*/

}

/********************************************

写时间修改值

********************************************/

//void P8563_settime()

//{

//     uchar i

//     for(i=2i<=8i++) { writeData(i,g8563_Store[i-2]) }

//     writeData(6,g8563_Store[3])

//}

/********************************************

P8563的初始化-----外部调用

********************************************/

/*

void P8563_init()

{

  uchar i

  if((ReadData(0xa)&0x3f)!=0x8) //检查是否第一次启动,是则初始化时间

  {

 //     for(i=0i<=6i++) g8563_Store[i]=c8563_Store[i] //初始化时间

//      P8563_settime()

      writeData(0x0,0x00)

      writeData(0xa,0x8) //8:00报警

      writeData(0x1,0x12) //报警有效

      writeData(0xd,0xf0)

  }

}

*/

#endif

C51单片机六位数码管时钟

用数码管dot分隔时分秒

用三个按键设置时间:

SET键:小时设定->分钟设定->结束设定,小时设定状态时表示小时的两位数码管闪烁,分钟设定时表示分钟的两位数码管闪烁

CHANGE键:在小时设定状态和分钟设定状态改变数值

SET S键:秒置零

C语言代码:

//main.c

#include <REGX52.H>

typedef unsigned int UINT

typedef unsigned char UCHAR

#define KEY P2

#define KEYMASK 0x07

sbit LE1 = P2^6 //定义位控口

sbit LE2 = P2^7 //定义段控口

UCHAR KeyPressDown = 0x00

UCHAR KeyRelease = 0x00

UCHAR LastKey = 0x00

UCHAR MODE

extern UCHAR HH

extern UCHAR MM

extern UCHAR SS

extern bit T_CYCLE

extern void T0_Init(void) //初始化定时器,函数定义在Timer.c

UCHAR code NUM[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}

void delay(UINT t) //延时t时钟周期

{

while (t--)

}

void H_Increase(void) //小时增1

{

if(HH<23) HH++

else

{

HH = 0

}

}

void M_Increase(void) //分钟增1

{

if(MM<59) MM++

else

{

MM = 0

H_Increase()

}

}

void S_Increase(void) //秒增1

{

if(SS<59) SS++

else

{

SS = 0

M_Increase()

}

}

void display(UCHAR SEG,UCHAR Digi) //显示一位数码管,SEG = 0-9数字,Digi = 第0-6位

{

LE2 = 1

P0 = (0x01<<Digi)

LE2 = 0

P0 = 0x00

LE1 = 1

P0 = NUM[SEG]

if (Digi==1||Digi==3) P0 &= 0x7f //显示分隔符

delay(50)

P0 = 0xff

LE1 = 0

}

void main(void)

{

P0 = 0xff

LE1 = 0

LE2 = 0

T0_Init()

while(1)

{

if(MODE != 1 || T_CYCLE)

{

display(HH/10,0) //显示小时十位数

display(HH%10,1) //显示小时个位数

}

if(MODE != 2 || T_CYCLE)

{

display(MM/10,2) //显示分钟十位数

display(MM%10,3) //显示分钟个位数

}

display(SS/10,4) //显示秒十位数

display(SS%10,5) //显示秒个位数

}

}

void key_Process(void) //按键处理程序

{

UCHAR CurrKey

KEY |= KEYMASK //将按键对应的IO设置为输入状态

CurrKey = (~KEY) &KEYMASK

KeyPressDown = (~LastKey) &CurrKey

KeyRelease = LastKey &(~CurrKey)

LastKey = CurrKey

switch(KeyRelease)

{

case 1:

if(MODE == 2) MODE = 0

else MODE ++

break

case 2:

if(MODE == 1) H_Increase()

if(MODE == 2) M_Increase()

break

case 4:

SS = 0

break

default: break

}

}

//Timer.c

#include <reg52.h>

typedef unsigned int UINT

typedef unsigned char UCHAR

UCHAR HH = 14 //小时初始值

UCHAR MM = 2 //分钟初始值

UCHAR SS = 55 //秒初始值

UINT u_10ms = 0//10ms计数

bit T_CYCLE = 0

extern void key_Process(void)

extern void S_Increase(void)

void T0_Init(void)

{

TMOD &= 0xf0

TMOD |= 0x01

//定时器赋初始值,定时时间为10ms。

TH0 = 0xd8

TL0 = 0xf0

TR0 = 1

IE = 0x82

}

void T0_INTSrv(void) interrupt 1

{

//定时器重新开始计时。

TH0 = 0xd8

TL0 = 0xf0

u_10ms ++

if (u_10ms%20==0) // 200 ms

{

T_CYCLE = ! T_CYCLE//闪烁循环

}

if (u_10ms>99) // 1000 ms = 1 second

{

u_10ms = 0

S_Increase()

}

key_Process() //SET按键处理

}

Proreus仿真电路:


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/8327333.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-15
下一篇 2023-04-15

发表评论

登录后才能评论

评论列表(0条)

保存