You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
7.5 KiB
211 lines
7.5 KiB
2 years ago
|
#include "ds1302.h"
|
||
|
#include "main.h"
|
||
|
|
||
|
extern int ds1302_port(void);
|
||
|
|
||
|
struct ds1302 ds1302;
|
||
|
int ds1302_port(void)
|
||
|
{
|
||
|
ds1302_init(&ds1302
|
||
|
, EN_1302_GPIO_Port, SCLK_1302_GPIO_Port, DA_1302_GPIO_Port
|
||
|
, EN_1302_Pin, SCLK_1302_Pin, DA_1302_Pin
|
||
|
);
|
||
|
return 0;
|
||
|
|
||
|
}
|
||
|
|
||
|
void ds1302_delay_us(int us,uint32_t system_clock_mhz)
|
||
|
{
|
||
|
volatile uint32_t con=us*system_clock_mhz/8;
|
||
|
do{
|
||
|
__NOP();
|
||
|
}while(con--);
|
||
|
}
|
||
|
struct ds1302* ds1302_init(struct ds1302 *ds1302,GPIO_TypeDef *gpio_ce,GPIO_TypeDef *gpio_sclk,GPIO_TypeDef *gpio_io,uint16_t pin_ce,uint16_t pin_sclk,uint16_t pin_io)
|
||
|
{
|
||
|
if(ds1302==NULL || gpio_ce==NULL || gpio_io==NULL || gpio_sclk==NULL){
|
||
|
return NULL;
|
||
|
}
|
||
|
ds1302->gpio_ce=gpio_ce;
|
||
|
ds1302->gpio_io=gpio_io;
|
||
|
ds1302->gpio_sclk=gpio_sclk;
|
||
|
ds1302->pin_ce=pin_ce;
|
||
|
ds1302->pin_io=pin_io;
|
||
|
ds1302->pin_sclk=pin_sclk;
|
||
|
return ds1302;
|
||
|
}
|
||
|
int ds1302_write_bytes(struct ds1302 *ds1302,uint8_t cmd,uint8_t addr,const uint8_t *bytes,uint8_t num)
|
||
|
{
|
||
|
int i,j;
|
||
|
uint8_t tmp;
|
||
|
if(ds1302==NULL || bytes==NULL || num==0){
|
||
|
return -1;
|
||
|
}
|
||
|
GPIO_WriteBit(ds1302->gpio_ce,ds1302->pin_ce,Bit_SET);
|
||
|
tmp=cmd|addr<<1|DS1302_CMD_WRITE_MASK;
|
||
|
for(j=0;j<8;j++){
|
||
|
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,tmp&1);
|
||
|
ds1302_delay_us(1,168);
|
||
|
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_SET);
|
||
|
ds1302_delay_us(1,168);
|
||
|
tmp>>=1;
|
||
|
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_RESET);
|
||
|
}
|
||
|
for(i=0;i<num;i++){
|
||
|
tmp=bytes[i];
|
||
|
for(j=0;j<8;j++){
|
||
|
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,tmp&1);
|
||
|
ds1302_delay_us(1,168);
|
||
|
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_SET);
|
||
|
ds1302_delay_us(1,168);
|
||
|
tmp>>=1;
|
||
|
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_RESET);
|
||
|
}
|
||
|
}
|
||
|
GPIO_WriteBit(ds1302->gpio_ce,ds1302->pin_ce,Bit_RESET);
|
||
|
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,Bit_SET);
|
||
|
return 0;
|
||
|
}
|
||
|
int ds1302_read_bytes(struct ds1302 *ds1302,uint8_t cmd,uint8_t addr,uint8_t *bytes, uint8_t num)
|
||
|
{
|
||
|
int i,j;
|
||
|
uint8_t tmp;
|
||
|
if(ds1302==NULL || bytes==NULL || num==0){
|
||
|
return -1;
|
||
|
}
|
||
|
GPIO_WriteBit(ds1302->gpio_ce,ds1302->pin_ce,Bit_SET);
|
||
|
tmp=cmd|addr<<1|DS1302_CMD_READ_MASK;
|
||
|
for(j=0;j<8;j++){
|
||
|
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,tmp&1);
|
||
|
ds1302_delay_us(1,168);
|
||
|
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_SET);
|
||
|
ds1302_delay_us(1,168);
|
||
|
tmp>>=1;
|
||
|
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_RESET);
|
||
|
}
|
||
|
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,Bit_SET);
|
||
|
for(i=0;i<num;i++){
|
||
|
tmp=0;
|
||
|
for(j=0;j<8;j++){
|
||
|
ds1302_delay_us(1,168);
|
||
|
tmp|=GPIO_ReadInputDataBit(ds1302->gpio_io,ds1302->pin_io)<<j;
|
||
|
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_SET);
|
||
|
ds1302_delay_us(1,168);
|
||
|
GPIO_WriteBit(ds1302->gpio_sclk,ds1302->pin_sclk,Bit_RESET);
|
||
|
}
|
||
|
bytes[i]=tmp;
|
||
|
}
|
||
|
GPIO_WriteBit(ds1302->gpio_ce,ds1302->pin_ce,Bit_RESET);
|
||
|
GPIO_WriteBit(ds1302->gpio_io,ds1302->pin_io,Bit_SET);
|
||
|
return 0;
|
||
|
}
|
||
|
int ds1302_write_enable(struct ds1302 *ds1302)
|
||
|
{
|
||
|
uint8_t data=0x00;
|
||
|
return ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_CONTROL,&data,1);
|
||
|
}
|
||
|
int ds1302_write_disable(struct ds1302 *ds1302)
|
||
|
{
|
||
|
uint8_t data=0x80;
|
||
|
return ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_CONTROL,&data,1);
|
||
|
}
|
||
|
uint64_t ds1302_get_time_s(struct ds1302 *ds1302)
|
||
|
{
|
||
|
uint8_t time_bcd[8];
|
||
|
struct time_clock_date date;
|
||
|
if(ds1302_read_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_ALL,time_bcd,8)!=0){
|
||
|
return 0;
|
||
|
}
|
||
|
if((time_bcd[DS1302_REG_ADDR_SECONDS]&DS1302_REG_SECONDS_CH_MASK)!=0){
|
||
|
return 0;
|
||
|
}
|
||
|
date.sec=(time_bcd[DS1302_REG_ADDR_SECONDS]>>4)*10+(time_bcd[DS1302_REG_ADDR_SECONDS]&0x0f);
|
||
|
date.min=(time_bcd[DS1302_REG_ADDR_MINUTES]>>4)*10+(time_bcd[DS1302_REG_ADDR_MINUTES]&0x0f);
|
||
|
if((time_bcd[DS1302_REG_ADDR_HOUR]&DS1302_REG_HOUR_12_N24_MASK)!=0){
|
||
|
date.hour=((time_bcd[DS1302_REG_ADDR_HOUR]>>4)&1)*10+(time_bcd[DS1302_REG_ADDR_HOUR]&0x0f);
|
||
|
if(date.hour==12){
|
||
|
date.hour-=12;
|
||
|
}
|
||
|
date.hour+=((time_bcd[DS1302_REG_ADDR_HOUR]>>5)&1)*12;
|
||
|
}
|
||
|
else{
|
||
|
date.hour=(time_bcd[DS1302_REG_ADDR_HOUR]>>4)*10+(time_bcd[DS1302_REG_ADDR_HOUR]&0x0f);
|
||
|
}
|
||
|
date.mday=(time_bcd[DS1302_REG_ADDR_DATE]>>4)*10+(time_bcd[DS1302_REG_ADDR_DATE]&0x0f);
|
||
|
date.mon=(time_bcd[DS1302_REG_ADDR_MONTH]>>4)*10+(time_bcd[DS1302_REG_ADDR_MONTH]&0x0f);
|
||
|
date.wday=0;
|
||
|
date.year=(time_bcd[DS1302_REG_ADDR_YEAR]>>4)*10+(time_bcd[DS1302_REG_ADDR_YEAR]&0x0f)+2000;
|
||
|
return time_clock_date_to_time(&date,8);
|
||
|
}
|
||
|
int ds1302_set_time_s(struct ds1302 *ds1302,uint64_t time_s)
|
||
|
{
|
||
|
int ret;
|
||
|
uint8_t time_bcd[8];
|
||
|
struct time_clock_date date;
|
||
|
if((ret=ds1302_write_enable(ds1302))!=0){
|
||
|
return ret;
|
||
|
}
|
||
|
time_clock_time_to_date(time_s,&date,8);
|
||
|
time_bcd[DS1302_REG_ADDR_SECONDS]=((date.sec/10)<<4)+(date.sec%10);
|
||
|
time_bcd[DS1302_REG_ADDR_MINUTES]=((date.min/10)<<4)+(date.min%10);
|
||
|
time_bcd[DS1302_REG_ADDR_HOUR]=((date.hour/10)<<4)+(date.hour%10);
|
||
|
time_bcd[DS1302_REG_ADDR_DATE]=((date.mday/10)<<4)+(date.mday%10);
|
||
|
time_bcd[DS1302_REG_ADDR_MONTH]=((date.mon/10)<<4)+(date.mon%10);
|
||
|
time_bcd[DS1302_REG_ADDR_DAY]=((date.wday/10)<<4)+(date.wday%10)+1;
|
||
|
time_bcd[DS1302_REG_ADDR_YEAR]=(((date.year-2000)/10)<<4)+((date.year-2000)%10);
|
||
|
time_bcd[DS1302_REG_ADDR_CONTROL]=0x80;
|
||
|
ret=ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_ALL,time_bcd,8);
|
||
|
ds1302_write_disable(ds1302);
|
||
|
return ret;
|
||
|
}
|
||
|
int ds1302_read_ram(struct ds1302 *ds1302,uint8_t addr,uint8_t *bytes,uint8_t num)
|
||
|
{
|
||
|
return ds1302_read_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_RAM_MASK,addr,bytes,num);
|
||
|
}
|
||
|
int ds1302_write_ram(struct ds1302 *ds1302,uint8_t addr,uint8_t *bytes,uint8_t num)
|
||
|
{
|
||
|
int ret;
|
||
|
if((ret=ds1302_write_enable(ds1302))!=0){
|
||
|
return ret;
|
||
|
}
|
||
|
ret=ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_RAM_MASK,addr,bytes,num);
|
||
|
ds1302_write_disable(ds1302);
|
||
|
return ret;
|
||
|
}
|
||
|
int ds1302_set_charger(struct ds1302 *ds1302,enum ds1302_trickle_charger_tcs tcs,enum ds1302_trickle_charger_ds ds,enum ds1302_trickle_charger_rs rs)
|
||
|
{
|
||
|
int ret;
|
||
|
uint8_t data=tcs|ds|rs;
|
||
|
if((ret=ds1302_write_enable(ds1302))!=0){
|
||
|
return ret;
|
||
|
}
|
||
|
ret=ds1302_write_bytes(ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_TRICKLE_CHARGER,&data,1);
|
||
|
ds1302_write_disable(ds1302);
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
uint8_t time_bcd[8] ={0};
|
||
|
log_i( "before : %d %d %d %d %d %d %d %d " ,
|
||
|
time_bcd[0] ,time_bcd[1] ,time_bcd[2] ,time_bcd[3],time_bcd[4] ,time_bcd[5] ,time_bcd[6] ,time_bcd[7]);
|
||
|
int a = ds1302_read_bytes(&ds1302,DS1302_CMD_MASK|DS1302_CMD_REG_MASK,DS1302_REG_ADDR_ALL,time_bcd,8);
|
||
|
// ds1302->time_base 保存了 时间戳 秒数 毫秒数
|
||
|
if(a!=0){
|
||
|
log_i("read error %d", a);
|
||
|
}else{
|
||
|
log_i("read ok");
|
||
|
|
||
|
}
|
||
|
// 修改 ds1302 时间
|
||
|
a = ds1302_set_time_s(&ds1302,1669961325);
|
||
|
log_i("a = %d", a);
|
||
|
|
||
|
uint8_t tmp;
|
||
|
a = ds1302_read_ram(&ds1302,0x00,&tmp,1);
|
||
|
log_i("ds1302_read_ram = %d %d", a, tmp);
|
||
|
|
||
|
log_i( "readout : %d %d %d %d %d %d %d %d " ,
|
||
|
time_bcd[0] ,time_bcd[1] ,time_bcd[2] ,time_bcd[3],time_bcd[4] ,time_bcd[5] ,time_bcd[6] ,time_bcd[7]);
|
||
|
|
||
|
*/
|