📄 ds1302.h
字号:
#include "iom16v.h"
//复位脚
#define RST_CLR PORTC &= ~(1 << PC6)
#define RST_SET PORTC |= (1 << PC6)
#define RST_IN DDRC &= ~(1 << PC6)
#define RST_OUT DDRC |= (1 << PC6)
//双向数据
#define IO_CLR PORTC &= ~(1 << PC1)
#define IO_SET PORTC |= (1 << PC1)
#define IO_R PINC & (1 << PC1)
#define IO_IN DDRC &= ~(1 << PC1)
#define IO_OUT DDRC |= (1 << PC1)
//时钟信号
#define SCK_CLR PORTC &= ~(1 << PC0)
#define SCK_SET PORTC |= (1 << PC0)
#define SCK_IN DDRC &= ~(1 << PC0)
#define SCK_OUT DDRC |= (1 << PC0)
#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
#define ds1302_charger_add 0x90
#define ds1302_clkburst_add 0xbe
//向DS1302写入一字节数据
void ds1302_write_byte(unsigned char addr, unsigned char d) {
unsigned char i;
RST_SET; //启动DS1302总线 RES为1时才可进行读写操作
//写入目标地址:addr
IO_OUT;
addr = addr & 0xFE;//最低位置零 写操作
for (i = 0; i < 8; i ++) {
if (addr & 0x01) {
IO_SET;
}
else {
IO_CLR;
}
SCK_SET; //上升沿将数据写入
SCK_CLR;
addr = addr >> 1;
}
//写入数据
IO_OUT;
for (i = 0; i < 8; i ++) {
if (d & 0x01) {
IO_SET;
}
else {
IO_CLR;
}
SCK_SET; //上升沿将数据写入
SCK_CLR;
d = d >> 1;
}
RST_CLR; //禁止DS1302总线
}
//读出一个字节
unsigned char ds1302_read_byte(unsigned char addr) {
unsigned char i;
unsigned char temp;
RST_SET; //启动DS1302总线
//写入目标地址:addr
IO_OUT;
addr = addr | 0x01; //最低位置高 读操作
for (i = 0; i < 8; i ++) {
if (addr & 0x01) {
IO_SET;
}
else {
IO_CLR;
}
SCK_SET;
SCK_CLR;
addr = addr >> 1;
}
//输出数据
IO_IN;
for (i = 0; i < 8; i ++) { //由低位向高位读数据
temp = temp >> 1;
if (IO_R) { //判断是否为1
temp |= 0x80;
}
else {
temp &= 0x7F;
}
SCK_SET;
SCK_CLR;
}
RST_CLR; //禁止DS1302总线
return temp;
}
//写入时钟数据
void ds1302_write_time(unsigned char *time_data)
{
ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护 此时可以写入数据
ds1302_write_byte(ds1302_sec_add,0x80); //暂停 时钟震荡停止
time_data++; //指针指向年的后两位
//送入数据
ds1302_write_byte(ds1302_year_add,*time_data++); //年份只写入后面两位
ds1302_write_byte(ds1302_month_add,*time_data++); //月
ds1302_write_byte(ds1302_date_add,*time_data++); //日
ds1302_write_byte(ds1302_hr_add,*time_data++); //时
ds1302_write_byte(ds1302_min_add,*time_data++); //分
ds1302_write_byte(ds1302_sec_add,*time_data++); //秒
ds1302_write_byte(ds1302_day_add,*time_data); //周
ds1302_write_byte(ds1302_control_add,0x80); //打开写保护 拒绝写入数据
}
//读出时钟数据
void ds1302_read_time(unsigned char *time_data) {
time_data++;
*time_data=ds1302_read_byte(ds1302_year_add); //只读出后面两位08
time_data++;
*time_data=ds1302_read_byte(ds1302_month_add); //月
time_data++;
*time_data=ds1302_read_byte(ds1302_date_add); //日
time_data++;
*time_data=ds1302_read_byte(ds1302_hr_add); //时
time_data++;
*time_data=ds1302_read_byte(ds1302_min_add); //分
time_data++;
*time_data=(ds1302_read_byte(ds1302_sec_add))&0x7F; //秒
time_data++;
*time_data=ds1302_read_byte(ds1302_day_add); //周
}
//初始化
void ds1302_init(void) {
RST_CLR; //RST为低电平
SCK_CLR; //时钟信号为低电平
RST_OUT; //RST 为输出
SCK_OUT; // SCK为输出
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -