求一个时钟数码管的C程序

求一个时钟数码管的C程序,第1张

简易电子时钟,LED数码管显示,

K1---时调整

(p36)

K2---分调整

(p37)

,数码管数据p0,数码管控制p2,上电时初始化显示:

12-00-00

#include

<reg51.h>

#include

<intrins.h>

unsigned

char

data

dis_digit

unsigned

char

key_s,

key_v

unsigned

char

code

dis_code[11]={

0x28,

0x7E,

0xA2,

0x62,

0x74,

0x61,

0x21,

0x7A,

0x20,

0x60,0xff}//0,1,2,3,4,5,6,7,8,9,关显示,数码管码表

unsigned

char

data

dis_buf[8]

unsigned

char

data

dis_index

unsigned

char

hour,min,sec

unsigned

char

sec100

sbit

K1

=

P3^6

sbit

K2

=

P3^7

bit

scan_key()

void

proc_key()

void

inc_sec()

void

inc_min()

void

inc_hour()

void

display()

void

delayms(unsigned

char

ms)

char

code

SST516[3]

_at_

0x003b

void

main(void)

{

P0

=

0xff

P2

=

0xff

TMOD

=

0x11

//

定时器0,

1工作模式1,

16位定时方式

TH1

=

0xdc

TL1

=

0

TH0

=

0xFC

TL0

=

0x17

hour

=

12

min

=

00

sec

=

00

sec100

=

0

dis_buf[0]

=

dis_code[hour

/

10]

//

时十位

dis_buf[1]

=

dis_code[hour

%

10]

//

个位

dis_buf[3]

=

dis_code[min

/

10]

//

分十位

dis_buf[4]

=

dis_code[min

%

10]

//

分个位

dis_buf[6]

=

dis_code[sec

/

10]

//

秒十位

dis_buf[7]

=

dis_code[sec

%

10]

//

秒个位

dis_buf[2]

=

0xf7

//

显示"-"

dis_buf[5]

=

0xf7

//

显示"-"

dis_digit

=

0xfe

dis_index

=

0

TCON

=

0x01

IE

=

0x8a

//

使能timer0,1

中断

TR0

=

1

TR1

=

1

key_v

=

0x03

while(1)

{

if(scan_key())

{

delayms(10)

if(scan_key())

{

key_v

=

key_s

proc_key()

}

}

}

}

bit

scan_key()

{

key_s

=

0x00

key_s

|=

K2

key_s

<<=

1

key_s

|=

K1

return(key_s

^

key_v)

}

void

proc_key()

{

EA

=

0

if((key_v

&

0x01)

==

0)

//

K1

{

inc_hour()

}

else

if((key_v

&

0x02)

==

0)

//

K2

{

min++

if(min

>

59)

{

min

=

0

}

dis_buf[3]

=

dis_code[min

/

10]

//

分十位

dis_buf[4]

=

dis_code[min

%

10]

//

分个位

}

EA

=

1

}

void

timer0()

interrupt

1

//

定时器0中断服务程序,

用于数码管的动态扫描

//

dis_index

---

显示索引,

用于标识当前显示的数码管和缓冲区的偏移量

//

dis_digit

---

位选通值,

传送到P2口用于选通当前数码管的数值,

如等于0xfe时,

//

选通P2.0口数码管

//

dis_buf

---

显于缓冲区基地址

{

TH0

=

0xFC

TL0

=

0x17

P2

=

0xff

//

先关闭所有数码管

P0

=

dis_buf[dis_index]

//

显示代码传送到P0口

P2

=

dis_digit

//

dis_digit

=

_crol_(dis_digit,1)

//

位选通值左移,

下次中断时选通下一位数码管

dis_index++

//

dis_index

&=

0x07

//

8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描

}

void

timer1()

interrupt

3

{

TH1

=

0xdc

sec100++

if(sec100

>=

100)

{

sec100

=

0

inc_sec()

}

}

void

inc_sec()

{

sec++

if(sec

>

59)

{

sec

=

0

inc_min()

}

dis_buf[6]

=

dis_code[sec

/

10]

//

秒十位

dis_buf[7]

=

dis_code[sec

%

10]

//

秒个位

}

void

inc_min()

{

min++

if(min

>

59)

{

min

=

0

inc_hour()

}

dis_buf[3]

=

dis_code[min

/

10]

//

分十位

dis_buf[4]

=

dis_code[min

%

10]

//

分个位

}

void

inc_hour()

{

hour++

if(hour

>

23)

{

hour

=

0

}

if(hour

>

9)

dis_buf[0]

=

dis_code[hour

/

10]

//

时十位

else

dis_buf[0]

=

0xff

//

当小时的十位为0时不显示

dis_buf[1]

=

dis_code[hour

%

10]

//

时个位

}

void

delayms(unsigned

char

ms)

//

延时子程序

{

unsigned

char

i

while(ms--)

{

for(i

=

0

i

<

120

i++)

}

}

利用8位数码管显示时间,原理与4位数码管显示的基本一样

仿真图:

程序源代码:

本程序已经通过在线软件仿真和硬件制作.

  org 0000h   程序开始入口地址

  sjmp main   跳转至主程序

  org 000bh   T0中断入口地址

  ljmp inti0  跳转至T0中断程序

  org 001bh   T1中断入口地址

  ljmp inti1  跳转至T1中断程序

  org 0030h

main:mov tmod,#11h  设T0、T1为模式1

     mov ie,#8ah  开T0、T1允许中断

  mov th0,#4ch  赋T0 50ms初值

  mov tl0,#00h

  mov th1,#4ch  赋T1 50ms初值

  mov tl1,#00h

  mov sp,#60h   设置堆栈指针

  mov 38h,#00 闹钟分初值

  mov 39h,#00 闹钟时初值

  mov 31h,#00 时间秒初值

  mov 32h,#00 时间分初值

  mov 33h,#00 时间时初值

  setb tr0  启动定时器T0

  setb tr1    启动定时器T1

loop:lcall display 调用时间显示程序

     lcall keysan 调用时间调节按钮

  lcall keynz 调用闹钟控制按钮

     ajmp loop

inti0:push psw   压入堆栈指针,保护现场

      push acc

   clr ea  关中断

   mov th0,#4ch 重赋T0定时初值

   mov tl0,#00h

   inc 3ah 3ah为50ms计数单元

   mov a,3ah

   cjne a,#20,out 1秒计数是否到

   mov 3ah,#00 清50ms计数初值

   inc 31h   秒加1

   mov a,31h

   cjne a,#60,out   60秒计数是否到

   mov 31h,#00

   inc 32h  分加1

   mov a,32h

   cjne a,#60,out 60分计数是否到

   mov 32h,#00

   inc 33h    时加1

   mov a,33h

   cjne a,#24,out   24时计数是否到

   mov 33h,#00

out: setb ea 开中断

     pop acc d出堆栈指针,恢复现场

  pop psw

  reti    中断返回

inti1:push psw  压入堆栈指针,恢复现场

      push acc

   clr ea

   mov th1,#4ch  重赋T1定时初值

   mov tl1,#00h

   inc 71h   71h为50ms计数单元

   mov a,71h

   cjne a,#20,out1

   mov 71h,#00

   mov a,32h  闹钟判断

      cjne a,38h,out1  闹钟时间分判断

   mov a,33h

   cjne a,39h,out1 闹钟时间时判断

   clr p1.0    到闹钟时间,清p1.0

 out1:setb ea   开中断

       pop acc

    pop psw

    reti    中断返回

display:mov a,31h  秒显示

  mov b,#10

  div ab

     mov 20h,a  将十位放入20h单元

  mov 21h,b  将个位、余数放入21h单元

disp1:  mov a,20h 秒十位显示

        mov dptr,#table

  movc a,@a+dptr  将A的内容+table内容,结果回存给A

  mov p0,a  将A给P0口

  clr p2.6  清p2.6,点亮第7位数码管

  lcall del1ms 调用1ms延时子程序

  setb p2.6  灭第7位数码管

disp2:  mov a,21h 秒个位显示

        mov dptr,#table

  movc a,@a+dptr

  mov p0,a

  clr p2.7

  lcall del1ms

  setb p2.7

disp4:  mov a,32h 分显示

        mov b,#10

  div ab

  mov 22h,a

  mov 23h,b

disp5:  mov a,22h 分十位显示

        mov dptr,#table

  movc a,@a+dptr

  mov p0,a

  clr p2.3

  lcall del1ms

  setb p2.3

disp6:  mov a,23h  分个位显示

        mov dptr,#table

  movc a,@a+dptr

  mov p0,a

  clr p2.4

  lcall del1ms

  setb p2.4

disp7:  mov a,33h   时显示

        mov b,#10

  div ab

  mov 24h,a

  mov 25h,b

disp8:  mov a,24h    时十位显示

        mov dptr,#table

  movc a,@a+dptr

  mov p0,a

  clr p2.0

  lcall del1ms

  setb p2.0

disp9:  mov a,25h  时个位显示

        mov dptr,#table

  movc a,@a+dptr

  mov p0,a

  clr p2.1

  lcall del1ms

  setb p2.1

disp10: mov 34h,#0bfh  "-"显示

        mov a,34h

        mov p0,a

  clr p2.5

  lcall del1ms

  setb p2.5

disp11: mov 35h,#0bfh  "-"显示

        mov a,35h

  mov p0,a

  clr p2.2

  lcall del1ms

  setb p2.2

  ret

display1:mov a,38h   闹钟分显示

         mov b,#10

   div ab

   mov 26h,a

   mov 27h,b

      d1:mov a,26h    闹钟分十位显示

         mov dptr,#table

   movc a,@a+dptr

   mov p0,a

   clr p2.3

   lcall del1ms

   setb p2.3

      d2:mov a,27h    闹钟分个位显示

      mov dptr,#table

   movc a,@a+dptr

   mov p0,a

   clr p2.4

   lcall del1ms

      setb p2.4

dispnz: mov a,39h  闹钟时显示

        mov b,#10

  div ab

  mov 28h,a

  mov 29h,b

 d5: mov a,28h   闹钟时十位显示

     mov dptr,#table

  movc a,@a+dptr

  mov p0,a

  clr p2.0

  lcall del1ms

  setb p2.0

 d6: mov a,29h   闹钟时个位显示

     mov dptr,#table

  movc a,@a+dptr

  mov p0,a

  clr p2.1

  lcall del1ms

  setb p2.1

        mov 35h,#0bfh  "-"显示

        mov a,35h

  mov p0,a

  clr p2.2

  lcall del1ms

  setb p2.2 

   ret  

table:db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h,80h,90h   数字0—9               

del1ms:mov r7,#10   1ms延时子程序

del1: mov r6,#50

del2:djnz r6,del2

     djnz r7,del1

  ret

del20ms:mov r5,#40    20ms延时子程序

del3: mov r4,#250

del4: djnz r4,del4

      djnz r5,del3

   ret

keysan:jnb p3.1,key1 秒加1按钮

       jnb p3.2,key2 分加1按钮

    jnb p3.3,key3 时加1按钮

      

    sjmp keyout

key1: lcall del20ms

      jb p3.1,keyout

   jnb p3.1,$

   inc 31h  秒加1

   mov a,31h

   cjne a,#60,keyout

   mov 31h,#00

   sjmp keyout

key2:lcall del20ms

     jb p3.2,keyout

  jnb p3.2,$

  inc 32h  分加1

  mov a,32h

  cjne a,#60,keyout

  mov 32h,#00

  sjmp keyout

key3:lcall del20ms

     jb p3.3,keyout

  jnb p3.3,$

  inc 33h 时加1

  mov a,33h

  cjne a,#24,keyout

  mov 33h,#00

  sjmp keyout

keyout:ret

keynz:jnb p3.4,keynz4 显示闹钟并可修改和显示当前时间

    jnb p3.7,keynz5

    jnb p3.5,nz3

    jnb p3.6,nz4

    sjmp nzout

nzout:ret

nz2:lcall display1

    jnb p3.5,nz3

 jnb p3.6,nz4

keynz4:jnb p3.4,nz2

  sjmp nzout

nz3:lcall del20ms

    jb p3.5,nzout

 jnb p3.5,$

    inc 38h

 mov a,38h

 cjne a,#60,nzout

 mov 38h,#00

 sjmp nzout

nz4:lcall del20ms

    jb p3.6,nzout

 jnb p3.6,$

 inc 39h

 mov a,39h

 cjne a,#24,nzout

 mov 39h,#00

 sjmp keyout

keynz5:jb p3.7,nzout

     jnb p3.7,$

  setb p1.0

 sjmp nzout

end

#include "reg52.h"

#define uint unsigned int

#define uchar unsigned char

uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}

uchar shi,fen,miao

uchar time

void delay(uint x)

{

uint y

for(x>0x--)

{

for(y=0y<124y++)

}

}

void display(uchar shi,uchar fen,uchar miao)

{

P2=0 //位码

P0=(tab[shi/10]) //段码

delay(2)

P2=1

P0=(tab[shi%10])

delay(2)

P2=2 //位码

P0=0x40 //段码

delay(2)

P2=3 //位码

P0=(tab[fen/10]) //段码

delay(2)

P2=4

P0=(tab[fen%10])

delay(2)

P2=5 //位码

P0=0x40 //段码

delay(2)

P2=6 //位码

P0=(tab[miao/10]) //段码

delay(2)

P2=7

P0=(tab[miao%10])

delay(2)

}

void main()

{

TMOD=0x01

TH0=(65536-50000)/256

TL0=(65536-50000)%256

EA=1

ET0=1

TR0=1

while(1)

{

if(time==20)

{

time=0

miao++

if(miao==60)

{

miao=0

fen++

if(fen==60)

{

fen=0

shi++

if(shi==24)

shi=0

}

}

}

display(shi,fen,miao)

}

}

void timer0() interrupt 1

{

TH0=(65536-50000)/256

TL0=(65536-50000)%256

time++

}

/*还有什么不明白继续追加*/


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

原文地址: http://outofmemory.cn/yw/8060750.html

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

发表评论

登录后才能评论

评论列表(0条)

保存