单片机控制一个4位的共阴数码管通电的状态下显示时间的程序

单片机控制一个4位的共阴数码管通电的状态下显示时间的程序,第1张

#include <reg52.h>郑哗

#define uint unsigned int

#define uchar unsigned char

sbit PRESS1=P1^0

sbit PRESS2=P1^1

sbit PRESS3=P1^2

uint a[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}//0到9

uint b[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}

int miao=45,fen=58,shi=15

uint jishu

uint miaog,miaos,feng,fens,shig,shis

int ji

void init()//初始化函数设桥迅置中断寄存器的值。

{

jishu=0

TMOD=0x01

TR0=1

ET0=1

EA=1

TH0=0x3c

TL0=0xb0

}

void delay(x)//延时函数。

{

uint i,j

for(i=xi>0i--)

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

}

void xian()//把时分秒送到数码管显示。

{

uint i

miaog=miao%10

miaos=miao/10

feng=fen%10

fens=fen/10

shig=shi%10

shis=shi/10

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

{

switch(i)

{

case 0:P3=b[7]P2=a[miaog]break

case 1:P3=b[6]P2=a[miaos]break

case 2:P3=b[5]P2=0x40break

case 3:P3=b[4]P2=a[feng]break

case 4:P3=b[3]P2=a[fens]break

case 5:P3=b[2]P2=0x40break

case 6:P3=b[1]P2=a[shig]break

case 7:P3=b[0]P2=a[shis]break

}

delay(1)

}

}

void jiance()//检测键是否按下按不同键实现不同的处理。

{

if(PRESS1==0)

{

delay(2)

if(PRESS1==0)

{

while(!PRESS1)

ji++

if(ji>=4)

ji=0

}

}

if(ji==1)

{

if(PRESS2==0)

{

delay(1)

while(!PRESS2)

miao++

if(miao>=60)

{

miao=0

fen++

}

}

if(PRESS3==0)

{

delay(1)

while(!PRESS3)

miao--

if(miao<0)

{

miao=59

}

}

}

if(ji==2)

{

if(PRESS2==0)

{

delay(1)

while(!PRESS2)

fen++

if(fen>=60)

{

fen=0

shi++

}

}

if(PRESS3==0)

{

delay(1)

while(!PRESS3)

fen--

if(fen<0)

{

fen=59

}

}

}

if(ji==3)

{

if(PRESS2==0)

{

delay(1)

while(!PRESS2)

shi++

if(shi>=24)

{

shi=0

}

}

if(PRESS3==0)

{

delay(1)

while(!PRESS3)

shi--

if(shi<0)

{

shi=23

}

}

}

if(ji==0)

EA=1

else

EA=0

}

void main()

{

init()

while(1)

{

xian()

jiance()

}

}

void duan() interrupt 1 //计时中断0工作敏丛此方式1函数。

{

TH0=0x3c

TL0=0xb0

jishu++

if(jishu==20)

{

jishu=0

miao++

if(miao==60)

{

miao=0

fen++

if(fen==60)

{

fen=0

shi++

if(shi==24)

shi=0

}

}

}

}

单片机中有EPROM,我用的是STC12C5A60S2,有1K空间的EPROM,是可以断电保存用户数据的,其他型号STC单粗培片机的EPROM大小不一,参考手册,但程序差不多的,程序如下:

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

* *

* 单片机学习开发板BP-51A - 内部EPROM读写演示程序 *

* 版本: V1.0 (2011/10/13) *

* 作者: BestProvider *

* 说明: STC12C5A60S2单片机有1K字节的内部EPROM,可森档以用来存放用户数 *

*据(断电不丢失),EPROM分2个扇区,地址为0X0000-0X1FFF和0X2000 *

*-0X3FFF,需要注意的是在进行写 *** 作时,必须先要进行所在扇区 *

*的清除 *** 作*

* 硬件: 本实验需要液晶屏LCD1602来显示数据 *

* 参考: 《STC12C5A60S2中文资料》- 第12章 STC12C5A60S2系列单片机 *

*EPROM的应用 *

* *

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

#include <stc12c5a60s2.h>

typedef unsigned char BYTE // 数据范围0-255

typedef unsigned int WORD // 数据范围0-65535

typedef bit BOOL // 数据范围0-1

#define CMD_IDLE 0

#define CMD_READ 1

#define CMD_WRITE 2

#define CMD_ERASE 3

#define ENABLE_IAP 0X82

BYTE write_data[5]={0,1,2,3,4}

BYTE read_data[5]

BYTE code dis1[ ] = {"EPROM Write/Read"}

BYTE code dis2[ ] = {"Data: "}

sbit LCD_RS = P2^0 // LCD控制线

sbit LCD_RW = P2^1

sbit LCD_EN = P2^2

/* ms级延时 */

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

void delay_ms(WORD n)

{

WORD i=0

WORD j

while(i<n)

{

for(j=0j<1000j++){}

i++

}

}

/* 测试LCD忙碌状态 */岩春唯

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

BOOL lcd_bz()

{

BOOL result

LCD_RS = 0

LCD_RW = 1

LCD_EN = 1

delay_ms(1)

result = (BOOL)(P0 &0x80)

LCD_EN = 0

return result

}

/* 写入指令数据到LCD*/

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

void lcd_wcmd(BYTE cmd)

{

while(lcd_bz())

LCD_RS = 0

LCD_RW = 0

LCD_EN = 0

delay_ms(1)

P0 = cmd

delay_ms(1)

LCD_EN = 1

delay_ms(1)

LCD_EN = 0

}

/* 设定显示位置 */

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

void lcd_pos(BYTE pos)

{

lcd_wcmd(pos | 0x80)

}

/* 写入字符显示数据到LCD*/

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

void lcd_wdat(BYTE dat)

{

while(lcd_bz())

LCD_RS = 1

LCD_RW = 0

LCD_EN = 0

P0 = dat

delay_ms(1)

LCD_EN = 1

delay_ms(1)

LCD_EN = 0

}

/* LCD初始化设定*/

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

void lcd_init()

{

lcd_wcmd(0x38)

delay_ms(10)

lcd_wcmd(0x0c)

delay_ms(10)

lcd_wcmd(0x06)

delay_ms(10)

lcd_wcmd(0x01) // 清除LCD的显示内容

delay_ms(10)

}

/* EPROM 扇区清除 */

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

void Iaperasesector(unsigned char addr)

{

IAP_ADDRH=addr

IAP_ADDRL=0x00

IAP_CONTR=ENABLE_IAP

IAP_CMD=CMD_ERASE

IAP_TRIG=0x5a

IAP_TRIG=0xa5

delay_ms(10)

}

/* EPROM 写 *** 作 */

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

void Iapwritebyte()

{

BYTE i

Iaperasesector(0x00) // 在进行内部EPROM写 *** 作前需进行扇区清除 *** 作

IAP_CONTR=ENABLE_IAP

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

{

IAP_ADDRH=0x00

IAP_ADDRL=0x00+i

IAP_DATA=write_data[i]

IAP_CMD=CMD_WRITE

IAP_TRIG=0x5a

IAP_TRIG=0xa5

delay_ms(10)

}

IAP_CONTR=0x00

}

/* EPROM 读 *** 作 */

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

void Iapreadbyte()

{

BYTE i

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

{

IAP_DATA=0

IAP_CONTR=ENABLE_IAP

IAP_ADDRH=0x00

IAP_ADDRL=0x00+i

IAP_CMD=CMD_READ

IAP_TRIG=0x5a

IAP_TRIG=0xa5

delay_ms(10)

read_data[i]=IAP_DATA

}

IAP_CONTR=0x00

}

/* 数据显示 */

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

void Display()

{

BYTE m

lcd_pos(0) // 设置显示位置为第一行的第1个字符

m = 0

while(dis1[m] != '\0')

{

lcd_wdat(dis1[m]) // 显示字符

m++

}

lcd_pos(0x40) // 设置显示位置为第二行第1个字符

m = 0

while(dis2[m] != '\0')

{

lcd_wdat(dis2[m]) // 显示字符

m++

}

lcd_pos(0x46) // 显示读取的第1个数据

lcd_wdat(0x30+read_data[0])

lcd_pos(0x48) // 显示读取的第2个数据

lcd_wdat(0x30+read_data[1])

lcd_pos(0x4a) // 显示读取的第3个数据

lcd_wdat(0x30+read_data[2])

lcd_pos(0x4c) // 显示读取的第4个数据

lcd_wdat(0x30+read_data[3])

lcd_pos(0x4e) // 显示读取的第5个数据

lcd_wdat(0x30+read_data[4])

}

/* 主程序 */

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

main()

{

delay_ms(200) // 通电后延迟200ms,再进行EPROM *** 作

Iapwritebyte() // 将4个数据存入单片机内部EPROM中

delay_ms(10)

Iapreadbyte() // 从EPROM中读取数据

lcd_init() // 初始化LCD

delay_ms(10)

Display() // 显示读取的数据

while(1)

}


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存