基于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协议就差不多了,重要的代码我已经贴出来给大家借鉴一下,应该是较为通俗易懂的了,最后大家如果有不懂的地方,可以通过评论区指出来,我会订正我的博客的!

原文地址:https://www.cnblogs.com/shasha2019/p/12172456.html