用C语言编写AT89C51单片机程序,设计一个智能数字钟。

用C语言编写AT89C51单片机程序,设计一个智能数字钟。,第1张

#include<reg52.h>

#define uint unsigned int

#define uchar unsigned char

sbit QB1=P1^0

sbit QB2=P1^1 //数码管段选

sbit QB3=P1^2

sbit QB4=P1^3

sbit QB5=P1^4

sbit QB6=P1^5

sbit fm=P1^6//蜂鸣器

sbit s1=P2^4//s5按键,切换显示

sbit s2=P2^3//s2按键,设置调时

sbit s3=P2^2//s3按键,加滚袜1

sbit s4=P2^1//s4按键,减1

sbit led1=P0^0

sbit led2=P0^1

sbit led3=P0^2

uchar count

uchar sec,minu,hour,day,week,mon

uchar n_sec,n_minu,n_hour

uint year

uchar set_2=1,set_1=1

uchar hs,hg,mis,mig,ss,sg

uchar nhs,nhg,nms,nmg,nss=0,nsg=0

uchar ms,mg,ds,dg,w

uchar code table[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,

0X90,0X88,0X83,0XC6,0XA1,0X8E,0X86,0xbf}//0~F,-,共阳

//uchar code tableyi[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,

//0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40}//0-F,-,共阴

uchar code table_d[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,

0x87,0xff,0xef}//0~9数组,带小数点

uchar table1[]={31,31,29,31,30,31,30,31,31,30,31,30,31}//闰年

uchar table2[]={31,31,28,31,30,31,30,31,31,30,31,30,31}//非闰年

void delay(uint)//延时函数

void timer0()//走时中断函数

void jishi()//计时函数

void key_change()//切换显示按键函数

void key_set()//设置时间按键函数

void disp(uchar,uchar,uchar,uchar,uchar,uchar)//显示函数

void zd_clock()//整点报时函数

void nz_clock()//闹钟函数

uchar incone(uchar)//加1函数

uchar decone(uchar)//减1函数

void set_time()//设置时间函数

void set_clock()//设置闹钟函数

void set_mdw()//设置月日星期函数

void main() //主函数

{

EA=1

ET0=1

TR0=1

TMOD=0x01

TH0=0x4c//50ms初值 晶振11.0592

TL0=0x00

hour=23minu=59sec=49//赋初值:11点59分0秒

n_hour=12n_minu=56n_sec=0//闹钟赋初值12点1分0秒

year=2008mon=5day=14week=3//年月日星期赋初值2008年5月11日星期天;祝天下所有母亲节日快乐

while(1)

{

hs=hour/10//时分大衫激秒HH.MM.SS

hg=hour%10

mis=minu/10

mig=minu%10

ss=sec/10

sg=sec%10

ms=mon/10//月日-星期MM.DD.-W

mg=mon%10

ds=day/10

dg=day%10

w=week

nhs=n_hour/10//闹钟定时HH.MM.SS

nhg=n_hour%10

nms=n_minu/10

nmg=n_minu%10

nss=n_sec/10

nsg=n_sec%10

key_change()//s4按键扫描

key_set()//s2按键扫描

set_time()//设置时间

set_mdw()//设置月日星期

set_clock()/塌冲/设置闹钟

if(set_1==1) //正常走时显示

{

disp(hs,hg,mis,mig,ss,sg)

}

if(set_1==2) //设置时间,LED1闪亮

{

disp(hs,hg,mis,mig,ss,sg)

if(sec%2==0)

{led2=1led3=1led1=~led1}

// else

// {led1=1}

}

if(set_1==3) //正常显示月日-星期

{

disp(ms,mg,ds,dg,16,w)

}

if(set_1==4) //设置月日-星期,LED2闪亮

{

disp(ms,mg,ds,dg,16,w)

if(sec%2==0)

{led1=1led3=1led2=~led2}

// else

// {led2=1}

}

if(set_1==5) //正常显示定时

{

disp(nhs,nhg,nms,nmg,nss,nsg)

}

if(set_1==6) //设置闹钟定时,LED3闪亮

{

disp(nhs,nhg,nms,nmg,nss,nsg)

if(sec%2==0)

{led1=1led2=1led3=~led3}

// else

// {led3=1}

}

zd_clock()//整点报时

nz_clock()//闹钟

}

}

void timer0() interrupt 1 //50ms中断函数

{

TMOD=0x01

TH0=0x4c//50ms初值 晶振11.0592

TL0=0x00

count++

if(count==20)

{

count=0

sec++

jishi()//调计时函数

}

}

void jishi() //计时函数

{

if(sec==60)

{

sec=0

minu++

if(minu==60)

{

minu=0

hour++

if(hour==24)

{ hour=0

day++

week++

if(week==8)

{week=0}

if(year%4==0&&year%100!=0||year%400==0) //闰年

{

if(day==table1[mon]+1)

{

day=0

mon++

if(mon==13)

{mon=0year++}

}

}

else //非闰年

{

if(day==table2[mon]+1)

{

day=0

mon++

if(mon==13)

{mon=0year++}

}

}

}

}

}

}

void key_change() //s1按键扫描

{

if(s1==0)

{

delay(200)

if(s1==0)

{

set_1++

while(!s1)

if(set_1==7)

{set_1=1}

}

}

}

void key_set() //s2按键扫描

{

if(s2==0)

{

delay(10)

if(s2==0)

{

set_2++

while(!s2)

if(set_2==4)

{set_2=1}

}

}

}

void disp(uchar a1,uchar a2,uchar a3,uchar a4,uchar a5,uchar a6) //显示函数

{

QB1=1

QB2=0

QB3=0

QB4=0

QB5=0

QB6=0

P3=table[a1]//段码送P0口

delay(10)//延时一小会

QB1=0

QB2=1

QB3=0

QB4=0

QB5=0

QB6=0

P3=table[a2]//第2个数码管显示,带小数点

delay(10)

QB1=0

QB2=0

QB3=1

QB4=0

QB5=0

QB6=0

P3=table[a3]//第3个数码管显示

delay(10)

QB1=0

QB2=0

QB3=0

QB4=1

QB5=0

QB6=0

P3=table[a4]//第4个数码管显示,带小数点

delay(10)

QB1=0

QB2=0

QB3=0

QB4=0

QB5=1

QB6=0

//第5个数码管显示

P3=table[a5]

delay(10)

QB1=0

QB2=0

QB3=0

QB4=0

QB5=0

QB6=1

P3=table[a6]//第6个数码管显示

delay(10)

QB1=0

QB2=0

QB3=0

QB4=0

QB5=0

QB6=0

}

void zd_clock() //整点报时函数

{

if(minu==59&&(sec==53||sec==55||sec==57))

{

fm=0

delay(5)

fm=1

delay(5)

}

fm=0

if(minu==59&&sec==59)

{

fm=0

delay(5)

fm=1

delay(5)

fm=0

}

}

void nz_clock() //闹钟函数

{

if(hour==n_hour&&minu==n_minu&&sec==n_sec)

//if((sec%2==0)&&sec<30)

{

fm=0

delay(1)

fm=1

delay(1)

}

}

void set_time() //设置时间函数

{

if(set_1==2)

{

if(set_2==1)

{

hour=incone(hour)

if(hour==24)

{hour=0}

// if(hour<0)

// {hour=23}

hour=decone(hour)

}

if(set_2==2)

{

minu=incone(minu)

if(minu==60)

{minu=0}

// if(minu<0)

// {minu=59}

minu=decone(minu)

}

}

}

void set_mdw() //设置月日星期函数

{

if(set_1==4)

{

if(set_2==1)

{

mon=incone(mon)

if(mon==13)

{mon=1}

mon=decone(mon)

// if(mon==0)

// {mon=12}

}

if(set_2==2)

{

day=incone(day)

if(day==32)

{day=0}

day=decone(day)

// if(day==0)

// {day=0}

}

if(set_2==3)

{

week=incone(week)

if(week==8)

{week=0}

week=decone(week)

// if(week==0)

// {week=7}

}

}

}

void set_clock() //设置闹钟函数

{

if(set_1==6)

{

if(set_2==1)

{

n_hour=incone(n_hour)

if(n_hour==24)

{n_hour=0}

n_hour=decone(n_hour)

if(n_hour==0)

{n_hour=0}

}

if(set_2==2)

{

n_minu=incone(n_minu)

if(n_minu==60)

{n_minu=0}

n_minu=decone(n_minu)

if(n_minu==0)

{n_minu=0}

}

}

}

uchar incone(uchar n) //加1函数

{

if(s3==0)

{ delay(200)

if(s3==0)

{

n++

while(!s3)

}

}

return(n)

}

uchar decone(uchar m) //减1函数

{

if(s4==0)

{

delay(200)

if(s4==0)

{

m--

while(!s4)

if(m<0)

{m=0}

}

}

return(m)

}

void delay(uint k) //延时函数

{

uint i,j

for(i=ki>0i--)

for(j=80j>0j--)

}

图11

程序如下:

library IEEE

use IEEE.STD_LOGIC_1164.ALL

use IEEE.STD_LOGIC_ARITH.ALL

use IEEE.STD_LOGIC_UNSIGNED.ALL

entity xuan21 is

Port ( alarm,a,b: in std_logic

y:out std_logic)

end xuan21

architecture one of xuan21 is

begin

process(alarm,a,b)

begin

if alarm='0' then y<=aelse y<=b

end if

end process

end one

仿真波形如下图12:

图12

(2)三位二选一:

模块图如图13。用以进行正常计时时间与闹铃时间显示的选择,alarm输入为按键。猜春当alarm按键未曾按下时二选一选洞好择器会选择输出显示正常的计时结果,否则当alarm按键按下时选择器将选择输出显示闹铃时间显示。

图13

程序如下:

library IEEE

use IEEE.STD_LOGIC_1164.ALL

use IEEE.STD_LOGIC_ARITH.ALL

use IEEE.STD_LOGIC_UNSIGNED.ALL

entity x213 is

Port ( alarm : in std_logic

y:out std_logic_vector(3 downto 0)

a,b: in std_logic_vector(3 downto 0))

end x213

architecture one of x213 is

begin

process(alarm,a,b)

begin

if alarm='0' then y<=aelse y<=b

end if

end process

end one

仿真结果如下图14:

图纳兆铅14

8、整点报时及闹时:

模块图如图15。在59分51秒、53秒、55秒、57秒给扬声器赋以低音512Hz信号,在59分59秒给扬声器赋以高音1024Hz信号,音响持续1秒钟,在1024Hz音响结束时刻为整点。当系统时间与闹铃时间相同时给扬声器赋以高音1024Hz信号。闹时时间为一分钟。

图15

程序如下:

library IEEE

use IEEE.STD_LOGIC_1164.ALL

use IEEE.STD_LOGIC_ARITH.ALL

use IEEE.STD_LOGIC_UNSIGNED.ALL

entity voice is

Port ( hou1,huo0,min1,min0,sec1,sec0,hh,hl,mh,ml: std_logic_vector(3 downto 0)

in_1000,in_500:in std_logic

q : out std_logic)

end voice

architecture one of voice is

begin

process(min1,min0,sec1,sec0)

begin

if min1="0101" and min0="1001" and sec1="0101" then

if sec0="0001" or sec0="0011" or sec0="0101" or sec0="0111"

then q<=in_500

elsif sec1="0101" and sec0="1001" then q<=in_1000

else q<='0'

end if

else q<='0'

end if

if min1=mh and min0=ml and hou1=hh and huo0=hl then

q<=in_1000

end if

end process

end one

仿真波形如下图16

图16

9、顶层原理图:

三、感想

通过这次设计,既复习了以前所学的知识,也进一步加深了对EDA的了解,让我对它有了更加浓厚的兴趣。特别是当每一个子模块编写调试成功时,心里特别的开心。但是在画顶层原理图时,遇到了不少问题,最大的问题就是根本没有把各个模块的VHD文件以及生成的器件都全部放在顶层文件的文件夹内,还有就是程序设计的时候考虑的不够全面,没有联系着各个模式以及实验板的情况来编写程序,以至于多考虑编写了译码电路而浪费了很多时间。在波形仿真时,也遇到了一点困难,想要的结果不能在波形上得到正确的显示

:在分频模块中,设定输入的时钟信号后,却只有二分频的结果,其余三个分频始终没反应。后来,在数十次的调试之后,才发现是因为规定的信号量范围太大且信号的初始值随机,从而不能得到所要的结果。还有的仿真图根本就不出波形,怎么调节都不管用,后来才知道原来是路径不正确,路径中不可以有汉字。真是细节决定成败啊!总的来说,这次设计的数字钟还是比较成功的,有点小小的成就感,终于觉得平时所学的知识有了实用的价值,达到了理论与实际相结合的目的,不仅学到了不少知识,而且锻炼了自己的能力,使自己对以后的路有了更加清楚的认识,同时,对未来有了更多的信心。

四、参考资料:

1、潘松,王国栋,VHDL实用教程〔M〕.成都:电子科技大学出版社,2000.(1)

2、崔建明主编,电工电子EDA仿真技术北京:高等教育出版社,2004

3、李衍编著,EDA技术入门与提高王行西安:西安电子科技大学出版社,2005

4、侯继红,李向东主编,EDA实用技术教程北京:中国电力出版社,2004

5、沈明山编著,EDA技术及可编程器件应用实训北京:科学出版社,2004

6、侯伯亨等,VHDL硬件描述语言与数字逻辑电路设计西安: 西安电子科技大学出版社,1997

7、辛春艳编著,VHDL硬件描述语言北京:国防工业出版社,2002 就这些


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存