基于stm8的IIC协议---DS3231时钟模块读取
一、综述
上一篇协议已经详细解说了iic协议的各个函数,通过上一篇协议,相信大家已经对iic有了一定的认识。这一篇博客,我是利用了IIC协议来实现DS3231传感。刚学习的朋友可以买一块来试手,上手较为简单。
二、具体任务实现步骤
1.硬件上:
接线较为简单,保证传感接地与接上电源,由数据手册可以知道,电源要接3.3v,过大电流会烧坏传感。SDA 与 SCL两个引脚分别接自己定义的
2.软件上:
(1)官方手册
这里给出的数据手册是英文版的,可以自行提取,需要中文版的可以自己去淘宝搜索一下,看一些相关的介绍和去百度找中文资料手册。
链接:https://pan.baidu.com/s/1Oo6o68SoVr7gt8tPZIoQxw 提取码:uzih
(2)器件地址
设备地址可以从数据手册上找到。
#define DS3231_Address 0xD0 //设备地址
(3)寄存器地址
这里的寄存器地址有很多个,但是实际用到的时候,只要任选一个即可。
#define DS3231_Address 0xD0 //设备地址 #define Seconds_Register 0x00 //秒钟寄存器 #define Minutes_Register 0x01 //分钟寄存器 #define Hour_Register 0x02 //小时寄存器 #define Day_Register 0x03 //星期寄存器 #define Date_Register 0x04 //日期寄存器 #define Month_Register 0x05 //月份寄存器(第七位是世纪位) #define Year_Register 0x06 //年份寄存器
三、例程
3.1库函数添加
在进行所有调试之前,首先要确保工程已经添加了库函数,打开STM8S_StdPeriph_Lib,这是一个官方的库文件,下载IAR STM8包的时候就携带,将Libraries文件复制到你工程所在的文件下,并将有关于ADC的库文件添加到你的工程列表当中。添加完成后,就可以开始编写代码了(如果你将全部的库文件都添加进来的话,编译程序后库文件还有红点报错的话,这是因为你选的芯片上没有该功能,你需要将其删掉才能不报错。)如图。
3.2代码部分
clock.c文件的代码:
#include "Clock.h" uint8_t vSen_DS3231_Read_Bytes() { uint8_t uRev_Register_Data = 0x00; //起始信号: Start_Signal_IIC_(); //发送设备地址 Send_Data_IIC_(DS3231_Address); bIIC_ReadACK(); //发送寄存器 Send_Data_IIC_(Hour_Register); //主动相应 vIIC_Ack(); //起始信号: Start_Signal_IIC_(); //发送设备地址 Send_Data_IIC_(DS3231_Address+1); //主动相应 vIIC_Ack(); //读取寄存器地址. uRev_Register_Data=uIIC_RecvByte(); //主动不应答 vIIC_NAck(); //结束信号 End_Data_IIC_(); return uRev_Register_Data; }
uint8_t vSen_DS3231_Write_Bytes(void) { //起始信号: Start_Signal_IIC_(); //发送设备地址 Send_Data_IIC_(DS3231_Address); //判断是否有应答 bIIC_ReadACK(); //4.发送寄存器 Send_Data_IIC_(Hour_Register); //5.等待响应 bIIC_ReadACK(); //6.发送数据到寄存器中 Send_Data_IIC_(0x10); //7.等待应答 bIIC_ReadACK(); //8.结束信号 End_Data_IIC_(); return 1; }
u8 read_Bytes(u8 ReadAddr)
{ uint8_t uRev_Register_Data = 0x00; //起始信号: Start_Signal_IIC_(); //发送设备地址 Send_Data_IIC_(DS3231_Address); bIIC_ReadACK(); //4.发送寄存器 Send_Data_IIC_(ReadAddr); //5.主动相应 vIIC_Ack(); //起始信号: Start_Signal_IIC_(); //发送设备地址 Send_Data_IIC_(DS3231_Address+1); //主动相应 vIIC_Ack(); //读取寄存器地址. uRev_Register_Data=uIIC_RecvByte(); //主动不应答 vIIC_NAck(); //结束信号 End_Data_IIC_(); return uRev_Register_Data; }
void DS3231_WriteByte(u8 WriteAddr,u8 DataToWrite) { Start_Signal_IIC_(); Send_Data_IIC_(DS3231_Address); bIIC_ReadACK(); Send_Data_IIC_(WriteAddr); bIIC_ReadACK(); Send_Data_IIC_(DataToWrite); bIIC_ReadACK(); End_Data_IIC_(); delay_ms(10000); }
//************************modify time********************************************
void ModifyTime(u8 yea,u8 mon,u8 da,u8 hou,u8 min,u8 sec)
{
u8 temp=0;
DS3231_WriteByte(0x06,temp);//修改年
DS3231_WriteByte(0x05,temp);//修改月
DS3231_WriteByte(0x04,temp);//修改日
DS3231_WriteByte(0x02,temp);//修改时
DS3231_WriteByte(0x01,temp);//修改分
DS3231_WriteByte(0x00,temp);//修改秒
}
接下来是iic.c里面的两个函数,iic.c里面的其他函数已经在上一篇贴出来,并且贴出了部分解释。下面两个是B格式与BCD格式的相互转化:
uint8_t Byte_Transform_BCD(uint8_t uData) { uint8_t i, j, uBCD_Code; i = uData / 10; j = uData % 10; uBCD_Code = j + ( i << 4 ); return uBCD_Code; } uint8_t BCD_Transform_Byte(uint8_t uData) { uint8_t uByte_Code; uByte_Code = (uData & 0x0f); uData >>= 4; uData &= 0x0f; uData *= 10; uByte_Code += uData; return uByte_Code; }
3.3结局测试
代码已经po出来了,最后是进行数据测试,最直观的办法是看波形变化,如果接收或者发送不了数据,可以直接通过示波器的波形变化曲线来了解一下。最后数据也可以在串口上看到接收发送的数据。
四、总结
到这里为止,基于iic的DS3231协议就差不多了,重要的代码我已经贴出来给大家借鉴一下,应该是较为通俗易懂的了,最后大家如果有不懂的地方,可以通过评论区指出来,我会订正我的博客的!