1.1 ds1302显示时分秒

1.数码管动态显示

在这里插入图片描述
数码管的静态显示
多个数码管只能显示一个数字
数码管的动态显示
一次只点亮一位,利用视觉暂留效应

0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f//位码0xfe为1111 1110
共阳极给0输出
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//段码0xc0为1100 0000为abcdef为0

数码管动态显示代码


#include<reg52.h>
#define uchar unsigned char	
#define BIT_ P1
#define SEG_ P2

uchar dspcom;//数码管扫描到的地方
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//段码
uchar code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码

void delay_ms(uchar z)
{uchar x,y;
for(x=z;x>0;x--)
for(y=60;y>0;y--);
}

void main()
{while(1){
P1=0xff;
for(dspcom=0;dspcom<8;dspcom++){
 P1=wei[dspcom];
 P2=tab[dspcom];
  
 delay_ms(15);
}
}
}

三步工作:1.位码全灭2.点亮一位3.延时
c语言中P0P1,P要大写
位码,段码首先要全灭,不然有残影
uchar code tab[]数据保存在程序存储区,掉电数据不消失

2.ds1302时钟

//DS1302地址定义

#define ds1302_sec_add 0x80 //秒数据地址

#define ds1302_min_add 0x82 //分数据地址

#define ds1302_hr_add 0x84 //时数据地址

#define ds1302_date_add 0x86 //日数据地址

#define ds1302_month_add 0x88 //月数据地址

#define ds1302_day_add 0x8a //星期数据地址

#define ds1302_year_add 0x8c //年数据地址

#define ds1302_control_add 0x8e //控制数据地址
mian.c,ds1302组件见另一篇文章

#include <reg52.h>
#include <intrins.h>
#include "ds1302.h"
#define uchar unsigned char						
uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf};//段码
uchar code wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码
uchar dspbuf[]={0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};//显示缓冲
void ds1302init();       
void display();//数码管显示
void daytime();
uchar dspcom;//数码管扫描到的地方
uchar h,m,s;//1302时分秒

void main()
{	
 ds1302init();
 EA=1;
 ET0=1;
 while(1)
 { 
  h=Read_Ds1302(0x85);
  m=Read_Ds1302(0x83);
  s=Read_Ds1302(0x81);
daytime();		
 }
}

void daytime()//白天
{
ET0=1;
dspbuf[0]=tab[h/16];
dspbuf[1]=tab[h%16];
dspbuf[2]=tab[11];
dspbuf[3]=tab[m/16];
dspbuf[4]=tab[m%16];
dspbuf[5]=tab[11];
dspbuf[6]=tab[s/16];
dspbuf[7]=tab[s%16];
display();}	


void display()
{P1=0XFF;
 P2=dspbuf[dspcom];
 P1=wei[dspcom];
 if(++dspcom==8)
 dspcom=0;
}
void ds1302init()//1302初始化
{   Write_Ds1302(0x8e,0x00);//关闭保护,wp=0时才能进行对其他寄存器的写操作	 (wp000000)
	Write_Ds1302(0x80,0x00);//秒
	Write_Ds1302(0x82,0x59);//分
	Write_Ds1302(0x84,0x06);//时
	Write_Ds1302(0x8e,0x90);//开启保护 ,wp=1时写保护位(初始状态)
}

工作:1.调用1302初始化设置时间(设定)2.读入时间(读)
3.dspbuf赋值后,输出数码管显示(显)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/******************************************************************************* * 标题: 试验数码管显示时钟 * * * * 通过本例程了解 DS1302时钟芯片的基本原理和使用 ,理解并掌握DS1302时钟芯片 * * 驱动程序的编写以及实现数字字符在数码管中的显示。 * * ********************************************************************************/ #include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义 #include <intrins.h> sbit SCK=P3^6; //时钟 sbit SDA=P3^4; //数据 sbit RST = P3^5;// DS1302复位 sbit LS138A=P2^2; sbit LS138B=P2^3; sbit LS138C=P2^4; bit ReadRTC_Flag;//定义读DS1302标志 unsigned char l_tmpdate[7]={0,0,12,15,5,3,8};//秒分时日月周年08-05-15 12:00:00 unsigned char l_tmpdisplay[8]; code unsigned char write_rtc_address[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //秒分时日月周年 最低位读写位 code unsigned char read_rtc_address[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; code unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //共阴数码管 0-9 '-' '熄灭‘表 /******************************************************************/ /* 函数声明 */ /******************************************************************/ void Write_Ds1302_byte(unsigned char temp); void Write_Ds1302( unsigned char address,unsigned char dat ); unsigned char Read_Ds1302 ( unsigned char address ); void Read_RTC(void);//read RTC void Set_RTC(void); //set RTC void InitTIMER0(void);//inital timer0 /******************************************************************/ /* 主函数 */ /******************************************************************/ void main(void) { InitTIMER0(); //初始化定时器0 Set_RTC(); //写入时钟值,如果使用备用电池时候,不需要没每次上电写入,此程序应该屏蔽 while(1) { if(ReadRTC_Flag) { ReadRTC_Flag=0; Read_RTC(); l_tmpdisplay[0]=l_tmpdate[2]/16; //数据的转换,因我们采用数码管0~9的显示,将数据分开 l_tmpdisplay[1]=l_tmpdate[2]&0x0f; l_tmpdisplay[2]=10; //加入"-" l_tmpdisplay[3]=l_tmpdate[1]/16; l_tmpdisplay[4]=l_tmpdate[1]&0x0f; l_tmpdisplay[5]=10; l_tmpdisplay[6]=l_tmpdate[0]/16; l_tmpdisplay[7]=l_tmpdate[0]&0x0f; } } } /******************************************************************/ /* 定时器0初始化 */ /******************************************************************/ void InitTIMER0(void) { TMOD|=0x01;//定时器设置 16位 TH0=0xef;//初始化值 TL0=0xf0; ET0=1; TR0=1; EA=1; } /******************************************************************/ /* 写一个字节 */ /******************************************************************/ void Write_Ds1302_Byte(unsigned char temp) { unsigned char i; for (i=0;i<8;i++) //循环8次 写入数据 { SCK=0; SDA=temp&0x01; //每次传输低字节 temp>>=1; //右移一位 SCK=1; } } /******************************************************************/ /* 写入DS1302 */ /******************************************************************/ void Write_Ds1302( unsigned char address,unsigned char dat ) { RST=0; _nop_(); SCK=0; _nop_(); RST=1; _nop_(); //启动 Write_Ds1302_Byte(address); //发送地址 Write_Ds1302_Byte(dat); //发送数据 RST=0; //恢复 } /******************************************************************/ /* 读出DS1302数据 */ /******************************************************************/ unsigned char Read_Ds1302 ( unsigned char address ) { unsigned char i,temp=0x00; RST=0; _nop_(); _nop_(); SCK=0; _nop_(); _nop_(); RST=1; _nop_(); _nop_(); Write_Ds1302_Byte(address); for (i=0;i<8;i++) //循环8次 读取数据 { if(SDA) temp|=0x80; //每次传输低字节 SCK=0; temp>>=1; //右移一位 _nop_(); _nop_(); _nop_(); SCK=1; } RST=0; _nop_(); //以下为DS1302复位的稳定时间 _nop_(); RST=0; SCK=0; _nop_(); _nop_(); _nop_(); _nop_(); SCK=1; _nop_(); _nop_(); SDA=0; _nop_(); _nop_(); SDA=1; _nop_(); _nop_(); return (temp); //返回 } /******************************************************************/ /* 读时钟数据 */ /******************************************************************/ void Read_RTC(void) //读取 日历 { unsigned char i,*p; p=read_rtc_address; //地址传递 for(i=0;i<7;i++) //分7次读取 秒分时日月周年 { l_tmpdate[i]=Read_Ds1302(*p); p++; } } /******************************************************************/ /* 设定时钟数据 */ /******************************************************************/ void Set_RTC(void) //设定 日历 { unsigned char i,*p,tmp; for(i=0;i<7;i++){ //BCD处理 tmp=l_tmpdate[i]/10; l_tmpdate[i]=l_tmpdate[i]; l_tmpdate[i]=l_tmpdate[i]+tmp*16; } Write_Ds1302(0x8E,0X00); p=write_rtc_address; //传地址 for(i=0;i<7;i++) //7次写入 秒分时日月周年 { Write_Ds1302(*p,l_tmpdate[i]); p++; } Write_Ds1302(0x8E,0x80); } /******************************************************************/ /* 定时器中断函数 */ /******************************************************************/ void tim(void) interrupt 1 using 1 //中断,用于数码管扫描 { static unsigned char i,num; TH0=0xf5; TL0=0xe0; P0=table[l_tmpdisplay[i]]; //查表法得到要显示数字的数码段 switch(i) { case 0:LS138A=0; LS138B=0; LS138C=0; break; case 1:LS138A=1; LS138B=0; LS138C=0; break; case 2:LS138A=0; LS138B=1; LS138C=0; break; case 3:LS138A=1; LS138B=1; LS138C=0; break; case 4:LS138A=0; LS138B=0; LS138C=1; break; case 5:LS138A=1; LS138B=0; LS138C=1; break; case 6:LS138A=0; LS138B=1; LS138C=1; break; case 7:LS138A=1; LS138B=1; LS138C=1; break; } i++; if(i==8) { i=0; num++; if(10==num) //隔段时间读取1302的数据。时间间隔可以调整 { ReadRTC_Flag=1; //使用标志位判断 num=0; } } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值