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

  • 相关阅读:
    Android ListView嵌套Button,Button事件覆盖item事件解决办法
    android 再按一次退出程序(实现代码)
    Android 带checkbox的listView 实现多选,全选,反选
    Android调用第三方应用
    Android输入法界面管理(打开/关闭/状态获取)
    ViewPager的使用方法和实现过程
    安装pycharm 2018.3 Professional Edition
    layui和jquery冲突:Syntax error, unrecognized expression: +
    解决因为本地代码和远程代码冲突,导致git pull无法拉取远程代码的问题(转载)
    Object.assign()
  • 原文地址:https://www.cnblogs.com/shasha2019/p/12172456.html
Copyright © 2020-2023  润新知