完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
[C] 纯文本查看 复制代码
/******************************************************************************* @ File name --> ds1302.c* @ Author --> By@ Sam Chan* @ Version --> V1.0* @ Date --> 08 - 23 - 2012* @ Brief --> 时钟芯片DS1302驱动** @ Copyright (C) 20*** @ All rights reserved********************************************************************************* File Update* @ Version --> V1.0.1* @ Author --> By@ Sam Chan* @ Date --> 10 - 20 - 2013 * @ Revise --> A、增加对STM32控制的移植支持* @ --> B、增加对内置的RAM操作相关函数* @ --> C、增加检测DS1302是否存在,是否第一次上电检测函数* @ --> D、增加对DS1302内置的锂电池充电寄存器参数设置函数和结构体*******************************************************************************/#include "ds1302.h"/****************************************************************************** 定义变量******************************************************************************/#define Date timeValue.date#define Min TimeValue.minute#define Sec TimeValue.second#define Hour TimeValue.hour#define Week TimeValue.week#define Month TimeValue.month#define Year TimeValue.yearTime_Typedef TimeValue; //定义时间数据指针void Time_Init(){ TimeValue.date=24; TimeValue.hour=6; TimeValue.minute=12; TimeValue.month=5; TimeValue.second=0; TimeValue.week=2; TimeValue.year=16;}Charge_Typedef ChargeValue; //定义充电寄存器/******************************************************************************* Function Name --> GPIO初始化* Description --> none* Input --> none* Output --> none* Reaturn --> none ******************************************************************************/void DS1302_GPIOInit(void){ GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //开启GPIOC外设时钟 /* 初始化GPIOC */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOC, &GPIO_InitStructure);}/******************************************************************************* Function Name --> DS1302写入一个字节数据* Description --> none* Input --> dat:要写入的数据* Output --> none* Reaturn --> none ******************************************************************************/void DS1302_Write_Byte(u8 dat){ u8 i; DS1302_SDA_OUT(); //设置为输出口 for(i=0;i<8;i++) { DS1302_SCL = 0; //时钟线拉低 if(dat & 0x01) DS1302_SDA = 1; //数据线放上数据,先发低位 else DS1302_SDA = 0; dat >>= 1; //数据右移一位 DS1302_SCL = 1; //发送数据,上升沿有效 }}/******************************************************************************* Function Name --> DS1302读出一个字节数据* Description --> none* Input --> none* Output --> none* Reaturn --> 读到的数据 ******************************************************************************/unsigned DS1302_Read_Byte(){ u8 ReData=0x00; u8 i; DS1302_SDA_IN(); //设置为输入口 for(i=0;i<8;i++) { if(DS1302_IN_SDA == 1) { ReData |= 0x80; } //读出一位数据是“1” DS1302_SCL = 0; //时钟线拉低 ReData >>= 1; //数据右移一位,先读取低位,数据补“0” DS1302_SCL = 1; //上升沿读取数据 } return(ReData); //返回读取到的数据}/******************************************************************************* Function Name --> 向DS1302某地址写入数据* Description --> none* Input --> add:要操作的地址* dat:要写入的数据* Output --> none* Reaturn --> none******************************************************************************/void DS1302_Write_Data(u8 add,u8 dat){ DS1302_RST = 0; //复位脚拉低 DS1302_SCL = 0; //时钟线拉低 DS1302_RST = 1; //复位脚拉高 DS1302_Write_Byte(add); //写入要操作地址 DS1302_Write_Byte(dat); //写入数据 //delay_us(5); DS1302_RST = 0; DS1302_SCL = 0;}/******************************************************************************* Function Name --> 从DS1302某地址读取数据* Description --> none* Input --> add:要操作的地址* Output --> none* Reaturn --> 要读取的寄存器的数值******************************************************************************/unsigned DS1302_Read_Data(u8 add){ u8 Temp; DS1302_RST = 1; DS1302_Write_Byte(add); //写入要操作地址 Temp = DS1302_Read_Byte(); //开始读取数据 DS1302_RST = 0; return(Temp); //返回读取到的数据}/******************************************************************************* Function Name --> 主电源对备用电池充电设置* Description --> 如果备用电池接的是可充电的锂电池或者其他可充电电池的时候,* 可以打开DS1302的充电电路,利用主供电对电池进行充电,免的换电池的麻烦* Input --> *CHG_dat:寄存器控制指针* Output --> none* Reaturn --> none******************************************************************************/void DS1302_Charge_Manage(Charge_Typedef* CHG_dat){ u8 CHG_Value; CHG_Value = (CHG_dat->TCSx << 4) | (CHG_dat->DSx << 2) | CHG_dat->RSx; DS1302_WP_Disable(); //取消写保护 DS1302_Write_Data(Trickle_Charger_Address,CHG_Value); DS1302_WP_Enable(); //打开写保护}/******************************************************************************* Function Name --> DS1302内置的RAM读写操作* Description --> none* Input --> *pBuff:读写数据存放区* WRadd:读写起始地址,范围在RAM_Address0 ~ RAM_Address28之间,最后一位地址有其他用途* num:读写字节数据的数量,范围在1 ~ 28之间* RW:读写判断位。0x00为写操作,0x01为读操作* Output --> none* Reaturn --> none******************************************************************************/void DS1302_RAM_WriteRead_Data(u8* pBuff,u8 WRadd,u8 num,u8 RW){ u8 i; if(WRadd == RAM_Address29) return; //要写入数据的RAM地址是最后一个,直接退出 //因为最后一个字节是用来检测DS1302的 if(RW == 0x00) //写数据操作 { for(i = 0;i < num;i++) { DS1302_WP_Disable(); //取消写保护 DS1302_Write_Data(WRadd+(i<<1),pBuff); DS1302_WP_Enable(); //打开写保护 } } else { for(i = 0;i < num;i++) { DS1302_WP_Disable(); //取消写保护 pBuff = DS1302_Read_Data(WRadd+1+(i<<1)); DS1302_WP_Enable(); //打开写保护 } }}/******************************************************************************* Function Name --> 测试设备好坏* Description --> 在DS1302芯片的RAM的最后一个地址写入一个数据并读出来判断* 与上次写入的值相等,不是第一次上电,否则则初始化时间* Input --> none* Output --> none* Reaturn --> 0:设备正常并不是第一次上电* 1:设备错误或者已损坏******************************************************************************/u8 DS1302_Check(void){ u8 test_value; DS1302_WP_Disable(); //取消写保护 test_value = DS1302_Read_Data(RAM_Address29 + 1); //读出最后一个RAM地址里的数据 DS1302_WP_Enable(); //打开写保护 if(test_value == test_data) //判断数据是否对 { return 0; //设备正常,不是第一次上电 } else { return 1; //不是第一次上电或者设备异常 // DS1302_WP_Disable(); //取消写保护// DS1302_Write_Data(RAM_Address29,0x55); //向RAM最后一个地址里写入数据// DS1302_WP_Enable(); //打开写保护// // _nop_();_nop_();// // DS1302_WP_Disable(); //取消写保护// test_value = DS1302_Read_Data(RAM_Address29 + 1); //读出最后一个RAM地址里的数据// DS1302_WP_Enable(); //打开写保护// // if(test_value == test_data) return 0; //设备正常,不是第一次上电 }// return 1; //设备不在线或者已损坏}/******************************************************************************* Function Name --> DS1302初始化* Description --> none* Input --> *Time: 时间结构体指针* Output --> none* Reaturn --> none******************************************************************************/void DS1302_Init(Time_Typedef* Time){ DS1302_RST = 0; DS1302_SCL = 0; DS1302_WP_Disable(); //取消写保护 DS1302_Write_Data(Address_year,(((Time->year)/10)<<4|(Time->year)%10)); //写年数据 delay_us(3); DS1302_Write_Data(Address_week,(((Time->week)/10)<<4|(Time->week)%10)); //写星期数据 delay_us(3); DS1302_Write_Data(Address_month,(((Time->month)/10)<<4|(Time->month)%10));//写月数据 delay_us(3); DS1302_Write_Data(Address_date,(((Time->date)/10)<<4|(Time->date)%10)); //写日数据 delay_us(3); DS1302_Write_Data(Address_hour,(((Time->hour)/10)<<4|(Time->hour)%10)); //写小时数据 delay_us(3); DS1302_Write_Data(Address_minute,(((Time->minute)/10)<<4|(Time->minute)%10)); //写分钟数据 delay_us(3); DS1302_Write_Data(Address_second ,(((Time->second)/10)<<4|(Time->second)%10)); //写秒数据并使时钟运行 delay_us(3); DS1302_WP_Enable(); //打开写保护 DS1302_WP_Disable(); //取消写保护 DS1302_Write_Data(RAM_Address29,test_data); //向RAM最后一个地址里写入数据 DS1302_WP_Enable(); //打开写保护} [mw_shl_code=c,true]#include "led.h"#include "delay.h"#include "sys.h"#include "ds1302.h"#include "usart.h"#define Date TimeValue.date#define Min TimeValue.minute#define Sec TimeValue.second#define Hour TimeValue.hour#define Week TimeValue.week#define Month TimeValue.month#define Year TimeValue.yearint main(){ Time_Typedef TimeValue; delay_init(); LED_Init(); uart_init(115200); DS1302_GPIOInit(); DS1302_Init(&TimeValue); while(1) { Sec=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Min=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Hour=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Date=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Month=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Week=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Year=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); printf("%d年%d月%d日%d:%d:%d 星期%drn",Year,Month,Date,Hour,Min,Sec,Week); delay_ms(300); }} [C] 纯文本查看 复制代码 /******************************************************************************* @ File name --> ds1302.h* @ Author --> By@ Sam Chan* @ Version --> V1.0* @ Date --> 08 - 23 - 2012* @ Brief --> 时钟芯片DS1302驱动** @ Copyright (C) 20*** @ All rights reserved********************************************************************************* File Update* @ Version --> V1.0.1* @ Author --> By@ Sam Chan* @ Date --> 10 - 20 - 2013 * @ Revise --> A、增加对STM32控制的移植支持* @ --> B、增加对内置的RAM操作相关函数* @ --> C、增加检测DS1302是否存在,是否第一次上电检测函数* @ --> D、增加对DS1302内置的锂电池充电寄存器参数设置函数和结构体*******************************************************************************/#ifndef _ds1302_h_ #define _ds1302_h_/****************************************************************************** 外部函数头文件 ******************************************************************************/#include "sys.h"#include "delay.h"/****************************************************************************** 定义接口 所接的IO不一样请修改这里 设置IO的方向请修改这里,对于不是具有准双向IO的MCU******************************************************************************/#define DS1302_SDA_IN() {GPIOC->CRL &= 0xfffff0ff;GPIOC->CRL |= 8<<8;}#define DS1302_SDA_OUT() {GPIOC->CRL &= 0xfffff0ff;GPIOC->CRL |= 0xa<<8;}#define DS1302_RST PCout(0) //RST#define DS1302_SCL PCout(1) //SCL#define DS1302_SDA PCout(2) //SDA#define DS1302_IN_SDA PCin(2) //读取SDA上数据用到/****************************************************************************** 定义时间结构******************************************************************************/typedef struct{ u8 year; //年 u8 month; //月 u8 date; //日 u8 week; //星期 u8 hour; //小时 u8 minute; //分钟 u8 second; //秒钟 }Time_Typedef;extern Time_Typedef TimeValue; //定义时间数据缓存#define test_data 0x55 //此数据用来检测DS1302是否存在于总线上用,可以改用其他值/****************************************************************************** 定义相关命令宏******************************************************************************/#define Clock_Address_Bass 0x80 //基地址#define Address_year (Clock_Address_Bass | 0x0c) //年#define Address_month (Clock_Address_Bass | 0x08) //月#define Address_date (Clock_Address_Bass | 0x06) //日#define Address_week (Clock_Address_Bass | 0x0a) //星期#define Address_hour (Clock_Address_Bass | 0x04) //小时#define Address_minute (Clock_Address_Bass | 0x02) //分钟#define Address_second (Clock_Address_Bass | 0x00) //秒#define Clock_Burst (Clock_Address_Bass | 0x3e) //时钟软复位//写保护寄存器#define Address_WP (Clock_Address_Bass | 0x0e) //写保护#define WP_Enable 0x80 //打开写保护#define WP_Disable 0x00 //关闭写保护/******************************************************************************电源管理寄存器位描述 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 TCS3 TCS2 TCS1 TCS0 DS1 DS0 RS1 RS0 TCSx:充电电流大小选择,值为0xa0时打开充电,其他值时关闭,DS1302默认是关闭的 DSx:设置VCC1和VCC2之间的二极管串联数量,0x01时为串联一只二极管,0x10时为串联两只二极管,0x00或0x11时关闭充电功能 RSx:设置限流电阻大小,0x00为开路并关闭充电功能,0x01为2K,0x10为4K,0x11为8K******************************************************************************///充电管理寄存器结构typedef struct{ u8 TCSx; //充电开关 u8 DSx; //串联二极管 u8 RSx; //限流电阻 }Charge_Typedef;extern Charge_Typedef ChargeValue; //定义充电寄存器//电源管理#define Trickle_Charger_Address (Clock_Address_Bass | 0x10) //管理电源,主电源供电时可以设置给备用电池充电#define Open_Trickle_Charge 0x0a#define Close_Trickle_Charge 0x00 //设置为其他值也可以#define One_Diode 0x01#define Two_Diode 0x10#define None_Diode 0x00 //or 0x11,断开串联并关闭充电功能#define Resistor_For2K 0x01#define Resistor_For4K 0x10#define Resistor_For8K 0x11#define None_Resistor 0x00 //断开串联限流电阻并关闭充电功能//RAM地址#define RAM_Address_Bass 0xc0 //基地址#define RAM_Address0 (RAM_Address_Bass | 0x00) //RAM地址 = 基地址 + 地址偏移量#define RAM_Address1 (RAM_Address_Bass | 0x02)#define RAM_Address2 (RAM_Address_Bass | 0x04)#define RAM_Address3 (RAM_Address_Bass | 0x06)#define RAM_Address4 (RAM_Address_Bass | 0x08)#define RAM_Address5 (RAM_Address_Bass | 0x0a)#define RAM_Address6 (RAM_Address_Bass | 0x0c)#define RAM_Address7 (RAM_Address_Bass | 0x0e)#define RAM_Address8 (RAM_Address_Bass | 0x10)#define RAM_Address9 (RAM_Address_Bass | 0x12)#define RAM_Address10 (RAM_Address_Bass | 0x14)#define RAM_Address11 (RAM_Address_Bass | 0x16)#define RAM_Address12 (RAM_Address_Bass | 0x18)#define RAM_Address13 (RAM_Address_Bass | 0x1a)#define RAM_Address14 (RAM_Address_Bass | 0x1c)#define RAM_Address15 (RAM_Address_Bass | 0x1e)#define RAM_Address16 (RAM_Address_Bass | 0x20)#define RAM_Address17 (RAM_Address_Bass | 0x22)#define RAM_Address18 (RAM_Address_Bass | 0x24)#define RAM_Address19 (RAM_Address_Bass | 0x26)#define RAM_Address20 (RAM_Address_Bass | 0x28)#define RAM_Address21 (RAM_Address_Bass | 0x2a)#define RAM_Address22 (RAM_Address_Bass | 0x2c)#define RAM_Address23 (RAM_Address_Bass | 0x2e)#define RAM_Address24 (RAM_Address_Bass | 0x32)#define RAM_Address25 (RAM_Address_Bass | 0x34)#define RAM_Address26 (RAM_Address_Bass | 0x36)#define RAM_Address27 (RAM_Address_Bass | 0x38)#define RAM_Address28 (RAM_Address_Bass | 0x3a)#define RAM_Address29 (RAM_Address_Bass | 0x3c)#define RAM_BURST (RAM_Address_Bass | 0x3e)//写秒为00并启动时钟#define DS1302_Start_Second() (DS1302_Write_Data(Address_second,0x00))//写保护命令#define DS1302_WP_Enable() (DS1302_Write_Data(Address_WP,WP_Enable)) //打开写保护#define DS1302_WP_Disable() (DS1302_Write_Data(Address_WP,WP_Disable)) //关闭写保护//关闭充电功能,可以直接调用#define DS1302_Disable_Charge() (DS1302_Write_Data(Trickle_Charger_Address,0x00))/****************************************************************************** 外部功能函数******************************************************************************/void DS1302_GPIOInit(void); //GPIO初始化void DS1302_Init(Time_Typedef *Time); //DS1302初始化extern unsigned DS1302_Read_Data(u8 add); //从DS1302某地址读取数据extern void DS1302_Write_Data(u8 add,u8 dat); //向DS1302某地址写入数据extern u8 DS1302_Check(void); //测试设备好坏extern void DS1302_Charge_Manage(Charge_Typedef *CHG_dat); //主电源对备用电池充电设置extern void DS1302_RAM_WriteRead_Data(u8* pBuff,u8 WRadd,u8 num,u8 RW); //DS1302内置的RAM读写操作#endif /* end ds1302.h */[C] 纯文本查看 复制代码 #include "led.h"#include "delay.h"#include "sys.h"#include "ds1302.h"#include "usart.h"#define Date TimeValue.date#define Min TimeValue.minute#define Sec TimeValue.second#define Hour TimeValue.hour#define Week TimeValue.week#define Month TimeValue.month#define Year TimeValue.yearint main(){ Time_Typedef TimeValue; delay_init(); LED_Init(); uart_init(115200); DS1302_GPIOInit(); DS1302_Init(&TimeValue); while(1) { Sec=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Min=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Hour=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Date=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Month=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Week=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); Year=(DS1302_Read_Data(Address_second|0x01)&0x0f+(DS1302_Read_Data(Address_second|0x01)>>4)*10); delay_us(3); printf("%d年%d月%d日%d:%d:%d 星期%drn",Year,Month,Date,Hour,Min,Sec,Week); delay_ms(300); }} 一直拒绝做伸手党 可是实在是没办法了 一直没找到问题到底在哪里出错了 上拉了电阻还是不行 我用了八度空间提供的模板 然后修改了一下ds1302.c的参数 写上main函数 结果实验失败了 求指教自上而下为ds1302.c ds1302.h main |
|
相关推荐
4个回答
|
|
|
|
|
|
请问解决了吗
|
|
|
|
可否分享一下
|
|
|
|
完全支持楼上的,问顶楼的同志,同样的问题。
|
|
|
|
只有小组成员才能发言,加入小组>>
如何使用STM32+nrf24l01架构把有线USB设备无线化?
2523 浏览 7 评论
请问能利用51单片机和nRF24L01模块实现实时语音无线传输吗?
2305 浏览 5 评论
3107 浏览 3 评论
2773 浏览 8 评论
为什么ucosii上移植lwip后系统进入了HardFault_Handler?
2732 浏览 4 评论
请教各位大咖:有没有接收频率32M左右的芯片推荐的?先感谢啦!
564浏览 1评论
819浏览 0评论
918浏览 0评论
583浏览 0评论
397浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-1 18:55 , Processed in 1.231359 second(s), Total 85, Slave 68 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号