ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

STM8驱动RTC芯片DS1302

2022-03-02 17:04:46  阅读:175  来源: 互联网

标签:TimeDisplay STM8 RTC DS1302 uint8 IO TimeBuffer


使用软件:IAR FOR STM8

编程方式:固件库

硬件配套:STM8S105C6T6实验板

目录

1. DS1302.h

  • 引脚定义
  • 函数封装
  • 时间数据结构体定义
  • 数据缓冲区定义
#ifndef __DS1302_H
#define __DS1302_H

/****************************驱动 RTC 芯片 DS1302******************************/

/* Includes ------------------------------------------------------------------*/

#include "stm8s.h"

/* Defines -------------------------------------------------------------------*/

#define RTC_RESET_TIME_EN       0u

#define RTC_SCK_PORT            (GPIOD)         
#define RTC_SCK_PIN             (GPIO_PIN_2)            // PD2
#define RTC_SCK_HIGH()          GPIO_WriteHigh(RTC_SCK_PORT, RTC_SCK_PIN)
#define RTC_SCK_LOW()           GPIO_WriteLow (RTC_SCK_PORT, RTC_SCK_PIN)

#define RTC_IO_PORT             (GPIOD)
#define RTC_IO_PIN              (GPIO_PIN_3)            // PD3

#define RTC_IO_IN()             GPIO_Init(RTC_IO_PORT, RTC_IO_PIN, GPIO_MODE_IN_PU_NO_IT)
#define RTC_IO_STATUS()         GPIO_ReadInputPin(RTC_IO_PORT, RTC_IO_PIN)

#define RTC_IO_OUT()            GPIO_Init(RTC_IO_PORT, RTC_IO_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW) 
#define RTC_IO_HIGH()           GPIO_WriteHigh(RTC_IO_PORT, RTC_IO_PIN)
#define RTC_IO_LOW()            GPIO_WriteLow (RTC_IO_PORT, RTC_IO_PIN)

#define RTC_RST_PORT            (GPIOD)
#define RTC_RST_PIN             (GPIO_PIN_7)            // PD7
#define RTC_RST_HIGH()          GPIO_WriteHigh(RTC_RST_PORT, RTC_RST_PIN)
#define RTC_RST_LOW()           GPIO_WriteLow (RTC_RST_PORT, RTC_RST_PIN)

/* Values --------------------------------------------------------------------*/

typedef struct Time
{
  uint8_t year;         // year       0-99 
  uint8_t month;        // month      01-12
  uint8_t day;          // day        01-28,29,30,31
  uint8_t week;         // week       01-07
  uint8_t hour;         // hour       01-12 or 00-23
  uint8_t minute;       // minute     00-59
  uint8_t second;       // second     00-59
}TimeTypeDef;

static TimeTypeDef TimeBuffer;   // 数据缓冲区(8421-BCD码)

/* Functions -----------------------------------------------------------------*/

void DS1302_Init (void);

static void    DS1302_WriteByte (uint8_t byte);
static uint8_t DS1302_ReadByte  (void);
static void    DS1302_WriteData (uint8_t addr, uint8_t data);
static uint8_t DS1302_ReadData  (uint8_t addr);

TimeTypeDef DS1302_ReadTime  (void);
void        DS1302_WriteTime (TimeTypeDef *TimeDisplay);

static uint8_t DectoBCD (uint8_t num);
static uint8_t BCDtoDec (uint8_t num);

static void DS1302_DLY_ms(uint16_t nCount);
static void DS1302_DLY_us(uint16_t nCount);

#endif /* __DS1302_H */

2. DS1302.c

  • 引脚初始化
  • 数据传输协议实现
  • BCD 码和十进制数互相转换
  • 数据处理
#include "ds1302.h"

/*************************************************************************
                                初始化
--------------------------------------------------------------------------
无参数
--------------------------------------------------------------------------
无返回值
*************************************************************************/
void DS1302_Init (void)
{
  GPIO_Init(RTC_SCK_PORT, RTC_SCK_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW);
  GPIO_Init(RTC_RST_PORT, RTC_RST_PIN, GPIO_MODE_OUT_PP_HIGH_SLOW);
  GPIO_Init(RTC_IO_PORT,  RTC_IO_PIN,  GPIO_MODE_OUT_PP_HIGH_SLOW);
  
  RTC_SCK_LOW();
  RTC_IO_LOW();
  RTC_RST_LOW();
}

/*************************************************************************
                              写一字节数据
--------------------------------------------------------------------------
byte:一字节数据
--------------------------------------------------------------------------
无返回值
*************************************************************************/
static void DS1302_WriteByte (uint8_t byte)
{
  uint8_t i;
  BitStatus bit;
  
  RTC_IO_OUT();         // IO 配置为输出模式
  
  for (i = 0; i < 8; i++)
  {
    RTC_SCK_LOW();
    
    bit = (BitStatus)(byte & 0x01);
    if (bit != RESET)
      RTC_IO_HIGH();
    else
      RTC_IO_LOW();
    
    RTC_SCK_HIGH();
    byte >>= 1;
    
    //DS1302_DLY_ms(1);
  }
}

/*************************************************************************
                              读一字节数据
--------------------------------------------------------------------------
addr:地址
--------------------------------------------------------------------------
返回值:一字节数据
*************************************************************************/
static uint8_t DS1302_ReadByte (void)
{
  uint8_t i;
  uint8_t data = 0;
  BitStatus bit;
  
  RTC_IO_IN();          // IO 配置为输入模式
  
  for (i = 0; i < 8; i++)
  {
    data >>= 1;
    RTC_SCK_LOW();
    
    bit = RTC_IO_STATUS();
    if (bit != RESET)
      data |= 0x80;
    else
      data &= 0x7F;
    
    RTC_SCK_HIGH();
    
    //DS1302_DLY_ms(1);
  }
  
  return data;
}

/*************************************************************************
                      往指定寄存器写入一字节数据
--------------------------------------------------------------------------
addr:地址  data:一字节数据
--------------------------------------------------------------------------
无返回值
*************************************************************************/
static void DS1302_WriteData (uint8_t addr, uint8_t data)
{
  // 数据传输开始
  RTC_RST_LOW();
  RTC_SCK_LOW();
  RTC_RST_HIGH();
  
  DS1302_WriteByte (addr);      // 写入的地址
  DS1302_WriteByte (data);      // 写入的数据
  
  // 数据传输结束
  RTC_RST_LOW();
}

/*************************************************************************
                      在指定寄存器读出一字节数据
--------------------------------------------------------------------------
addr:地址
--------------------------------------------------------------------------
返回值:一字节数据
*************************************************************************/
static uint8_t DS1302_ReadData (uint8_t addr)
{
  uint8_t data;
  
  // 数据传输开始
  RTC_RST_LOW();
  RTC_SCK_LOW();
  RTC_RST_HIGH();
  
  DS1302_WriteByte (addr);      // 要读的地址
  data = DS1302_ReadByte();     // 要读的数据
  
  // 数据传输结束
  RTC_RST_LOW();
  
  return data;
}

/*************************************************************************
                                读时间
--------------------------------------------------------------------------
无参数
--------------------------------------------------------------------------
返回值:时间数据
*************************************************************************/
TimeTypeDef DS1302_ReadTime (void)
{
  TimeTypeDef TimeDisplay;
  
  // 读出来的数据是 BCD 码
  TimeBuffer.year   = DS1302_ReadData (0x8D);  
  TimeBuffer.month  = DS1302_ReadData (0x89);  
  TimeBuffer.day    = DS1302_ReadData (0x87);  
  TimeBuffer.week   = DS1302_ReadData (0x8B);  
  TimeBuffer.hour   = DS1302_ReadData (0x85);  
  TimeBuffer.minute = DS1302_ReadData (0x83);  
  TimeBuffer.second = DS1302_ReadData (0x81);  // bit7 定义为时钟暂停标志(CH)
  
  // BCD 码转换为十进制
  TimeDisplay.year   = BCDtoDec (TimeBuffer.year);
  TimeDisplay.month  = BCDtoDec (TimeBuffer.month);
  TimeDisplay.day    = BCDtoDec (TimeBuffer.day);
  TimeDisplay.week   = BCDtoDec (TimeBuffer.week);
  TimeDisplay.hour   = BCDtoDec (TimeBuffer.hour);
  TimeDisplay.minute = BCDtoDec (TimeBuffer.minute);
  TimeDisplay.second = BCDtoDec (TimeBuffer.second);
  
  return TimeDisplay;
}

/*************************************************************************
                                修改时间
--------------------------------------------------------------------------
*TimeDisplay:要显示的时间(十进制)
--------------------------------------------------------------------------
无返回值
*************************************************************************/
void DS1302_WriteTime (TimeTypeDef *TimeDisplay)
{ 
  // 十进制转换为 BCD 码
  TimeBuffer.year   = DectoBCD (TimeDisplay->year);
  TimeBuffer.month  = DectoBCD (TimeDisplay->month);
  TimeBuffer.day    = DectoBCD (TimeDisplay->day);
  TimeBuffer.week   = DectoBCD (TimeDisplay->week);
  TimeBuffer.hour   = DectoBCD (TimeDisplay->hour);
  TimeBuffer.minute = DectoBCD (TimeDisplay->minute);
  TimeBuffer.second = DectoBCD (TimeDisplay->second);
  
  // 关闭写保护(控制寄存器:8FH、8EH  bit7:保护位)
  DS1302_WriteData (0x8E, 0x00);        
  
  // 写入的数据是 BCD 码
  DS1302_WriteData (0x8C, TimeBuffer.year);   
  DS1302_WriteData (0x88, TimeBuffer.month); 
  DS1302_WriteData (0x86, TimeBuffer.day); 
  DS1302_WriteData (0x8A, TimeBuffer.week); 
  DS1302_WriteData (0x84, TimeBuffer.hour); 
  DS1302_WriteData (0x82, TimeBuffer.minute); 
  DS1302_WriteData (0x80, TimeBuffer.second); // bit7 定义为时钟暂停标志(CH)
  
  // 开启写保护(控制寄存器:8FH、8EH  bit7:保护位)
  DS1302_WriteData (0x8E, 0x80);        
}

/*************************************************************************
                             十进制转BCD码
--------------------------------------------------------------------------
num:十进制数
--------------------------------------------------------------------------
返回值:BCD码
*************************************************************************/
static uint8_t DectoBCD (uint8_t num)
{
  uint8_t result;
  uint8_t temp1, temp2;

  temp1  = (num / 10) << 4;          // 十位 / 10 * 16
  temp2  =  num % 10;                // 个位 % 10
  result = temp1 + temp2;
  
  return result;
}

/*************************************************************************
                             BCD码转十进制
--------------------------------------------------------------------------
num:BCD码
--------------------------------------------------------------------------
返回值:十进制
*************************************************************************/
static uint8_t BCDtoDec (uint8_t num)
{
  uint8_t result;
  uint8_t temp1, temp2;
  
  temp1 = (num >> 4) * 10;         // 十位 / 16 * 10
  temp2 =  num & 0x0F;             // 个位 % 16
  result = temp1 + temp2;
  
  return result;
}

/*************************************************************************
                             软件延时(ms级别)
--------------------------------------------------------------------------
nCount:延时长度
--------------------------------------------------------------------------
无返回值
*************************************************************************/
static void DS1302_DLY_ms(uint16_t nCount)
{
  while(nCount--)
  {
    DS1302_DLY_us(1000);
  }
}

/*************************************************************************
                             软件延时(us级别)
--------------------------------------------------------------------------
nCount:延时长度
--------------------------------------------------------------------------
无返回值
*************************************************************************/
static void DS1302_DLY_us(uint16_t nCount)
{
  nCount *= 2;
  while(--nCount);
}

3. main.c

#include "stm8s.h"
#include "ds1302.h"
#include "uart.h"

void SystemInit_CLK(void);

void main(void)
{
  // 数据显示区(十进制)
  // 初始值:2022.02.25 Fri. 01:59:50
  TimeTypeDef TimeDisplay = {22, 02, 25, 5, 01, 59, 50};  
  uint8_t TimeSecPre;
  
  SystemInit_CLK();
  UART2_Config();
  DS1302_Init();
  
  printf("Init Success!\r\n");
  
#if RTC_RESET_TIME_EN > 0u
  DS1302_WriteTime(&TimeDisplay);
#endif
  
  while (1)
  {
    TimeDisplay = DS1302_ReadTime();
    if (TimeSecPre != TimeDisplay.second)
    {
      TimeSecPre = TimeDisplay.second;
      printf("20%d年%d月%d日 星期%d\r\n", TimeDisplay.year, TimeDisplay.month, TimeDisplay.day, 
             TimeDisplay.week);
      printf("%d时%d分%d秒\r\n", TimeDisplay.hour, TimeDisplay.minute, TimeDisplay.second);
      printf("\r\n");
    }
  }
}

void SystemInit_CLK(void)
{
  CLK_DeInit();
  CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 16MHz
  CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
  CLK_HSICmd(ENABLE);
}


#ifdef USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param file: pointer to the source file name
  * @param line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

在串口打印时间:

image

---EOF---

标签:TimeDisplay,STM8,RTC,DS1302,uint8,IO,TimeBuffer
来源: https://www.cnblogs.com/Mount256/p/15955934.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有