首页 单片机C语言模块化编程之数码管显示电子万年历篇

单片机C语言模块化编程之数码管显示电子万年历篇

举报
开通vip

单片机C语言模块化编程之数码管显示电子万年历篇数码管显示模块化显示电子万年历 数码管 共阳极7407驱动 共阴极max7221/7419驱动 Ds1302 实时时间显示 Ds18b20 温度显示芯片 /*delay.h*/ #ifndef _DELAY_H #define _DELAY_H_ #define uint unsigned int #define uchar unsigned char void delay(uint xms); //秒级延时 void delayms(uint xms); //毫秒级延时,不可以...

单片机C语言模块化编程之数码管显示电子万年历篇
数码管显示模块化显示电子万年历 数码管 共阳极7407驱动 共阴极max7221/7419驱动 Ds1302 实时时间显示 Ds18b20 温度显示芯片 /*delay.h*/ #ifndef _DELAY_H #define _DELAY_H_ #define uint unsigned int #define uchar unsigned char void delay(uint xms); //秒级延时 void delayms(uint xms); //毫秒级延时,不可以更改,若更改,DS18B20将显示异常 #endif /*delay.c*/ #include "delay.h" void delay(uint xms) { uint i; uchar j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } void delayms(uint xms) //毫秒级别延时 { while(xms--); } /*ds1302.h*/ #ifndef _DS1302_H_ #define _DS1302_H_ #include #define uint unsigned int #define uchar unsigned char sbit IO=P1^0; //ds1302跟单片机接口 sbit SCLK=P1^1; sbit RST=P1^2; extern unsigned char datetime[7]; //存储获得的时间值 extern void gettime(); //读取时间值函数 #endif /*ds1302.c*/ #include #include "ds1302.h" uchar datetime[7]={0,0,0,0,0,0,0}; //用来接收获得的时间值 void write_a_byte_to_ds1302(uchar X) { uchar i; for(i=0;i<8;i++) { IO=X&0X01; SCLK=1; SCLK=0; X>>=1; } } uchar get_a_byte_from_ds1302() { uchar i,b=0x00; for(i=0;i<8;i++) { b|=_crol_((uchar )IO,i); SCLK=1; SCLK=0; } //return b/16*10+b%16; //返回的BCD码转换为十进制 return (b>>4)*10+(b&0x0f); //注意运算的优先级 } uchar read_data(uchar add) { uchar dat; RST=0; SCLK=0; RST=1; write_a_byte_to_ds1302(add); dat=get_a_byte_from_ds1302(); SCLK=1; RST=0; return dat; } void gettime() //ds1302读取当前时间存储在datetime中 { uchar i,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 #define uint unsigned int #define uchar unsigned char sbit DIN=P2^0; //max7221与单片机接口 DIN..CSB..CLK.. sbit CSB=P2^1; sbit CLK=P2^2; sbit DIN1=P2^3; sbit CSB1=P2^4; sbit CLK1=P2^5; extern void write(unsigned char addr , unsigned char dat); //max7221写数据,转换数据函数 ,num的值为1,或者2,当num为1时,片选的是第一块Max7221,同理亦然。 extern void write1(uchar addr,uchar dat); extern void init(); //max7221初始化 extern void init1(); #endif /*max7221.c*/ #include "max7221.h" #include void write(uchar addr,uchar dat) // 写数据,写地址函数 { uchar i; 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; } void write1(uchar addr,uchar dat) { uchar i; 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; } void init() { write(0x09,0xff); //编码模式地址0x09 , 0x00-0xff,为1的则位选通 write(0x0a,0x07); //亮度地址0x0a ,0x00-0x0f,0x0f时最亮 write(0x0b,0x07); //扫描数码管个数地址0x0c,最多扫描8只数码管 write(0x0c,0x01); //工作模式地址0x0c 0x00:关闭;0x01:正常 } void init1() { 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 #define NOP() {_nop_(),_nop_(),_nop_(),_nop_()} sbit DQ=P1^3; //DS18B20控制线,单线模式。 extern bit ng; //正负数标志位,ng=0,为正数,反之为负数,正数负数的处理 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 不同, extern bit DS18B20_IS_OK; //为1时 关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf 示当前读取温度正常,否则读取失败。 extern uchar Display_Digit[4]; //读取的温度值转换后存在这个数组中 extern void Read_Temperature(); //读取当前温度值 extern void Process_Temperature(); //处理当前获得的温度值,正数,负数等。 #endif /*ds18b20.c*/ #include "ds18b20.h" //温度字符 uchar code Temperature_Char[8] = {0x0c,0x12,0x12,0x0c,0x00,0x00, 0x00,0x00}; //温度小数对照表 uchar code df_Table[] = {0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 }; uchar CurrentT = 0 ; //当前读取的温度整数部分 uchar Temp_Value[] = {0x00,0x00}; //从DS18B20读取的温度值 bit ng=0; //正负数标志位,ng=0,为正数,反之为负数,正数负数的处理方法不同, bit DS18B20_IS_OK=1; //为1时表示当前读取温度正常,否则读取失败。 uchar Display_Digit[4]={0,0,0,0}; //读取的温度值转换后存在这个数组中 //------------------------------------------------------- // 初始化DS18B20 //------------------------------------------------------- uchar Init_DS18B20() { uchar status; DQ = 1; delayms(8); DQ = 0 ; delayms(90); DQ = 1; delayms(8); status = DQ; delayms(100); DQ = 1; return status; } //------------------------------------------------------- //读一字节 //------------------------------------------------------- uchar ReadOneByte() { uchar i, 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; } return dat; } //------------------------------------------------------- // 写一字节 //------------------------------------------------------- void WriteOneByte(uchar dat) { uchar i ; for (i = 0; i < 8; i++) { DQ = 0 ; DQ = dat & 0x01 ; delayms(5); DQ = 1; dat>>=1; } } //---------------------------------------------------------------- // 读取温度值 //---------------------------------------------------------------- void Read_Temperature() { if( Init_DS18B20() == 1 ) //DS18B20故障 DS18B20_IS_OK = 0; else { WriteOneByte(0xCC); //跳过序列号 WriteOneByte(0x44); //启动温度转换 Init_DS18B20(); WriteOneByte(0xCC); //跳过序列号 WriteOneByte(0xBE); //读取温度寄存器 Temp_Value[0] = ReadOneByte(); //温度低8位 Temp_Value[1] = ReadOneByte(); //温度高8位 DS18B20_IS_OK = 1; } } //---------------------------------------------------------------- //对读取的温度值进行判断,处理,负数的情况,整数情况 //---------------------------------------------------------------- void Process_Temperature() { // uchar i; //延时值与负数标识 // uchar ng = 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]++; //负数标识置1 ng = 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" uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //数码管段码共阳极 uchar disbuff[]={0,0,10,0,0,10,0,0}; //第一个max7221显示缓存 uchar disbuff1[]={0,0,10,0,0,10,0,0}; //第二个max7221显示缓存 void init_T() //定时器初始化 { TMOD=0X01; TH0=-5000/256; TL0=-5000%256; TR0=1; ET0=1; EA=1; } void main() //主函数 { uchar i; init(); init1(); //第一个max7221初始化 init_T(); //第二个max7221初始化 Read_Temperature(); //先读一遍当前温度 delayms(50000); //读取温度有一段时间,先让他等待一段时间否则下一刻显示的将会是错误的温度 delayms(50000); delayms(50000); while(1) { gettime(); //读取当前时间值 disbuff[0]=datetime[2]/10; //将获得的时间值分解出来 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); } } } void Timer0_1() interrupt 1 //为了避免温度显示在数码管上出现闪屏的情况,这里使用定时器来显示当前温度。 { static num=0; TH0=-3000/256; //这个数值要足够的小,这样扫描次数才会更多,显示才会更稳定 TL0=-3000%256; P3=0x00; //每次进来时候要让位码清空,也叫做消影 switch(num) //通过一个Switch语句来实现对数码管的扫描 { case 0: //在数码管上显示当前温度值 { P0=table[Display_Digit[0]]; //小数后面的一位 P3=0x20>>0; } break; case 1: { P0=table[Display_Digit[1]]&0x7f; //有小数点的位要&0x7f P3=0x20>>1; //小数位,个为 } break; case 2: //十位 { if(Display_Digit[2]==0) { if(Display_Digit[3]==0) //若十位为零且百位也为零,则都显示十位为空P0=0xff; P0=0xff; } else P0=table[Display_Digit[2]]; //否则,正常显示当前十位的值 P3=0x20>>2; } break; case 3: { if(Display_Digit[3]==0) //若百位为零,则不显示, P0=0xff; else //否则正常显示 P0=table[Display_Digit[3]]; P3=0x20>>3; } break; case 4: //显示口 { P0=~0x63; P3=0x80; } break; case 5: //固定显示C { P0=~0x39; P3=0x40; } break; case 6: // 对负数的处理 { 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直接循环 }
本文档为【单片机C语言模块化编程之数码管显示电子万年历篇】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_295414
暂无简介~
格式:doc
大小:192KB
软件:Word
页数:13
分类:互联网
上传时间:2011-11-09
浏览量:81