时钟芯片DS1302驱动程序

合集下载

ds1302的驱动程序

ds1302的驱动程序

#ifndef __ds1302_H#define __ds1302_H/*------宏定义------*/#define uchar unsigned char#define uint unsigned int/******************RTC常量******************/#define TRUE 1#define FALSE 0#define RTC_CLK PD2#define RTC_DATA PD3#define RTC_CS PD4//命令#define RD 0x01 //读出#define WR 0x00 //写入#define C_SEC 0x80 //秒#define C_MIN 0x82 //分#define C_HR 0x84 //时#define C_DAY 0x86 //日#define C_MTH 0x88 //月#define C_WK 0x8A //星期DATE#define C_YR 0x8C //年#define C_WP 0x8E //控制(写保护)#define C_CHARGE 0x90 //涓流充电#define C_BURST 0xBE //时钟多字节//配置#define CLK_HALT 0x80 //停止时钟控制位SECOND bit7#define CLK_START 0x00 //启动时钟#define CHARGE_START 0xa5 //启动涓流充电#define M12_24 0x80 //12/24小时值选择位HOUR bit7 #define PROTECT 0x80 //写保护控制位CONTROL bit7 #define UPROTECT 0x00 //写保护控制位CONTROL bit7 //涓流充电控制常量#define TC_D1R2 0xA5 //high 1 Diode +2K Resistors#define TC_D2R8 0xAB //low 2 Diodes+8K Resistors#define TC_DISABLED 0x00 //Disabled(TCS<>1010 or DS=00 or RS=00) //RAM 命令#define C_RAMBASE 0xC0 //RAM0~RAM30<<1 地址需左移一位uchar time_1sok;void delay_nus(unsigned int n) //N us延时函数{char i=0;while(n--)for(i=0;i<8;i++);}void delay_nms(unsigned int n) //N ms延时函数{unsigned int i;while(n--)for(i=0;i<1140;i++);}/*******************************************函数名称: DS1302_init功能: 初始化DS1302的数据接口参数: 无返回值: 无/********************************************/void DS1302_portinit(void){DDRD|=BIT(RTC_CLK)|BIT(RTC_DATA)|BIT(RTC_CS);//将时钟端(RTC_CLK)数据端(RTC_DATA)片选端(RTC_CS)设置为输出}/*******************************************函数名称: DS1302_writeB功能: 向DS1302写入一个字节数据(没有RST操作)参数: byte--要写入的数据返回值: 无/********************************************/void DS1302_writeB(uchar byte){uchar i;for(i=0;i<8;i++) //8位数据计数{PORTD&=~BIT(RTC_CLK); //拉低时钟端if(byte&0x01) //当前位是否是1{PORTD|=BIT(RTC_DATA); //当前位是1,拉高数据端}else{PORTD&=~BIT(RTC_DATA); //当前位是0,拉低数据端}delay_nus(10); //调整时钟和脉冲宽度PORTD|=BIT(RTC_CLK); //时钟上升沿(DS1302采样数据)byte>>=1; //数据右移1位,为送出新数据位做准备}}/*******************************************函数名称: DS1302_readB功能: 从DS1302读出一个字节数据(没有RST操作)参数: 无返回值: byte--读出的数据/********************************************/uchar DS1302_readB(void){uchar i,byte=0;DDRD&=~BIT(RTC_DA TA); //将数据端口设置为输入PORTD&=~BIT(RTC_DA TA); //无上拉电阻for(i=0;i<8;i++) //8位数据计数{byte>>=1; //保存读入的数据位PORTD|=BIT(RTC_CLK); //时钟上升沿delay_nus(10); //延时,调整时钟脉冲宽度PORTD&=~BIT(RTC_CLK); //时钟下降沿,DS1302输出数据位delay_nus(10); //等待数据变化(MEGA16太快,必须等待DS1302的数据位输出,否则不能正确读出)if(PIND&BIT(RTC_DA TA)) //当前位是否是高电平{byte|=BIT(PB7); //是高电平就将返回数据的当前位置1}else{byte&=~BIT(PB7); //是低电平就将返回数据的当前位置0}}DDRD|=BIT(RTC_DA TA); //最后将数据端口设置为输出return byte; //返回读出的数据}/*******************************************函数名称: DS1302_writeD功能: 向DS1302的某个地址写入一个字节数据参数: addr--地址值(寄存器或RAM)data--要写入的地址返回值: 无/********************************************/void DS1302_writeD(uchar addr,uchar data){PORTD&=~BIT(RTC_CS); //拉低片选端PORTD&=~BIT(RTC_CLK); //拉低时钟端delay_nus(10);PORTD|=BIT(RTC_CS); //拉高片选端delay_nus(10); //调整片选脉冲DS1302_writeB(addr); //写入操作命令(地址)delay_nus(10);PORTD&=~BIT(RTC_CLK); //拉低时钟端delay_nus(10);DS1302_writeB(data); //写入数据PORTD&=~BIT(RTC_CLK); //拉低时钟端delay_nus(10); //调整片选脉冲PORTD&=~BIT(RTC_CS); //拉低片选端}/******************************************* 函数名称: DS1302_readD功能: 从DS1302的某个地址读出一个字节数据参数: addr--地址值(寄存器或RAM)返回值: data--读出的数据/********************************************/ uchar DS1302_readD(uchar addr){uchar data;PORTD&=~BIT(RTC_CS); //拉低片选端PORTD&=~BIT(RTC_CLK); //拉低时钟端delay_nus(10);PORTD|=BIT(RTC_CS); //拉高片选端delay_nus(10); //调整片选脉冲DS1302_writeB(addr); //写入操作命令(地址)delay_nus(10);data=DS1302_readB(); //读出数据delay_nus(10);PORTD&=~BIT(RTC_CLK); //拉低时钟端PORTD&=~BIT(RTC_CS); //拉低片选端return data; //返回读出的数据}/******************************************* 函数名称: DS1302_setT功能: 设置DS1302的时间参数: ptTimeD--设置时间数组指针返回值: 无/********************************************/ void DS1302_setT(uchar ptTimeD[]){uchar i;uchar addr = 0x80; //写入地址从秒寄存器开始DS1302_writeD(C_WP|WR,UPROTECT); //控制命令,WP位为0,允许写操作delay_nms(5);for(i=0;i<7;i++){DS1302_writeD(addr|WR,ptTimeD[i]); // 秒分时日月星期年addr+=2;delay_nms(1);}DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作}/*******************************************函数名称: DS1302_getT功能: 读取DS1302的当前时间参数: time[]--读取的时间数组返回值: 无/********************************************/void DS1302_getT(uchar time[]){uchar i;////////下面的是单次读写///////////////////////////* uchar addr = 0x80; //读取地址从秒寄存器开始for(i=0;i<7;i++){time[i]=DS1302_readD(addr|RD); // 秒分时日月星期年addr+=2;}*//////////////////////////////////////////////////////////////下面是多字节读取///////////////PORTD&=~BIT(RTC_CS); //拉低片选端delay_nms(10);PORTD|=BIT(RTC_CS); //拉高片选端delay_nms(10); //调整片选脉冲DS1302_writeB(0xbf); // 0xbf:时钟多字节读取命令for (i=0;i<8;i++) //时间数据的存放格式是:{ //秒,分,时,日,月,星期,年,控制time[i]=DS1302_readB(); //【7个数据(BCD格式)+1个控制】}PORTD&=~BIT(RTC_CS); //拉低片选端///////////////////////////////////////////////PORTD&=~BIT(RTC_CLK); //拉低时钟端(时钟端在不操作时为低)}/*******************************************函数名称: DS1302_check功能: 检测DS1302是否正常工作参数: 无返回值: exist--为TRUE为检测到DS1302,为FALSE为没检测到/********************************************/uchar DS1302_check(void){uchar exist;DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令DS1302_writeD(C_RAMBASE|WR,0xA5); //RAM0写入0xA5exist=DS1302_readD(C_RAMBASE|RD); //读取RAM0if(exist==0xA5){exist=TRUE; //如果读取值与写入值相等,返回TRUE }else{exist=FALSE; //如果读取值与写入值不相等,返回FALSE}return exist;}/*******************************************函数名称: DS1302_init功能: 初始化DS1302参数: 无返回值: 无/********************************************/void DS1302_init(void){DS1302_writeD(C_WP|WR,UPROTECT); //写入写允许命令DS1302_writeD(C_SEC|WR,CLK_START); //启动振荡器,DS1302开始工作//DS1302_writeD(C_CHARGE|WR,CHARGE_START);//启动涓流充电DS1302_writeD(C_WP|WR,PROTECT); //控制命令,WP位为1,不允许写操作}/*******************************************函数名称: BCD_ASCII功能: 将压缩BCD码转换成ascii码参数: BCD--将要转换的压缩BCD码ptasc--转换后的ASCII码数组指针返回值: 无/********************************************/void BCD_ASCII(uchar BCD,uchar ptasc[]){ptasc[0]=BCD/16|0x30; //0X58 35 38 //转换十位ptasc[1]=BCD&0x0F|0x30; //转换个位}/***********************************把gettime从十六进制转换为十进制T[]用来寄存转换后的数据***********************************/void change_gettime(uchar gettime[],uchar T[]){uchar i,da;for(i=0;i<7;++i){da=gettime[i]/16;if(da)da*=10;else da=0;da+=gettime[i]%16;T[i]=da;}}/*********************************把十进制转换为13b20显示的十六进制数T[]用来寄存转换后的数据************************************/void change_settime(uchar T[],uchar settime[]){uchar i,da;for(i=0;i<7;++i){da=T[i]/10*16;da+=T[i]%10;settime[i]=da;}}#endif。

DS1302驱动程序

DS1302驱动程序
delay1(10);
}
SDA = 0;
RST = 0; //复位置0,结束突发连写连读
set_ds1302_WP(); //写保护
for (i=0; i<7; i++) // 转化为正常格式
{
tmp = timedata[i] / 16;
timedata[i] = timedata[i] % 16;
}
/**
* 设置写保护
*/
void set_ds1302_WP(void)
{
reset_ds1302();
RST = 1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0x80);
SDA = 0;
RST = 0;
}
for (i=0; i<7; i++) //7组数据秒分时日月周年分别写入寄 //存器中
{
write_ds1302_byte(timedata[i]);
delay1(10);
}
write_ds1302_byte(0); //写入0,
SDA = 0;
RST = 1;
}
/**
* 清除写保护
*/
void clear_ds1302_WP(void)
{
reset_ds1302();
RST = 1;
write_ds1302_byte(0x8E);
write_ds1302_byte(0);
SDA = 0;
RST = 0;
Timer_display(time[2],time[1],time[0]);

51单片机DS1302日历时钟程序

51单片机DS1302日历时钟程序
v_W1302(0x88,0x01); //设置月
v_W1302(0x86,0x13); //设置日
v_W1302(0x84,0x18); //设置小时
v_W1302(0x82,0x05); //设置分
v_W1302(0x80,0x00); //启动晶振,设置秒
v_W1302(0x8e,0x80); //使能
v_W1302(0x80,second);
}
if(key0_count==2)
{
minute ++;
if(60==minute)
minute = 0;
write_add(0x40+7,minute);
v_W1302(0x82,minute);
}
if(key0_count==3)
{
hour ++;
if(24==hour)
uchar reverse(uchar c);
void keyscan();
void init();
void RTC_initial ();
void wr_1302(uchar wr_data);
uchar rd_1302(void);
uchar uc_R1302(uchar ucAddr);
void v_W1302(uchar ucAddr, uchar ucDa);
delay(1);
}
}
void RTC_initial ()
{
v_W1302(0x8e,0x00); //使能
v_W1302(0x80,0x80); //停止晶振
v_W1302(0x90,0x00); //关闭充电
v_W1302(0x8c,0x07); //设置年

时钟芯片ds1302程序

时钟芯片ds1302程序

这是对DS1302编程最常见的操作,有很好的参考价值!我们通过本例程可以了解 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 chartable[]={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 RTCvoid Set_RTC(void); //set RTCvoid InitTIMER0(void);//inital timer0/******************************************************************/ /* 主函数 *//******************************************************************/ void main(void){InitTIMER0(); //初始化定时器0Set_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]%10;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的数据。

DS1302时钟芯片驱动程序

DS1302时钟芯片驱动程序

DS1302时钟芯片驱动程序//DS1302时钟芯片驱动程序#include <reg51.h>//下面是引脚连接关系sbit clock_dat=P1^0;sbit clock_clk=P1^1;sbit clock_clk=P1^2;sbit a0=ACC^0;sbit a1=ACC^1;sbit a2=ACC^2;sbit a3=ACC^3;sbit a4=ACC^4;sbit a5=ACC^5;sbit a6=ACC^6;sbit a7=ACC^7;void clock_out(unsigned char dd) {ACC=dd;clock_dat=a0;clock_clk=1;clock_clk=0; clock_dat=a1;clock_clk=1;clock_clk=0; clock_dat=a2;clock_clk=1;clock_clk=0; clock_dat=a3;clock_clk=1;clock_clk=0; clock_dat=a4;clock_clk=1;clock_clk=0; clock_dat=a5;clock_clk=1;clock_clk=0; clock_dat=a6;clock_clk=1;clock_clk=0; clock_dat=a7;clock_clk=1;clock_clk=0; }unsigned char clock_in(void) {clock_dat=1;a0=clock_dat;clock_clk=1;clock_clk=0;a1=clock_dat; clock_clk=1;clock_clk=0;a2=clock_dat; clock_clk=1;clock_clk=0;a3=clock_dat; clock_clk=1;clock_clk=0;a4=clock_dat; clock_clk=1;clock_clk=0;a5=clock_dat;clock_clk=1;clock_clk=0;a6=clock_dat;clock_clk=1;clock_clk=0;a7=clock_dat;return(ACC);}unsigned char read_clock(unsigned char ord) {unsigned char dd=0;clock_clk=0;clock_rst=0;clock_rst=1;clock_out(ord);dd=clock_in();clock_rst=0;clock_clk=1;return(dd);}void write_clock(unsigned char ord,unsigned char dd) {clock_clk=0;clock_rst=0;clock_rst=1;clock_out(ord);clock_out(dd);clock_rst=0;clock_clk=1;}/*注意事项:1.每次上电,必须把秒寄存器高位(第7位)设置为0,时钟才能走时。

STM32F103驱动DS1302程序(带注释)

STM32F103驱动DS1302程序(带注释)

S T M32F103驱动D S1302程序(带注释) -CAL-FENGHAI-(2020YEAR-YICAI)_JINGBIAN1简介主控芯片是STM32F103ZET6,DS1302模块在某宝购买,测试两个小时,发现一个小时大概差1秒钟。

芯片受温度、电压影响较大。

输出结果用串口打印到串口调试助手。

如果要oled或者其他显示需要转换为十进制。

2.代码部分2.1 led部分------------led.h--------------------#ifndef __LED_H#define __LED_H#include "sys.h"void LED_Init(void);//初始化#endif------------led.c--------------------#include "led.h"//LED IO初始化void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB5 输出高}2.2 usart部分---------------usart.h------------------------#ifndef __USART_H#define __USART_H#include "stdio.h"#include "sys.h"void uart_init(u32 bound);void usart1_send_string(u8 *BuffToSend);void usart1_sendbyte(u8 data);#endif---------------usart.c-----------------------#include "sys.h"#include "usart.h"void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Peri ph_GPIOA, ENABLE); //使能USART1,GPIOA时钟//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_ART_BaudRate = bound;//串口波特率USART_ART_WordLength =USART_WordLength_8b;//字长为8位数据格式USART_ART_StopBits =USART_StopBits_1;//一个停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE); //使能串口1}//打印字节void usart1_sendbyte(u8 data){USART_SendData(USART1, data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);}//打印字符串void usart1_send_string(u8 *BuffToSend){u8 i=0;while(BuffToSend[i]!='\0'){USART_SendData(USART1, BuffToSend[i]);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);i++;}}2.3 ds1302部分---------------ds1302.h-----------------------#ifndef __DS1302_H#define __DS1302_H#include "sys.h"//写年月日时间寄存器#define WriteSecond 0x80#define WriteMinute 0x82#define WriteHour 0x84#define WriteDay 0x86#define WriteMonth 0x88#define writeWeek 0x8a#define writeYear 0x8c//读年月日时间寄存器#define ReadSecond 0x81#define ReadMinute 0x83#define ReadHour 0x85#define ReadDay 0x87#define ReadMonth 0x89#define ReadWeek 0x8b#define ReadYear 0x8d//引脚分配 SDA-PC3 SCL-PC4 RST-PC5#define DS_SDA_IN {GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)8<<12;}#define DS_SDA_OUT {GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)3<<12;}#define DS_SDA_DATAGPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)//SDA#define DS_SDA_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_3)#define DS_SDA_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_3) #define DS_SCK_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_4)//SCL #define DS_SCK_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_4)#define DS_RST_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_5)//CE #define DS_RST_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_5) void ds1302_init(void);void write_one_byte(u8 data);u8 read_one_byte(void);void ds1302_write_data(u8 reg,u8 data);u8 ds1302_read_data(u8 reg);void time_init(void);void time_read(void);u8 hex_to_bcd(u8 hex_data);u8 bcd_to_hex(u8 bcd_data);#endif---------------ds1302.c-----------------------#include "ds1302.h"#include "delay.h"u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear; u8 time[7]={0x18,0x06,0x10,0x19,0x23,0x59,0x30};//年星期月日时分秒void ds1302_init(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin =GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_5);//CE拉低GPIO_SetBits(GPIOC, GPIO_Pin_3|GPIO_Pin_4); //拉高}//写入一个字节void write_one_byte(u8 data){u8 i;DS_SDA_OUT;for(i=0;i<8;i++){DS_SCK_LOW;if(data&0x01) //从低位开始{DS_SDA_HIGH;}else{DS_SDA_LOW;}delay_us(2);DS_SCK_HIGH;data>>=1;delay_us(2);}}//读一个字节u8 read_one_byte(){u8 i,data;DS_SDA_IN ;for(i=0;i<8;i++){data>>=1;DS_SCK_HIGH;if(DS_SDA_DATA==1){data|=0x80;}else{data&=0x7F;}delay_us(2);DS_SCK_LOW;}return data;}//ds1302写寄存器写数据void ds1302_write_data(u8 reg,u8 data) {DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;write_one_byte(data); //sck低到高delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;}//读ds1302寄存器数据u8 ds1302_read_data(u8 reg){u8 temp;DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 delay_us(2);write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;temp=read_one_byte(); //sck由高到低delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;return temp;}u8 hex_to_bcd(u8 hex_data){u8 temp;temp=(hex_data/10*16 + hex_data%10);return temp;}u8 bcd_to_hex(u8 bcd_data){u8 temp;temp=(bcd_data/16*10 + bcd_data%16);return temp;}//time初始化void time_init(){ds1302_write_data(0x8e,0x00);//关闭写保护ds1302_write_data(writeYear ,(time[0]));//写入hex格式数据ds1302_write_data(writeWeek,(time[1]));ds1302_write_data(WriteMonth,(time[2]));ds1302_write_data(WriteDay,(time[3]));ds1302_write_data(WriteHour,(time[4]));ds1302_write_data(WriteMinute,(time[5]));//ds1302_write_data(WriteSecond,(time[6]));//ds1302_write_data(0x8e,0x80);//开启写保护}//读取寄存器时间void time_read(){DSyear=ds1302_read_data(ReadYear);DSweek=ds1302_read_data(ReadWeek);DSmonth=ds1302_read_data(ReadMonth);DSday=ds1302_read_data(ReadDay);DShour=ds1302_read_data(ReadHour);DSminute=ds1302_read_data(ReadMinute);DSsecond=ds1302_read_data(ReadSecond);}2.4主函数---------------main-----------------------#include "sys.h"#include "delay.h"#include "usart.h"#include "led.h"#include "ds1302.h"Extern u8DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear; int main(void){delay_init();LED_Init();uart_init(115200);ds1302_init();time_init();while(1){time_read();//更新时间usart1_sendbyte(DSyear);usart1_sendbyte(DSmonth);usart1_sendbyte(DSday);usart1_sendbyte(DShour);usart1_sendbyte(DSminute);usart1_sendbyte(DSsecond);usart1_sendbyte(DSweek);GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED0闪烁delay_ms(250);GPIO_SetBits(GPIOB,GPIO_Pin_5); //delay_ms(250);}}3.结果串口调试助手hex显示,打印的是十六进制数据。

DS1302驱动程序详解1

DS1302驱动程序详解1

DS1302驱动程序详解DS1302引脚介绍特性介绍驱动程序详解sbit IO=P1^0; //DS1302数据线sbit SCLK=P1^1; //DS1302时钟线sbit RST=P1^2; //DS1302复位线uchar WEEK[][4]={"SUN","***","MON","TUS","WEN","THU","FRI","SAT"}; //亦可定义成指针数组*WEEK[]uchar LCD_DSY_BUFFER1[]={"DA TE 00-00-00 "};uchar LCD_DSY_BUFFER2[]={"TIME 00:00:00 "};uchar DateTime[7];void Initialize_LCD();void Display_LCD_String(uchar p,uchar *s);void DelayMS(uint ms);//------------------------------------------------------------------//向DS1302写入一个字节//------------------------------------------------------------------void Write_A_Byte_TO_DS1302(uchar x){uchar i;SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备for (i=0;i<8;i++){IO=x & 0x01; //取出x的第0位数据写入1302SCLK=1; //上升沿写入数据SCLK=0; //重新拉低SCLK,形成脉冲x >>=1; //将x的各数据位右移1位,准备写入下一个数据位}}//------------------------------------------------------------------//从DS1302读取一个字节,//注意:DS1302中所存放的数据是BCD码,在读写时要注意转换////------------------------------------------------------------------uchar Get_A_Byte_FROM_DS1302(){uchar i,b=0x00;for (i=0;i<8;i++){b |= _crol_((uchar)IO,i);//将uchar类型的IO数据左移i位SCLK=1; //将SCLK置于高电平,为下降沿读出SCLK=0; //时钟下降沿读取}return (b/16)*10+b%16; //将BCD码转换为十进制数}//------------------------------------------------------------------//从DS1302指定位置读取数据//------------------------------------------------------------------ uchar Read_Data(uchar addr){uchar dat;RST=0; //拉低RSTSCLK=0; //确保写数据前SCLK被拉低RST=1; //启动数据传输Write_A_Byte_TO_DS1302(addr); //写入命令字dat=Get_A_Byte_FROM_DS1302();SCLK=1; //将时钟电平置于已知状态RST=0; //禁止数据传递return dat;}//------------------------------------------------------------------//读取当前日期时间//------------------------------------------------------------------ void GetTime(){uchar i,addr =0x81;for (i=0;i<7;i++){DateTime[i] = Read_Data(addr);addr+=2;}}//------------------------------------------------------------------//日期与时间值转换为数字字符//------------------------------------------------------------------ void Format_DataTime(uchar d,uchar *a){a[0]=d/10+'0';a[1]=d%10+'0';}//------------------------------------------------------------------//主程序//------------------------------------------------------------------ void main(){Initialize_LCD();while(1){GetTime();Format_DataTime(DateTime[6],LCD_DSY_BUFFER1+5); //0x8D 年份寄存器Format_DataTime(DateTime[4],LCD_DSY_BUFFER1+8); //0x89 月份寄存器Format_DataTime(DateTime[3],LCD_DSY_BUFFER1+11); //0x87 日期寄存器//星期strcpy (LCD_DSY_BUFFER1+13,WEEK[DateTime[5]]);//将字符串WEEK[DateTime[5]]复制到字符数组LCD_DSY_BUFFER1+13中//0x8B 周日寄存器Format_DataTime(DateTime[2],LCD_DSY_BUFFER2+5); //0x85 小时寄存器Format_DataTime(DateTime[1],LCD_DSY_BUFFER2+8); //0x83 分钟寄存器Format_DataTime(DateTime[0],LCD_DSY_BUFFER2+11); //0x81 秒寄存器Display_LCD_String(0x00,LCD_DSY_BUFFER1); //第一行显示年、月、日、星期几Display_LCD_String(0x40,LCD_DSY_BUFFER2); //第二行显示小时、分钟、秒}}。

DS1302时钟程序(完整版),液晶显示

DS1302时钟程序(完整版),液晶显示

#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar table0[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}; //液晶显示数字0——9代码sbit SCLK=P1^0;sbit DATA=P1^1;sbit CE=P1^2;sbit RS=P2^0;sbit RW=P2^1;sbit EN=P2^2;sbit FB=P0^7;sbit start=P1^4;sbit stop=P1^5;uchar i;/*******************延时n微秒函数*****************/void delaynus(uchar n) //n us延时函数{// uchar i;for(i=n;i>0;i--);}/*******************写数据函数*****************/void write1302(uchar add,uchar dat){CE=0;SCLK=0;CE=1;for(i=0;i<8;i++) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=0;i<8;i++) //写入数据{DATA=dat&0x01;SCLK=1;SCLK=0;dat>>=1;}SCLK=1;CE=0;}/*******************读数据函数*****************/uchar read1302(uchar add){uchar dat;CE=0;SCLK=0;CE=1;for(i=8;i>0;i--) //写入地址{DATA=add&0x01;SCLK=1;SCLK=0;add>>=1;}for(i=8;i>0;i--) //读出数据/********************为神马???**************************/{dat>>=1;if(DATA==1)dat=dat|0x80;SCLK=1;SCLK=0;}SCLK=1;CE=0;return dat;}/*******************DS1302初始化函数*****************/void init1302(){uchar flag;flag=read1302(0x81);if(flag&0x80){write1302(0x8e,0x00);write1302(0x80,0x00);write1302(0x82,(((1/10)<<4)|(1%10)));write1302(0x84,(((20/10)<<4)|(20%10)));write1302(0x86,(((19/10)<<4)|(19%10)));write1302(0x88,(((7/10)<<4)|(7%10)));write1302(0x8a,((2/10)<<4)|(2%10));write1302(0x8c,(((11/10)<<4)|(11%10)));write1302(0x90,0xa5); //充电。

STM32F103驱动DS1302程序(带注释)

STM32F103驱动DS1302程序(带注释)

1简介主控芯片是STM32F103ZET6,DS1302模块在某宝购买,测试两个小时,发现一个小时大概差1秒钟。

芯片受温度、电压影响较大。

输出结果用串口打印到串口调试助手。

如果要oled或者其他显示需要转换为十进制。

2.代码部分2.1 led部分------------led.h--------------------#ifndef __LED_H#define __LED_H#include "sys.h"void LED_Init(void);//初始化#endif------------led.c--------------------#include "led.h"//LED IO初始化void LED_Init(void){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);//使能PB端口时钟GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);//根据设定参数初始化GPIOB.5GPIO_SetBits(GPIOB,GPIO_Pin_5); //PB5 输出高}2.2 usart部分---------------usart.h------------------------#ifndef __USART_H#define __USART_H#include "stdio.h"#include "sys.h"void uart_init(u32 bound);void usart1_send_string(u8 *BuffToSend);void usart1_sendbyte(u8 data);#endif---------------usart.c-----------------------#include "sys.h"#include "usart.h"void uart_init(u32 bound){//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Peri ph_GPIOA, ENABLE); //使能USART1,GPIOA时钟//USART1_TX GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9//USART1_RX GPIOA.10初始化GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ; //抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC 寄存器//USART 初始化设置USART_ART_BaudRate = bound;//串口波特率USART_ART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_ART_StopBits = USART_StopBits_1;//一个停止位USART_ART_Parity = USART_Parity_No;//无奇偶校验位USART_ART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_ART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断USART_Cmd(USART1, ENABLE); //使能串口1 }//打印字节void usart1_sendbyte(u8 data){USART_SendData(USART1, data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);}//打印字符串void usart1_send_string(u8 *BuffToSend){u8 i=0;while(BuffToSend[i]!='\0'){USART_SendData(USART1, BuffToSend[i]);while( USART_GetFlagStatus(USART1,USART_FLAG_TC)!= SET);i++;}}2.3 ds1302部分---------------ds1302.h-----------------------#ifndef __DS1302_H#define __DS1302_H#include "sys.h"//写年月日时间寄存器#define WriteSecond 0x80#define WriteMinute 0x82#define WriteHour 0x84#define WriteDay 0x86#define WriteMonth 0x88#define writeWeek 0x8a#define writeYear 0x8c//读年月日时间寄存器#define ReadSecond 0x81#define ReadMinute 0x83#define ReadHour 0x85#define ReadDay 0x87#define ReadMonth 0x89#define ReadWeek 0x8b#define ReadYear 0x8d//引脚分配 SDA-PC3 SCL-PC4 RST-PC5#define DS_SDA_IN {GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)8<<12;}#define DS_SDA_OUT{GPIOC->CRL&=0XFFFF0FFF;GPIOC->CRL|=(u32)3<<12;}#define DS_SDA_DATA GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)//SDA#define DS_SDA_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_3)#define DS_SDA_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_3)#define DS_SCK_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_4)//SCL#define DS_SCK_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_4)#define DS_RST_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_5)//CE#define DS_RST_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_5)void ds1302_init(void);void write_one_byte(u8 data);u8 read_one_byte(void);void ds1302_write_data(u8 reg,u8 data);u8 ds1302_read_data(u8 reg);void time_init(void);void time_read(void);u8 hex_to_bcd(u8 hex_data);u8 bcd_to_hex(u8 bcd_data);#endif---------------ds1302.c-----------------------#include "ds1302.h"#include "delay.h"u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;u8 time[7]={0x18,0x06,0x10,0x19,0x23,0x59,0x30};//年星期月日时分秒void ds1302_init(){GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure);GPIO_ResetBits(GPIOC,GPIO_Pin_5);//CE拉低GPIO_SetBits(GPIOC, GPIO_Pin_3|GPIO_Pin_4); //拉高}//写入一个字节void write_one_byte(u8 data){u8 i;DS_SDA_OUT;for(i=0;i<8;i++){DS_SCK_LOW;if(data&0x01) //从低位开始{DS_SDA_HIGH;}else{DS_SDA_LOW;}delay_us(2);DS_SCK_HIGH;data>>=1;delay_us(2);}}//读一个字节u8 read_one_byte(){u8 i,data;DS_SDA_IN ;for(i=0;i<8;i++){data>>=1;DS_SCK_HIGH;if(DS_SDA_DATA==1){data|=0x80;}else{data&=0x7F;}delay_us(2);DS_SCK_LOW;}return data;}//ds1302写寄存器写数据void ds1302_write_data(u8 reg,u8 data) {DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;write_one_byte(data); //sck低到高delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;}//读ds1302寄存器数据u8 ds1302_read_data(u8 reg){u8 temp;DS_SCK_LOW;DS_RST_LOW;//初始rst为低delay_us(2);DS_RST_HIGH;//sck为低时rst才可置高 delay_us(2);write_one_byte(reg); //sck低到高delay_us(5);DS_SCK_LOW;temp=read_one_byte(); //sck由高到低delay_us(5);//DS_SCK_HIGH;DS_RST_LOW;return temp;}u8 hex_to_bcd(u8 hex_data){u8 temp;temp=(hex_data/10*16 + hex_data%10);return temp;}u8 bcd_to_hex(u8 bcd_data){u8 temp;temp=(bcd_data/16*10 + bcd_data%16);return temp;}//time初始化void time_init(){ds1302_write_data(0x8e,0x00);//关闭写保护ds1302_write_data(writeYear ,(time[0]));//写入hex格式数据ds1302_write_data(writeWeek,(time[1]));ds1302_write_data(WriteMonth,(time[2]));ds1302_write_data(WriteDay,(time[3]));ds1302_write_data(WriteHour,(time[4]));ds1302_write_data(WriteMinute,(time[5]));//ds1302_write_data(WriteSecond,(time[6]));//ds1302_write_data(0x8e,0x80);//开启写保护}//读取寄存器时间void time_read(){DSyear=ds1302_read_data(ReadYear);DSweek=ds1302_read_data(ReadWeek);DSmonth=ds1302_read_data(ReadMonth);DSday=ds1302_read_data(ReadDay);DShour=ds1302_read_data(ReadHour);DSminute=ds1302_read_data(ReadMinute);DSsecond=ds1302_read_data(ReadSecond);}2.4主函数---------------main-----------------------#include "sys.h"#include "delay.h"#include "usart.h"#include "led.h"#include "ds1302.h"Extern u8 DSsecond,DSminute,DShour,DSweek,DSday,DSmonth,DSyear;int main(void){delay_init();LED_Init();uart_init(115200);ds1302_init();time_init();while(1){time_read();//更新时间usart1_sendbyte(DSyear);usart1_sendbyte(DSmonth);usart1_sendbyte(DSday);usart1_sendbyte(DShour);usart1_sendbyte(DSminute);usart1_sendbyte(DSsecond);usart1_sendbyte(DSweek);GPIO_ResetBits(GPIOB,GPIO_Pin_5); //LED0闪烁delay_ms(250);GPIO_SetBits(GPIOB,GPIO_Pin_5); //delay_ms(250);}}3.结果串口调试助手hex显示,打印的是十六进制数据。

DS1302显示时钟程序

DS1302显示时钟程序

#include<reg52.h>#include<intrins.h>#define uint unsigned int#define uchar unsigned charsbit k1=P1^0; //开关的位置sbit k2=P1^1;sbit k3=P1^2;sbit k4=P1^3;sbit clk=P3^6; //时钟线sbit en=P3^5; //使能端sbit io=P3^4; //DS1302的IO口sbit lcden=P2^7; //液晶使能端sbit lcdrd=P2^6; //数据命令端sbit lcdwr=P2^5; //读写选择端sbit beep=P2^4; //蜂鸣器位置bit flag; //按键标志位uchar code t[]="LCD LOCK"; //第一行显示字符uchar code b[]="****"; //第二行显示字符uchar c[8] ={0x00}; //定义显示缓冲区uchar d[7] ={0,0,0x12,0,0,0,0}; //DS1302时间缓冲区,存放秒、分、时、日、月、uchar e[2]={0}; //用来存放分钟小时的中间值void delay(uint x) //延时函数{ uint i,j;for(i=0;i<x;i++)for(j=0;j<115;j++); //延时X*MS}void write_com(uchar com) //命令函数{ lcdrd=0; //选择命令端P0=com; //要写的命令送到P0口delay(5);lcden=1; //开启使能端delay(5);lcden=0; //关闭使能端}void write_data(uchar dat) //数据函数{ lcdrd=1; //数据选择端P0=dat;delay(5);lcden=1; //开使能delay(5);lcden=0;}bit busy() //忙碌检查函数{ bit result;lcdrd=0;lcdwr=1;lcden=1;_nop_(); //延时几微秒_nop_();_nop_();_nop_();result=(bit)(P0&0x80);lcden=0;return result;}void lcdclr() //LCD清屏函数{ write_com(0x01); //清零显示,数据指针清零delay(5);}void init() //初始化函数{ delay(15);write_com(0x38); //16*2显示,5*7点阵,8位数据delay(15);write_com(0x38);write_com(0x06); //写一个字符地址指针加1 delay(5);write_com(0x0c); //设置显示,不显示光标delay(5);write_com(0x01); //显示清零,数据指针清零}void write_byte(uchar date) //写一个字节函数{ uchar i;for(i=0;i<8;i++){ clk=0; //低电平改变数据if(date&0x01)io=1;elseio=0;clk=1; //高电平写入1302_nop_();date=date>>1;}}uchar read_byte() //读一个字节函数{uchar i,temp=0;io=1;for(i=0;i<7;i++){clk=0;if(io==1)temp=temp|0x80;elsetemp=temp&0x7f;clk=1; //产生下跳沿temp=temp>>1;}return temp;}void write1302(uchar com,uchar dat) //写1302函数在某个地址写数据{ clk=0;en=1;write_byte(com);write_byte(dat);clk=0;en=0;}uchar read1302(uchar add) //读1302函数,从地址读数据{ uchar d;clk=0;en=1;write_byte(add); //先写地址d=read_byte(); //后读数据clk=0;en=0;return d;}void set1302(uchar add,uchar *p,uchar n) //时间初始化{ write1302(0x80,0x00); //写控制,允许写操作for(;n>0;n--){ write1302(add,*p);p++;add=add+2;}write1302(0x8e,0x80); //写保护,不允许写操作}void get1302(uchar add,uchar *p,uchar n) //读取当前数据{ for(;n>0;n--){ *p=read1302(add);p++;add=add+2;}}void init1302() //初始化1302函数{ en=0;clk=0;write1302(0x80,0x00); //写秒寄存器write1302(0x90,0xab); //写充电器write1302(0x8e,0x80); //写保护,禁止写}void BEEP() //蜂鸣器函数{ beep=0; //响蜂鸣器delay(100); //响0.1sbeep=1;delay(100);}void lcdcon(uchar m1,m2,m3) //将数据转化成适合LCD显示的数据{ c[0]=m1/10+0x30; //小时十位数据c[1]=m1%10+0x30; //小时个位数据c[2]=m2/10+0x30; //分钟十位数据c[3]=m2%10+0x30; //分钟个位数据c[4]=m3/10+0x30; //秒十位c[5]=m3%10+0x30; //秒个位}void lcddis() //LCD显示函数{ write_com(0x44|0x80); //第二行第四列write_data(c[0]); //小时十位write_data(c[1]); //小时个位write_data(':'); //显示:write_data(c[2]); //显示分钟十位write_data(c[3]); //显示分钟个位write_data(':');write_data(c[4]); //显示秒十位write_data(c[5]); //显示秒个位}void keyscan() //按键函数{ uchar fen,shi; //定义两个16位分钟和小时write1302(0x8e,0x00); //1302写保护,允许写write1302(0x80,0x80); //时钟停止运行if(k2==0) //按键2被按下{ d elay(10); //去抖动if(k2==0) //确认被按下{ while(!k2); //等待按键释放BEEP(); //蜂鸣器函数d[2]=d[2]+1; //小时加1if(d[2]==24) //满24清零d[2]=0;shi=d[2]/10*16+d[2]%10; //将小时转化成16进制write1302(0x84,shi); //调整后写入1302}}if(k3==0) //按键3被按下{ delay(10); //抖动if(k3==0) //确认被按下{ while(!k3); //等待按键放开BEEP(); //蜂鸣器函数d[1]=d[1]+1; //分钟加1if(d[1]==60) //满60清零d[1]=0;fen=d[1]/10*16+d[1]%10; //将分钟转化为16进制write1302(0x82,fen); //调整后,写入1302}}if(k4==0) //按键4被按下{ d elay(10); //去抖动if(k4==0) //确认被按下{ while(!k4); //等待按键释放BEEP(); //蜂鸣器函数write1302(0x80,0x00); //调整后,启动时钟运行write1302(0x8e,0x80); //写保护,禁止写flag=0; //按键1标志位清零}}}void gettime() //读取当前时间,转化为10进制{ uchar miao,fen,shi;write1302(0x8e,0x00); //控制命令,0表示允许写write1302(0x90,0xab); //电流控制miao=read1302(0x81); //读取秒fen=read1302(0x83); //读取分shi=read1302(0x85); //读取小时d[0]=miao/16*10+miao%16; //转化为10进制d[1]=fen/16*10+fen%16; //转化为10进制d[2]=shi/16*10+shi%16; //转换为10进制}void main() //主函数{ uchar i;P0=0xff;P2=0xff;init1302(); //1302初始化函数lcdclr(); //1302清屏函数write_com(0x00|0x80); //第一行第0列i=0;while(t[i]!=0){ write_data(t[i]); //第一个字符显示i++;}write_com(0x40|0x80); //第二行显示第0列i=0;while(b[i]!=0);{ write_data(b[i]);i++;}init1302();while(1){ gettime();if(k1==0) //按键1按下{ delay(10); //去抖动if(k1==0) //确认按下{ while(!k1); //等待按键释放BEEP(); //蜂鸣器函数flag=1; //按键1标志位置位,进行时钟调整}}if(flag==1) //如为1,则进行调整keyscan();lcdcon(d[2],d[1],d[0]); //将1302的数据送到函数转换lcddis(); //调整LCD显示,显示小时,分钟,秒}}。

DS1302时钟芯片C51驱动程序

DS1302时钟芯片C51驱动程序

DS1302时钟芯片C51驱动程序/**********************************************程序名称:DS1302时钟芯片C51驱动程序简要说明:read_clockS函数为读取时钟数据调用Set_time即可调整时间并写入DS1302sel为调整标志,可通过外部按键来更改其值来源:整理杜洋程序文档所得**********************************************///定义头文件#include/************************************************************** ****///定义DS1302时钟接口sbit clock_clk = P1 ^ 0; //ds1302_clk(时钟线)sbit clock_dat = P1 ^ 1; //ds1302_dat(数据线)sbit clock_Rst = P1 ^ 2; //ds1302_Rst(复位线)/************************************************************** ****///定义累加器A中的各位sbit a0 = ACC ^ 0;sbit a1 = ACC ^ 1;sbit a2 = ACC ^ 2;sbit a3 = ACC ^ 3;sbit a4 = ACC ^ 4;sbit a5 = ACC ^ 5;sbit a6 = ACC ^ 6;sbit a7 = ACC ^ 7;/************************************************************** ****///定义全局变量unsigned char yy,mo,dd,xq,hh,mm,ss; //定义时间映射全局变量/************************************************************** ****///声明unsigned char clock_in(void);void clock_out(unsigned char dd);void Init_1302(void);unsigned char read_clock(unsigned char ord);void read_clockS(void);void Set_time(unsigned char sel);void write_clock(unsigned char ord, unsigned char dd);/************************************************************** ****///常用时钟数据读取void read_clockS(void){ss = read_clock(0x81); //读取秒数据mm = read_clock(0x83); //读取分钟数据hh = read_clock(0x85); //小时dd = read_clock(0x87); //日mo = read_clock(0x89); //月xq = read_clock(0x8b); //星期yy = read_clock(0x8d); //年}/************************************************************** ****///调时用加1或减1程序void Set_time(unsigned char sel){//根据选择调整的相应项目加1或减1并写入DS1302,sel为调整项标志,通过外部程序来影响它signed char address,item;signed char max,mini;if(sel==6) {address=0x80; max=0;mini=0;} //秒7if(sel==5) {address=0x82; max=59;mini=0;} //分钟6if(sel==4) {address=0x84; max=23;mini=0;} //小时5if(sel==3) {address=0x8a; max=7;mini=1;} //星期4if(sel==2) {address=0x86; max=31;mini=1;} //日3if(sel==1) {address=0x88; max=12;mini=1;} //月2if(sel==0) {address=0x8c; max=99; mini=0;} //年1//读取1302某地址上的数值转换成10进制赋给itemitem=((read_clock(address+1))/16)*10 + (read_clock(address+1))%16;if(ADD_KEY == 0){item++;} //增加键(ADD_KEY)按下,数加1if(DEC_KEY == 0){item--;} //减少键(DEC_KEY)按下,数减 1 if(item>max) item=mini; //查看数值有效范围if(itemwrite_clock(0x8e,0x00); //允许写操作write_clock(address,(item/10)*16+item%10);//转换成16进制写入1302write_clock(0x8e,0x80); //写保护,禁止写操作}/************************************************************** ****///设置1302的初始时间void Init_1302(void)//(2009年1月1日00时00分00秒星期一){write_clock(0x8e,0x00); //允许写操作write_clock(0x8c,0x09); //年write_clock(0x8a,0x01); //星期write_clock(0x88,0x01); //月write_clock(0x86,0x01); //日write_clock(0x84,0x00); //小时write_clock(0x82,0x00); //分钟write_clock(0x80,0x00); //秒write_clock(0x90,0xa5); //充电write_clock(0x8e,0x80); //禁止写操作}/************************************************************** ****///DS1302写数据(底层协议)void write_clock(unsigned char ord, unsigned char dd){clock_clk=0;clock_Rst=0;clock_Rst=1;clock_out(ord);clock_out(dd);clock_Rst=0;clock_clk=1;}/************************************************************** ****///1302驱动程序(底层协议)void clock_out(unsigned char dd){ACC=dd;clock_dat=a0; clock_clk=1; clock_clk=0;clock_dat=a1; clock_clk=1; clock_clk=0;clock_dat=a2; clock_clk=1; clock_clk=0;clock_dat=a3; clock_clk=1; clock_clk=0;clock_dat=a4; clock_clk=1; clock_clk=0;clock_dat=a5; clock_clk=1; clock_clk=0;clock_dat=a6; clock_clk=1; clock_clk=0;clock_dat=a7; clock_clk=1; clock_clk=0;}/************************************************************** ****///DS1302写入字节(底层协议)unsigned char clock_in(void){clock_dat=1;a0=clock_dat;clock_clk=1; clock_clk=0; a1=clock_dat;clock_clk=1; clock_clk=0; a2=clock_dat;clock_clk=1; clock_clk=0; a3=clock_dat;clock_clk=1; clock_clk=0; a4=clock_dat;clock_clk=1; clock_clk=0; a5=clock_dat;clock_clk=1; clock_clk=0; a6=clock_dat;clock_clk=1; clock_clk=0; a7=clock_dat;return(ACC);}/************************************************************** ****///DS1302读数据(底层协议)unsigned char read_clock(unsigned char ord){unsigned char dd=0;clock_clk=0;clock_Rst=0;clock_Rst=1;clock_out(ord);dd=clock_in();clock_Rst=0;clock_clk=1;return(dd);}/************************************************************** ****/。

基于STM32的DS1302时钟模块驱动程序(详细)

基于STM32的DS1302时钟模块驱动程序(详细)

基于STM32的DS1302时钟模块驱动程序(详细)⽬录1.项⽬概述2.DS1032的数据⼿册解析2.1 DS1302的引脚介绍2.2 DS1302的通讯协议及时序2.3 DS1302的相关寄存器3.程序代码及其注释4.结果演⽰5.附录:7针0.96⼨OLED屏驱动代码(SPI驱动)1.项⽬概述本程序采⽤的主控芯⽚为STM32F103RCT6,通过主控芯⽚驱动DS1302时钟模块,并将其实时时间显⽰在7针0.96⼨OLED屏上。

使⽤STM32的普通IO⼝模拟DS1302的通信时序,使⽤STM32的SPI外设驱动OLED屏。

下⾯从DS1302的数据⼿册开始完成整个项⽬。

2.DS1302数据⼿册解析2.1DS1302引脚介绍VCC1,VCC2是电源引脚,VCC1是主供电引脚,VCC2接备⽤电池,当主供电电源电量不⾜或者断电时,备⽤电池会通过VCC2及时供电,保证时钟模块在主供电引脚断电后任然会正常计时。

GND是地引脚。

X1,X2是有关晶振的引脚,不做深究。

CE引脚是输⼊引脚,在单⽚机从DS1302读取数据或者向其写⼊数据时,CE引脚必须配置为⾼电平。

在芯⽚内部连接有40K下拉电阻。

I/O引脚充当双向数据引脚,即数据的发送和接收都在这条线上完成。

SCLK是同步时钟引脚,控制I/O引脚上数据的接收和发送。

2.2 DS1302的通讯协议及时序指令字节启动每次的数据传输,上图说明了指令字节的构造。

①位7必须为逻辑1,位7为逻辑0时指令会失效。

②我们使⽤的不是RAM当中的寄存器及数据,故位6应该为逻辑0。

③位1到位5为寄存器地址。

④位0为逻辑0时表明要往指定寄存器⾥⾯写数据,为逻辑1时要从指定寄存器⾥⾯读出数据。

指令字节的传输总是从位0(LSB)开始传输。

上图是ds1302通信时序图。

1.CE和时钟控制。

将CE置⾼将开启数据传输,CE输⼊提供俩个功能,⾸先CE开启了通信数据进⼊移位寄存器的通路,其次CE提供了⼀个可以终⽌单个字节或者多个字节的数据传输。

DS1302 时钟芯片 C程序

DS1302 时钟芯片 C程序
/*DS1302操作的引脚定义*/
sbit ds_sclk=P1^6;//串行时钟,输入,控制数据的输入输出
sbit ds_io =P3^5;//三线接口时的双向数据线
sbit ds_ce =P1^7;//输入信号,在读写数据期间,必须为高。该引脚有两个功能:
//第一,CE开始控制字访问移位寄存器的控制逻辑:其次,CE提供结束单字节或多字节数据传输的方法。
年份寄存器 8CH 8DH 00-99
更新时间:2012年07月17日
更新版本:无
更新日志:
2012年07月17日 文件大小:256字节
2012年07月17日 开始优化代码 将相同的代码写成函数以便调用
2012年07月17日 文件大小:276字节
2012年07月17日 除了突发功能没有编写其他的均已写出
/*DS1302年份寄存器地址*/
#define Read_years 0x8d //读取的年地址
#define Write_years 0x8c //写入的年地址
/*DS1302写保护寄存器地址*/
#define Read_wp 0x8f //读取的写保护地址
20ndef __DS_1302_H__
#define __DS_1302_H__
#include<stc89.h> //包含单片机寄存器的头文件
#define uchar unsigned char
#define uint unsigned int
ds1302_write(Write_years ,Decimal_bcd(12));//写入时间年
ds1302_write(Write_charging,ds_cr6 ); //写入是否涓流充电 不充电

DS1302驱动程序

DS1302驱动程序

DS1302是课程设计和毕业设计经常用到的时钟芯片,还在愁怎么对DS1302操作吗?那么看完DS1302驱动程序,一切变得那么简单。

DS1302驱动程序://===========DS1302.H================#ifndef _DS1302_H__#define _DS1302_H__//DS1302管脚定义sbit T_IO=P2^6; //位定义1302芯片的接口,数据输出端定义在P2.5引脚sbit T_RST=P2^7; //位定义1302芯片的接口,复位端口定义在P2.6引脚sbit T_CLK=P2^5; //位定义1302芯片的接口,时钟输出端口定义在P2.4引脚//变量定义声明unsigned char TableDs1302[7]={55,59,23,4,3,5,11}; //初始化时时间日期设置//秒分时日月星期年//函数定义声明void Write1302(unsigned char ); //向1302写一个字节数据void WriteSet1302(unsigned char ,unsigned char );//根据命令字,向1302写一个字节数据unsigned char Read1302(void);//从1302读一个字节数据unsigned char ReadSet1302(unsigned char Cmd);//根据命令字从1302读取一个字节数据void InitDS1302(void);//初始化1302void GetTime(void);//获取1302的时间/*****************************************************函数功能:向1302写一个字节数据入口参数:x***************************************************/void Write1302(unsigned char dat){unsigned char i;T_CLK=0; //拉低T_CLK,为脉冲上升沿写入数据做好准备Delay1Us(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续写8个二进制位数据{T_IO=dat&0x01; //取出dat的第0位数据写入1302Delay1Us(2); //稍微等待,使硬件做好准备T_CLK=1; //上升沿写入数据Delay1Us(2); //稍微等待,使硬件做好准备T_CLK=0; //重新拉低T_CLK,形成脉冲dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位}}/*****************************************************函数功能:根据命令字,向1302写一个字节数据入口参数:Cmd,储存命令字;dat,储存待写的数据,为十进制数***************************************************/void WriteSet1302(unsigned char Cmd,unsigned char dat){T_RST=0; //禁止数据传递T_CLK=0; //确保写数居前T_CLK被拉低T_RST=1; //启动数据传输Delay1Us(2); //稍微等待,使硬件做好准备Write1302(Cmd); //写入命令字Write1302((dat/10<<4)|(dat%10)); //写数据T_CLK=1; //将时钟电平置于已知状态T_RST=0; //禁止数据传递}/*****************************************************函数功能:从1302读一个字节数据入口参数:x***************************************************/unsigned char Read1302(void){unsigned char i,dat;Delay1Us(2); //稍微等待,使硬件做好准备for(i=0;i<8;i++) //连续读8个二进制位数据{dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位if(T_IO==1) //如果读出的数据是1dat|=0x80; //将1取出,写在dat的最高位T_CLK=1; //将T_CLK置于高电平,为下降沿读出Delay1Us(2); //稍微等待T_CLK=0; //拉低T_CLK,形成脉冲下降沿Delay1Us(2); //稍微等待}return dat; //将读出的数据返回}/*****************************************************函数功能:根据命令字,从1302读取一个字节数据入口参数:Cmd***************************************************/unsigned char ReadSet1302(unsigned char Cmd){unsigned char temp,dat1,dat2;T_RST=0; //拉低T_RSTT_CLK=0; //确保写数居前T_CLK被拉低T_RST=1; //启动数据传输Write1302(Cmd); //写入命令字temp=Read1302(); //读出数据T_CLK=1; //将时钟电平置于已知状态T_RST=0; //禁止数据传递dat1=temp/16; //16进制转成BCDdat2=temp%16;temp=dat1*10+dat2; //转换成10进制数字return (temp); //将读出的数据返回}/*****************************************************函数功能: 1302进行初始化设置***************************************************/void InitDS1302(void){unsigned char i,add;add=0x80;WriteSet1302(0x8e,0x00); //允许写入for(i=0;i<7;i++){WriteSet1302(add,TableDs1302[i]);add+=2;}WriteSet1302(0x90,0xa6); //写充电控制寄存器.WriteSet1302(0x8e,0x80); //禁止写入}/*****************************************************程序功能:获取DS1302时间*****************************************************/void GetTime(){unsigned char i,add=0x81;WriteSet1302(0x8e,0x00); //允许向DS1302写入数据for(i=0;i<7;i++){TableDs1302[i]=ReadSet1302(add); //获得的数据已转换为十进制add+=2;}WriteSet1302(0x8e,0x80); //获取完一次时间,禁止向DS1302写入数据,提高可靠}endif。

时钟芯片DS1302数码管程序

时钟芯片DS1302数码管程序
void write(uchar address,uchar number)
{
uchar i;
dsclk=0;//清零时钟总线
dsdata=0;//清零数据总线
dsret=0;//片选端无效
dsret=1;//逻辑控制有效,可对1302操作
for(i=16;i>0;i++)
dsclk=1;
}
dsclk=1;//上升沿动作
dsret=0;//片选无效,不可进行操作
}
/*********** 时间显示函数**************/
void show(
{
uchar i;
for(i=0;i<8;i++) // 数码管有8位,因此需要循环8次
{
uchar code tab[8]={0xf7,0xfb,0Xfd,0Xfe,0x7f,0xbf,0xdf,0xef};//数码管显示位选端
uchar buf[8];//申请数据暂存空间
/********** 延时函数************/
void delay(uchar i)
{
while(--i);
address=address>>1;
if(dsdata)
address=address|0x80;
dsclk=1;//上升沿动作
dsclk=1;//等待
}
dsclk=1;//时钟置高
dsret=0;//片选无效
return (address);
}
/*********** 写 ***************/

DS1302时钟芯片C语言驱动程序

DS1302时钟芯片C语言驱动程序

/*********************************************************************/ /* 实时时钟模块时钟芯片型号:DS1302 *//*/*//*********************************************************************/sbit T_CLK = P2^7; /*实时时钟时钟线引脚*/sbit T_IO = P1^4; /*实时时钟数据线引脚*/sbit T_RST = P1^5; /*实时时钟复位线引脚*//********************************************************************** 名称: v_RTInputByte* 说明:* 功能: 往DS1302写入1Byte数据* 调用:* 输入: ucDa 写入的数据* 返回值: 无***********************************************************************/ void v_RTInputByte(uchar ucDa){uchar i;ACC = ucDa;for(i=8; i>0; i--){T_IO = ACC0; /*相当于汇编中的RRC */T_CLK = 1;T_CLK = 0;ACC = ACC >> 1;}}/********************************************************************** 名称: uchar uc_RTOutputByte* 说明:* 功能: 从DS1302读取1Byte数据* 调用:* 输入:* 返回值: ACC***********************************************************************/ uchar uc_RTOutputByte(void){uchar i;for(i=8; i>0; i--){ACC = ACC >>1; /*相当于汇编中的RRC */ACC7 = T_IO;T_CLK = 1;T_CLK = 0;}return(ACC);}/********************************************************************** 名称: v_W1302* 说明: 先写地址,后写命令/数据* 功能: 往DS1302写入数据* 调用: v_RTInputByte()* 输入: ucAddr: DS1302地址, ucDa: 要写的数据* 返回值: 无***********************************************************************/ void v_W1302(uchar ucAddr, uchar ucDa){T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令*/v_RTInputByte(ucDa); /* 写1Byte数据*/T_CLK = 1;T_RST =0;}/********************************************************************** 名称: uc_R1302* 说明: 先写地址,后读命令/数据* 功能: 读取DS1302某地址的数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: ucAddr: DS1302地址* 返回值: ucDa :读取的数据***********************************************************************/ uchar uc_R1302(uchar ucAddr){uchar ucDa;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(ucAddr); /* 地址,命令*/ucDa = uc_RTOutputByte(); /* 读1Byte数据*/T_CLK = 1;T_RST =0;return(ucDa);}/********************************************************************** 名称: v_BurstW1302T* 说明: 先写地址,后写数据(时钟多字节方式)* 功能: 往DS1302写入时钟数据(多字节方式)* 调用: v_RTInputByte()* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年控制* 8Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B 1B* 返回值: 无***********************************************************************/ void v_BurstW1302T(uchar *pSecDa){uchar i;v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbe); /* 0xbe:时钟多字节写命令*/for (i=8;i>0;i--) /*8Byte = 7Byte 时钟数据+ 1Byte 控制*/{v_RTInputByte(*pSecDa);/* 写1Byte数据*/pSecDa++;T_CLK = 1;T_RST =0;}/********************************************************************** 名称: v_BurstR1302T* 说明: 先写地址,后读命令/数据(时钟多字节方式)* 功能: 读取DS1302时钟数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: pSecDa: 时钟数据地址格式为: 秒分时日月星期年* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B* 返回值: ucDa :读取的数据***********************************************************************/ void v_BurstR1302T(uchar *pSecDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xbf); /* 0xbf:时钟多字节读命令*/for (i=8; i>0; i--){*pSecDa = uc_RTOutputByte(); /* 读1Byte数据*/pSecDa++;}T_CLK = 1;T_RST =0;/********************************************************************** 名称: v_BurstW1302R* 说明: 先写地址,后写数据(寄存器多字节方式)* 功能: 往DS1302寄存器数写入数据(多字节方式)* 调用: v_RTInputByte()* 输入: pReDa: 寄存器数据地址* 返回值: 无***********************************************************************/ void v_BurstW1302R(uchar *pReDa){uchar i;v_W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xfe); /* 0xbe:时钟多字节写命令*/for (i=31;i>0;i--) /*31Byte 寄存器数据*/{v_RTInputByte(*pReDa); /* 写1Byte数据*/pReDa++;}T_CLK = 1;T_RST =0;}/********************************************************************** 名称: uc_BurstR1302R* 说明: 先写地址,后读命令/数据(寄存器多字节方式)* 功能: 读取DS1302寄存器数据* 调用: v_RTInputByte() , uc_RTOutputByte()* 输入: pReDa: 寄存器数据地址* 返回值: 无***********************************************************************/ void v_BurstR1302R(uchar *pReDa){uchar i;T_RST = 0;T_CLK = 0;T_RST = 1;v_RTInputByte(0xff); /* 0xbf:时钟多字节读命令*/for (i=31; i>0; i--) /*31Byte 寄存器数据*/{*pReDa = uc_RTOutputByte(); /* 读1Byte数据*/pReDa++;}T_CLK = 1;T_RST =0;}/********************************************************************** 名称: v_Set1302* 说明:* 功能: 设置初始时间* 调用: v_W1302()* 输入: pSecDa: 初始时间地址。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

return date; } uchar RE1302( uchar addr ) { uchar Date; RST=0; CK=0; RST=1; //CK 为 0 时,RST 才能为 1,然后才能读写 WRdate(addr); //写地址 Date=REdate(); //读数据 CK=1; RST=0; re02(0x8E,0X00); // 0X8E 是 WP 写保护地址,最高位赋 0 表示可以写 WR1302( 0x80, Z10BCD( sec ) ); //向秒单元赋初值 WR1302( 0x82, Z10BCD( min ) ); //向分单元赋初值 WR1302( 0x84, Z10BCD( hor ) ); //向时单元赋初值 WR1302( 0x86, Z10BCD( day ) ); //向日单元赋初值 WR1302( 0x88, Z10BCD( yue ) ); //向月单元赋初值 WR1302( 0x8a, Z10BCD( week) ); //向周单元赋初值 WR1302( 0x8c, Z10BCD( year) ); //向年单元赋初值 } main()
时钟芯片 DS1302 驱动程序
芯片介绍 DS1302 是 DALLAS 公司推出的串行接口实时时钟芯片。芯片使用简单, 外部连线少,在智能化仪表及自动控制领域具有广泛用途。其主要特点为简 单的三线串行 I/O 接口; 2.5~5.5V 的电压工作范围(在 2.5V 工作时耗电 小于 300nA); 与 TTL 兼容(Vcc=5V)时; 实时时钟包括秒、分、小时、 日、月、星期和年(闰年)等信息; 31*8 静态 RAM 可供用户使用; 可 选的涓流充电方式; 工作电源和备份电源双引脚输入; 备份电源可由大容 量电容来替代。 2 脚和 3 脚接 32768Khz 晶振,1 脚接主电源,8 脚接备用电池(亦可用大 电容代替)。5、6、7 脚与单片机连接。 #include #include #define uint unsigned int #define uchar unsigned char
// WR1302(0x90,0XA4); //一个二极管不加电阻 // WR1302(0x90,0XA8); //两个二极管不加电阻 // WR1302(0x90,0XA9); //两个二极管加一个 2K 电阻 // WR1302(0x90,0XAA); //两个二极管加一个 4K 电阻 // WR1302(0x90,0XAB); //两个二极管加一个 8K 电阻 while(1) { Sec = BCDTO10( RE1302(0x81) ); //0x81 读秒数据,读出来的是 BCD 码,还要 转换成十进制数 Min = BCDTO10( RE1302(0x83) ); //0x83 读分数据 Hor = BCDTO10( RE1302(0x85) ); //0x85 读时数据
#define nop() _nop_() sbit RST = P1 ; sbit CK = P1; sbit IO = P1; uchar Z10BCD( uchar date) //十进制转 BCD 码 { uchar i,j; i=date/10; j=date-(i*10); i=(i>4 ; j=date &amp; 0x0f ; i=i*10+j;
return i; } void MCs() //上升沿 { CK=0; nop(); CK=1; } void MCx() //下降沿 { CK=1; nop(); CK=0;
} void WRdate( uchar date ) //写一个字节,由低到高 { uchar i; for(i=0;i>=1; } } uchar REdate() { uchar i,date=0; for(i=0;i>=1; }
{ uchar Sec,Min,Hor,Day; uchar Yue,Week,Year; WR1302(0x8E,0X00); // 0X8E 是 WP 写保护地址,最高位赋 0 表示可以写 操作 Initime(5,20,14,18,6,3,10); //设置初始值 //顺序:秒、分、时、日、月、星期、年(只写 00~99) 2010-6-18 14:20:05 周三 WR1302(0x8E,0X80); // 0X8E 是 WP 写保护地址,最高位赋 1 表示写保护, 只能读 WR1302(0x90,0XA7); //0x90 是充电设置地址,0XA7 表示一个二极管串联 一个 8K 电阻 // WR1302(0x90,0XA6); //一个二极管加一个 4K 电阻 // WR1302(0x90,0XA5); //一个二极管加一个 2K 电阻
} void WR1302( uchar addr,uchar Date ) //给某地址写数据 { RST=0; CK=0; RST=1; //CK 为 0 时,RST 才能为 1,然后才能读写 WRdate(addr); //写地址 WRdate(Date); //写数据 CK=1; RST=0; } void Initime(uchar sec,uchar min,uchar hor,uchar day,uchar yue,uchar week,uchar year)
相关文档
最新文档