使用软件:IAR FOR STM8
编程方式:固件库
硬件配套:STM8S105C6T6实验板
1. DS1302.h
#ifndef __DS1302_H
#define __DS1302_H
#include "stm8s.h"
#define RTC_RESET_TIME_EN 0u
#define RTC_SCK_PORT (GPIOD)
#define RTC_SCK_PIN (GPIO_PIN_2)
#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)
#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)
#define RTC_RST_HIGH() GPIO_WriteHigh(RTC_RST_PORT, RTC_RST_PIN)
#define RTC_RST_LOW() GPIO_WriteLow (RTC_RST_PORT, RTC_RST_PIN)
typedef struct Time
{
uint8_t year;
uint8_t month;
uint8_t day;
uint8_t week;
uint8_t hour;
uint8_t minute;
uint8_t second;
}TimeTypeDef;
static TimeTypeDef TimeBuffer;
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
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();
}
static void DS1302_WriteByte (uint8_t byte)
{
uint8_t i;
BitStatus bit;
RTC_IO_OUT();
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;
}
}
static uint8_t DS1302_ReadByte (void)
{
uint8_t i;
uint8_t data = 0;
BitStatus bit;
RTC_IO_IN();
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();
}
return 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();
}
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;
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);
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;
}
void DS1302_WriteTime (TimeTypeDef *TimeDisplay)
{
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);
DS1302_WriteData (0x8E, 0x00);
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);
DS1302_WriteData (0x8E, 0x80);
}
static uint8_t DectoBCD (uint8_t num)
{
uint8_t result;
uint8_t temp1, temp2;
temp1 = (num / 10) << 4;
temp2 = num % 10;
result = temp1 + temp2;
return result;
}
static uint8_t BCDtoDec (uint8_t num)
{
uint8_t result;
uint8_t temp1, temp2;
temp1 = (num >> 4) * 10;
temp2 = num & 0x0F;
result = temp1 + temp2;
return result;
}
static void DS1302_DLY_ms(uint16_t nCount)
{
while(nCount--)
{
DS1302_DLY_us(1000);
}
}
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)
{
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);
CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);
CLK_HSICmd(ENABLE);
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
while (1)
{
}
}
#endif
在串口打印时间:
|