DS3231模块使用

1.该模块是最近流行的时钟模块,采取IIC和单片机进行通讯,使用方便,且目前已经找到可以使用的程序。
2.注意:该模块的工作电压是3.3V不是5V,昨天在排除所有硬件错误之后,采取3.3V供电,模块才能正常工作,因此使用任何电子元器件之前或者模块之前,一定要先看电气手册
已经成功调通的程序代码如下:
DS3231.c :
#include “DS3231.h”
#include “myiic.h”
#include “delay.h”
#include “sys.h”
_calendar_obj calendar;

#define DS3231_WriteAddress 0xD0
#define DS3231_ReadAddress 0xD1

u8 BCD2HEX(u8 val)
{
u8 i;
i= val&0x0f;
val >>= 4;
val &= 0x0f;
val *= 10;
i += val;

return i;

}

u16 B_BCD(u8 val)
{
u8 i,j,k;
i=val/10;
j=val%10;
k=j+(i<<4);
return k;
}

void I2cByteWrite(u8 addr,u8 bytedata)
{
IIC_Start();
delay_us(5);
IIC_Send_Byte(DS3231_WriteAddress);
IIC_Wait_Ack();
delay_us(5);
IIC_Send_Byte(addr);
IIC_Wait_Ack();
delay_us(5);
IIC_Send_Byte(bytedata);
IIC_Wait_Ack();
delay_us(5);
IIC_Stop();
}

u8 I2cByteRead(u8 addr)
{
u8 Dat=0;

IIC_Start();
IIC_Send_Byte(DS3231_WriteAddress);
IIC_Wait_Ack();
delay_us(5);
IIC_Send_Byte(addr);
IIC_Wait_Ack();
delay_us(5);
IIC_Start();
IIC_Send_Byte(DS3231_ReadAddress);
IIC_Wait_Ack();
delay_us(5);
Dat=IIC_Read_Byte(1);
IIC_Stop();
return Dat;
}

void DS3231_Init(void)
{
IIC_Init();
I2cByteWrite(0x0e,0);
delay_ms(2);
I2cByteWrite(0x0f,0x0);
delay_ms(2);
}
void DS3231_Get(void)
{
calendar.w_year=I2cByteRead(0x06);
calendar.w_month=I2cByteRead(0x05);
calendar.w_date=I2cByteRead(0x04);
calendar.hour=I2cByteRead(0x02);
calendar.min=I2cByteRead(0x01);
calendar.sec=I2cByteRead(0x00);
}

void DS3231_Set(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec)
{
u8 temp=0;

temp=B_BCD(yea);
I2cByteWrite(0x06,temp);

temp=B_BCD(mon);
I2cByteWrite(0x05,temp);

temp=B_BCD(da);
I2cByteWrite(0x04,temp);

temp=B_BCD(hou);
I2cByteWrite(0x02,temp);

temp=B_BCD(min);
I2cByteWrite(0x01,temp);

temp=B_BCD(sec);
I2cByteWrite(0x00,temp);
}

void get_show_time(void)
{

calendar.w_year=I2cByteRead(0x06);
calendar.w_year=BCD2HEX(calendar.w_year);

calendar.w_month=I2cByteRead(0x05);
calendar.w_month=BCD2HEX(calendar.w_month);

calendar.w_date=I2cByteRead(0x04);
calendar.w_date=BCD2HEX(calendar.w_date);

calendar.hour=I2cByteRead(0x02);
calendar.hour&=0x3f;
calendar.hour=BCD2HEX(calendar.hour);

calendar.min=I2cByteRead(0x01);
calendar.min=BCD2HEX(calendar.min);

calendar.sec=I2cByteRead(0x00);
calendar.sec=BCD2HEX(calendar.sec);
}
DS3231.h :
#include “sys.h”
#ifndef DS3231_H
#define DS3231_H

typedef struct
{
u8 hour;
u8 min;
u8 sec;
u32 w_year;
u8 w_month;
u8 w_date;
u8 week;
}_calendar_obj;
extern _calendar_obj calendar; //日历结构体

extern u8 const mon_table[12]; //月份日期数据表

void DS3231_Init(void);
void get_show_time(void);
//u8 RTC_Get_Week(u16 year,u8 month,u8 day);
void DS3231_Set(u8 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec);//设置时间

#endif

由于该模块使用的IIC通讯,因此特将正点原子的官方IIC程序复制:
myiic.c

#include “myiic.h”
#include “delay.h”
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//IIC驱动 代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/9
//版本:V1.0
//版权所有,盗版必究。
//Copyright© 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//

//初始化IIC
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC, ENABLE );

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_SetBits(GPIOC,GPIO_Pin_12|GPIO_Pin_11); 	//PB10,PB11 输出高

}
//产生IIC起始信号
void IIC_Start(void)
{
SDA_OUT(); //sda线输出
IIC_SDA=1;
delay_us(1);
IIC_SCL=1;
delay_us(5);
IIC_SDA=0;//START:when CLK is high,DATA change form high to low
delay_us(5);
IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
delay_us(2);
}
//产生IIC停止信号
void IIC_Stop(void)
{
SDA_OUT();//sda线输出
IIC_SCL=0;
IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
delay_us(4);
IIC_SCL=1;
delay_us(5);
IIC_SDA=1;//发送I2C总线结束信号
delay_us(4);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
u8 IIC_Wait_Ack(void)
{
u8 ucErrTime=0;
SDA_IN(); //SDA设置为输入
IIC_SDA=1;delay_us(1);
IIC_SCL=1;delay_us(1);
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>250)
{
IIC_Stop();
return 1;
}
}
IIC_SCL=0;//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_us(2);
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
}
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
IIC_SCL=0;//拉低时钟开始数据传输
for(t=0;t<8;t++)
{
//IIC_SDA=(txd&0x80)>>7;
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_us(2); //对TEA5767这三个延时都是必须的
IIC_SCL=1;
delay_us(2);
IIC_SCL=0;
delay_us(2);
}
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
u8 IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_us(2);
IIC_SCL=1;
receive<<=1;
if(READ_SDA)receive++;
delay_us(1);
}
if (!ack)
IIC_NAck();//发送nACK
else
IIC_Ack(); //发送ACK
return receive;
}

myiic.h:

#ifndef __MYIIC_H
#define __MYIIC_H
#include “sys.h”
//
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK战舰STM32开发板
//IIC驱动 代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//修改日期:2012/9/9
//版本:V1.0
//版权所有,盗版必究。
//Copyright© 广州市星翼电子科技有限公司 2009-2019
//All rights reserved
//

//IO方向设置
#define SDA_IN() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=8<<12;}
#define SDA_OUT() {GPIOC->CRH&=0XFFFF0FFF;GPIOC->CRH|=3<<12;}

//IO操作函数
#define IIC_SCL PCout(12) //SCL
#define IIC_SDA PCout(11) //SDA
#define READ_SDA PCin(11) //输入SDA

//IIC所有操作函数
void IIC_Init(void); //初始化IIC的IO口
void IIC_Start(void); //发送IIC开始信号
void IIC_Stop(void); //发送IIC停止信号
void IIC_Send_Byte(u8 txd); //IIC发送一个字节
u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 IIC_Wait_Ack(void); //IIC等待ACK信号
void IIC_Ack(void); //IIC发送ACK信号
void IIC_NAck(void); //IIC不发送ACK信号

void IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
u8 IIC_Read_One_Byte(u8 daddr,u8 addr);
#endif

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值