数码管模块化显示电子万年历.docx

上传人:b****4 文档编号:12022854 上传时间:2023-04-16 格式:DOCX 页数:15 大小:64.33KB
下载 相关 举报
数码管模块化显示电子万年历.docx_第1页
第1页 / 共15页
数码管模块化显示电子万年历.docx_第2页
第2页 / 共15页
数码管模块化显示电子万年历.docx_第3页
第3页 / 共15页
数码管模块化显示电子万年历.docx_第4页
第4页 / 共15页
数码管模块化显示电子万年历.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

数码管模块化显示电子万年历.docx

《数码管模块化显示电子万年历.docx》由会员分享,可在线阅读,更多相关《数码管模块化显示电子万年历.docx(15页珍藏版)》请在冰豆网上搜索。

数码管模块化显示电子万年历.docx

数码管模块化显示电子万年历

数码管显示模块化显示电子万年历

数码管共阳极7407驱动共阴极max7221/7419驱动

Ds1302实时时间显示

Ds18b20温度显示芯片

/*delay.h*/#ifndef_DELAY_H#define_DELAY_H_

#defineuintunsignedint

#defineucharunsignedchar

/*delay.c*/

#include"delay.h"voiddelay(uintxms)

uinti;

ucharj;

for(i=xms;i>0;i--)for(j=110;j>0;j--);

voiddelayms(uintxms)//毫秒级别延时

while(xms--);

/*ds1302.h*/#ifndef_DS1302_H_

#define_DS1302_H_

#include

#defineuintunsignedint

#defineucharunsignedchar

sbitIO=P1A0;〃ds1302跟单片机接口

sbitSCLK二PHI;

sbitRST=P1A2;

externunsignedchardatetime[7];//存储获得的时间值

externvoidgettime();//读取时间值函数

#endif

/*ds1302.c*/

#include

#include"ds1302.h"

uchardatetime[7]={0,0,0,0,0,0,0};//用来接收获得的时间值

voidwrite_a_byte_to_ds1302(ucharX)

uchari;

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

IO=X&0X01;

SCLK=1;

SCLK=0;

X>>=1;

ucharget_a_byte_from_ds1302()

uchari,b=0x00;

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

b|=_crol_((uchar)IO,i);

SCLK=1;

SCLK=0;

//returnb/16*10+b%16;II返回的BCD码转换为十进制

return(b>>4)*10+(b&0x0f);//注意运算的优先级

ucharread_data(ucharadd)

uchardat;

RST=0;

SCLK=0;

RST=1;

write_a_byte_to_ds1302(add);

dat=get_a_byte_from_ds1302();

SCLK=1;

RST=0;

returndat;

voidgettime()//ds1302读取当前时间存储在datetime中

uchari,add=0x81;

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

datetime[i]=read_data(add);

add+=2;

/*max7221.h*/

#ifndef_MAX7221_H_//注:

Max7221只能用来驱动共阴数码管,对共阳

的没效

#define_MAX7221_H_

#include

#defineuintunsignedint

#defineucharunsignedchar

sbitDIN=P2A0;//max7221与单片机接口DIN..CSB..CLK..

sbitCSB=P2A1;

sbitCLK=P2A2;

sbitDIN1=P2A3;

sbitCSB1=P2A4;

sbitCLK1=P2A5;

externvoidwrite(unsignedcharaddr,unsignedchardat);

//max7221写数据,转换数据函数,num的值为1,或者2,当num为1时,片选的是第一块Max7221,同理亦然。

externvoidwrite1(ucharaddr,uchardat);

externvoidinit();//max7221初始化

externvoidinit1();

#endif

/*max7221.c*/#include"max7221.h"

#include

voidwrite(ucharaddr,uchardat)//写数据,写地址函数uchari;

CSB=0;

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

CLK=0;

addr<<=1;

DIN=CY;

CLK=1;

_nop_();

_nop_();

CLK=0;

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

CLK=0;

dat<<=1;

DIN=CY;

CLK=1;

_nop_();

_nop_();

CLK=0;

CSB=1;

voidwrite1(ucharaddr,uchardat)uchari;

CSB1=0;

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

CLK1=0;

addr<<=1;

DIN1=CY;

CLK1=1;

_nop_();

_nop_();

CLK1=0;

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

CLK1=0;

dat<<=1;

DIN1=CY;

CLK1=1;

_nop_();

_nop_();

CLK1=0;

CSB1=1;

voidinit()

write(0x09,0xff);//

编码模式地址0x09,0x00-0xff,为1的则位

选通

write(0x0a,0x07);//

亮度地址0x0a,0x00-0x0f,0x0f时最亮

write(0x0b,0x07);//

扫描数码管个数地址0x0c,最多扫描8只数码

write(0x0c,0x01);//

工作模式地址OxOc0x00:

关闭;0x01:

正常

voidinit1()

write1(0x09,0xff);

write1(0x0a,0x07);

write1(0x0b,0x07);

write1(0x0c,0x01);

/*ds18b20.h*/

#ifndef_DS18B20_H

#define_DS18B20_H

#include

#include"delay.h"

#include

#defineNOP(){_nop_(),_nop_(),_nop_(),_nop_()}

sbitDQ=P1A3;//DS18B20

控制线,单线模式。

externbitng;//正负数标志位,ng=0,为正数,反之为负数,正

数负数的处理方法不同,

externbitDS18B20_IS_OK;

//为1时表示当前读取温度正常,否则第7页

读取失败。

#endif

/*ds18b20.c*/#include"ds18b20.h"

//温度字符

ucharcodeTemperature_Char[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};

//温度小数对照表

ucharcodedf_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};

ucharCurrentT=0;//当前读取的温度整数部分

ucharTemp_Value[]={0x00,0x00};//从DS18B20读取的温度值

bitng=0;//正负数标志位,ng=0,为正数,反之为负数,正

数负数的处理方法不同,

bitDS18B20_IS_OK=1;//为1时表示当前读取温度正常,否则读取失

败。

ucharDisplay_Digit[4]={0,0,0,0};//读取的温度值转换后存在这个数组中

//初始化DS18B20

ucharInit_DS18B20()

ucharstatus;

DQ=1;delayms(8);DQ=0;delayms(90);DQ=1;delayms(8);

status=DQ;delayms(100);

DQ=1;

returnstatus;

//读一字节

ucharReadOneByte()

uchari,dat=0;

DQ=1;_nop_();

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

DQ=0;dat>>=1;DQ=1;_nop_();_nop_();

if(DQ)dat|=0x80;

delayms(30);

DQ=1;

returndat;

//写一字节

voidWriteOneByte(uchardat)

uchari;

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

DQ=0;DQ=dat&0x01;delayms(5);DQ=1;dat>>=1;

//读取温度值

voidRead_Temperature()

if(Init_DS18B20()==1

DS18B20_IS_OK=0;else

)//DS18B20故障

WriteOneByte(0xCC);//

WriteOneByte(0x44);//

Init_DS18B20();

WriteOneByte(0xCC);//

WriteOneByte(0xBE);//

跳过序列号

启动温度转换

跳过序列号读取温度寄存器

Temp_Value[0]=ReadOneByte();//

温度低8位

Temp_Value[1]=ReadOneByte();//

温度高8位

DS18B20_IS_OK=1;

//对读取的温度值进行判断,处理,负数的情况,整数情况

voidProcess_Temperature()

//uchari;

//延时值与负数标识

//ucharng=0;

//高5位全为1(0)则为负数,为负数时取反加1,并设置负数标识

if((Temp_Value[1]&0xF8)==0xF8)

Temp_Value[1]=~Temp_Value[1];

Temp_Value[0]=~Temp_Value[0]+1;

 

if(Temp_Value[0]==0x00)Temp_Value[1]++;

//负数标识置1ng=1;

else

ng=0;

//查表得到温度小数部分

Display_Digit[0]=df_Table[Temp_Value[0]&0x0F];

//获取温度整数部分(高字节中的第三位与低字节中的高四位,无符号)

CurrentT=((Temp_Value[0]&0xF0)>>4)|((Temp_Value[1]0x07)<<4);

//将整数部分分解为3位待显示数字

Display_Digit[3]=CurrentT/100;

Display_Digit[2]=CurrentT%100/10;

Display_Digit[1]=CurrentT%10;

/*main.c*/

#include"max7221.h"

#include"ds1302.h"

#include"ds18b20.h"

code

uchartable[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};

//数码管段码共阳极

uchardisbuff[]={0,0,10,0,0,10,0,0};//

第一个max7221显示缓存

uchardisbuff1[]={0,0,10,0,0,10,0,0};//第二个max7221显示缓存

voidinit_T()//定时器初始化

TMOD=0X01;

TH0=-5000/256;

TL0=-5000%256;

TR0=1;

ET0=1;

EA=1;

voidmain()//主函数

uchari;

init();

init1();//第一个max7221初始化

init_T();//第二个max7221初始化

Read_Temperature();//先读一遍当前温度

delayms(50000);//读取温度有一段时间,先让他等待一段时

间否则下一刻显示的将会是错误的温度

delayms(50000);

delayms(50000);

while

(1)

gettime();//读取当前时间值

disbuff[1]=datetime[2]%10;

disbuff[3]=datetime[1]/10;

disbuff[4]=datetime[1]%10;

disbuff[6]=datetime[0]/10;

disbuff[7]=datetime[0]%10;

disbuff1[0]=datetime[6]/10;

disbuff1[1]=datetime[6]%10;

disbuff1[3]=datetime[4]/10;

disbuff1[4]=datetime[4]%10;

disbuff1[6]=datetime[3]/10;

disbuff1[7]=datetime[3]%10;

for(i=0;i<8;i++)//第一个max7221显示

write(i+1,disbuff1[i]);

for(i=0;i<8;i++)//第二个max7221显示

write1(i+1,disbuff[i]);

Read_Temperature();//再次读取当前温度

if(DS18B20_IS_OK)//如果读取成功

Process_Temperature();//对温度进行处理,特别要考虑的

是负数的情况

delayms(50000);//延时等温度显示稳定了再

次读取,这个值要取适当,否则数码管显示会出现闪烁情况

delayms(50000);

delayms(50000);

voidTimer0_1()interrupt1//为了避免温度显示在数码管上出

现闪屏的情况,这里使用定时器来显示当前温度。

TH0=-3000/256;

//这个数值要足够的小,这样扫描次数才会更多,

staticnum=0;

显示才会更稳定

TL0=-3000%256;

P3=0x00;//每次进来时候要让位码清空,也叫做消影

switch(num)//通过一个Switch语句来实现对数码管的扫

case0:

//在数码管上显示当前温度

P0=table[Display_Digit[0]];

P3=0x20>>0;

break;

case1:

P0=table[Display_Digit[1]]&0x7f;

要&0x7f

//小数后面的一位

//有小数点的位

P3=0x20>>1;

break;

case2:

//小数位,个为

//十位

if(Display_Digit[2]==0)

 

if(Display_Digit[3]==0)

//若十位为零

且百位也为零,则都显示十位为空P0=0xff;

P0=0xff;

else

P0=table[Display_Digit[2]];

显示当前十位的值

P3=0x20>>2;

break;

case3:

if(Display_Digit[3]==0)

零,则不显示,

P0=0xff;

else

P0=table[Display_Digit[3]];

P3=0x20>>3;

break;

case4:

//显示口

P0=~0x63;

P3=0x80;

break;

case5:

//固定显示C

//否则,正常

//若百位为

//否则正常显示

P0=~0x39;

 

P3=0x40;

break;

case6:

//对负数的处理

if(ng==1)//若ng=1,表示当前表示当前获得的温度值为负数,

if(Display_Digit[3]==0)//因为考虑到温度为负数的时候最小值为-55.0所以,只可能在十位,和百位这两个位置可能出现负号

if(Display_Digit[2]==0)//百位和十位都为零,则,在十位的位置添加一个负号,P0=0xbf,

P0=0xbf;

P3=0x08;

else//否则直接在百位的位置添加一个负号、

P0=0xbf;

P3=0x04;

break;

num=(num+1)%7;//num值不断在0-6直接循环希望以上资料对你有所帮助,附励志名言3条:

1、生命对某些人来说是美丽的,这些人的一生都为某个目标而奋斗。

2、推销产品要针对顾客的心,不要针对顾客的头。

3、不同的信念,决定不同的命运。

第17页

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 幼儿教育 > 唐诗宋词

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1