STM32基于HAL工程读取DS1302时间数据
- ✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!
- 对于文中所提供的相关资源链接将作不定期更换。
- 相关篇《STM32基于STM32CubeMX读取/设置DS1307》
- 本工程使用STM32F103VE+DS1302实物验证没有问题。
基于STM32CubeMX配置工程,当然不局限与STM32其他型号的芯片的使用,只要是stm32芯片都可以使用该源文件进行驱动,方便适配移植,减少不必要的重复开发工作。
- 串口打印信息:
STM32CubeMX配置
- 只需配置串口,用于读取DS1302数据输出。
- 当然你也可以在STM32CubeMX先指定DS1302引脚。
- 如果你不想使用系统嘀嗒定时器作为微秒延时函数来时基,可以启用一个定时器。
- 时钟源根据个人具体的STM32型号自己配置。
KEIL工程配置
usart.c
文件中添加printf重映射,并在Keil设置中勾选MicroLib
选项。
#include "stdio.h"
int fputc(int ch,FILE *f)
{
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch , 1 , 1000);
return ch;
}
设置时间到DS1302中
- 创建一个数组存放当前时间,注意数组下标和时间参数对应关系。
uint8_t buf[8]={1,23,4,3,17,34,8,1};
DS1302_WriteTime(buf);
DS1302驱动代码
#ifndef _DS1302_H
#define _DS1302_H
#include "stm32f1xx_hal.h"
#include "dwt_delay.h"
#define DS1302_CLK_Pin GPIO_PIN_7
#define DS1302_IO_Pin GPIO_PIN_6
#define DS1302_RST_Pin GPIO_PIN_4
#define DS1302_GPIO GPIOA
#define DS1302_SCLK DS1302_CLK_Pin
#define DS1302_SDA DS1302_IO_Pin
#define DS1302_RST DS1302_RST_Pin
typedef struct _time
{
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t date;
uint8_t month;
uint8_t week;
uint8_t year;
} DS1302_Time_t;
void DS1302_Init(void);
void DS1302_ReadTime(DS1302_Time_t* time);
void DS1302_WriteTime(uint8_t *buf);
void DS1302_WriteRam(uint8_t addr, uint8_t val);
uint8_t DS1302_ReadRam(uint8_t addr);
void DS1302_ClearRam(void);
void DS1302_ReadTimeBurst(uint8_t * temp);
void DS1302_WriteTimeBurst(uint8_t * buf);
void DS1302_ReadRamBurst(uint8_t len, uint8_t * buf);
void DS1302_WriteRamBurst(uint8_t len, uint8_t * buf);
void DS1302_ClockStart(void);
void DS1302_ClockStop(void);
void DS1302_ClockClear(void);
#endif
#include "DS1302.h"
#define DS1302_SEC 0x80
#define DS1302_MIN 0x82
#define DS1302_HOUR 0x84
#define DS1302_DATE 0x86
#define DS1302_MONTH 0x88
#define DS1302_DAY 0x8A
#define DS1302_YEAR 0x8C
#define DS1302_CONTROL 0x8E
#define DS1302_CHARGER 0x90
#define DS1302_CLKBURST 0xBE
#define DS1302_RAMBURST 0xFE
#define RAMSIZE 0x31
#define DS1302_RAMSTART 0xC0
#define HEX2BCD(v) ((v) % 10 + (v) / 10 * 16)
#define BCD2HEX(v) ((v) % 16 + (v) / 16 * 10)
static void writeSDA(void) {
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = DS1302_SDA;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DS1302_GPIO, &GPIO_InitStructure);
}
static void readSDA(void) {
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = DS1302_SDA;
GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
GPIO_InitStructure.Pull = GPIO_PULLDOWN;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DS1302_GPIO, &GPIO_InitStructure);
}
static void DS1302_SendCmd(uint8_t cmd) {
uint8_t i;
for (i = 0; i < 8; i ++)
{
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, (cmd & 1) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);
delayUS_DWT(1);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);
delayUS_DWT(1);
cmd >>= 1;
}
}
static void DS1302_WriteByte(uint8_t addr, uint8_t d)
{
uint8_t i;
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_SET);
DS1302_SendCmd(addr);
for (i = 0; i < 8; i ++)
{
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, (d & 1) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);
delayUS_DWT(1);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);
delayUS_DWT(1);
d >>= 1;
}
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, GPIO_PIN_RESET);
}
static void DS1302_WriteBurst(uint8_t cmd, uint8_t len, uint8_t * temp)
{
uint8_t i, j;
DS1302_WriteByte(DS1302_CONTROL, 0x00);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_SET);
DS1302_SendCmd(cmd);
for(j = 0; j < len; j++) {
for (i = 0; i < 8; i ++)
{
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, (temp[j] & 1) ? GPIO_PIN_SET : GPIO_PIN_RESET);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);
delayUS_DWT(1);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);
delayUS_DWT(1);
temp[j] >>= 1;
}
}
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, GPIO_PIN_RESET);
DS1302_WriteByte(DS1302_CONTROL, 0x80);
}
static uint8_t DS1302_ReadByte(uint8_t addr)
{
uint8_t i;
uint8_t temp = 0;
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_SET);
addr = addr | 0x01;
DS1302_SendCmd(addr);
readSDA();
for (i = 0; i < 8; i ++)
{
temp >>= 1;
if(HAL_GPIO_ReadPin(DS1302_GPIO, DS1302_SDA))
temp |= 0x80;
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);
delayUS_DWT(1);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);
delayUS_DWT(1);
}
writeSDA();
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, GPIO_PIN_RESET);
return temp;
}
static void DS1302_ReadBurst(uint8_t cmd, uint8_t len, uint8_t * temp)
{
uint8_t i, j;
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_SET);
cmd = cmd | 0x01;
DS1302_SendCmd(cmd);
readSDA();
for (j = 0; j < len; j ++) {
temp[j] = 0;
for (i = 0; i < 8; i ++)
{
temp[j] >>= 1;
if(HAL_GPIO_ReadPin(DS1302_GPIO, DS1302_SDA))
temp[j] |= 0x80;
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);
delayUS_DWT(1);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);
delayUS_DWT(1);
}
}
writeSDA();
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, GPIO_PIN_RESET);
}
void DS1302_WriteTime(uint8_t *buf)
{
DS1302_WriteByte(DS1302_CONTROL, 0x00);
delayUS_DWT(1);
DS1302_WriteByte(DS1302_SEC, 0x80);
DS1302_WriteByte(DS1302_YEAR, HEX2BCD(buf[1]));
DS1302_WriteByte(DS1302_MONTH, HEX2BCD(buf[2]));
DS1302_WriteByte(DS1302_DATE, HEX2BCD(buf[3]));
DS1302_WriteByte(DS1302_HOUR, HEX2BCD(buf[4]));
DS1302_WriteByte(DS1302_MIN, HEX2BCD(buf[5]));
DS1302_WriteByte(DS1302_SEC, HEX2BCD(buf[6]));
DS1302_WriteByte(DS1302_DAY, HEX2BCD(buf[7]));
DS1302_WriteByte(DS1302_CONTROL, 0x80);
delayUS_DWT(1);
}
void DS1302_ReadTime(DS1302_Time_t* time)
{
uint8_t tmp;
tmp = DS1302_ReadByte(DS1302_YEAR);
time->year= BCD2HEX(tmp);
tmp = DS1302_ReadByte(DS1302_MONTH);
time->month = BCD2HEX(tmp);
tmp = DS1302_ReadByte(DS1302_DATE);
time->date = BCD2HEX(tmp);
tmp = DS1302_ReadByte(DS1302_HOUR);
time->hour = BCD2HEX(tmp);
tmp = DS1302_ReadByte(DS1302_MIN);
time->minute = BCD2HEX(tmp);
tmp = DS1302_ReadByte((DS1302_SEC)) & 0x7F;
time->second = BCD2HEX(tmp);
tmp = DS1302_ReadByte(DS1302_DAY);
time->week = BCD2HEX(tmp);
}
void DS1302_Init(void)
{
DWT_Delay_Init();
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = DS1302_SCLK | DS1302_SDA | DS1302_RST;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(DS1302_GPIO, &GPIO_InitStructure);
DS1302_WriteByte(DS1302_CHARGER, 0x00);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);
HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);
delayUS_DWT(10);
DS1302_ClockStart();
}
void DS1302_WriteRam(uint8_t addr, uint8_t val) {
DS1302_WriteByte(DS1302_CONTROL, 0x00);
delayUS_DWT(1);
if (addr >= RAMSIZE) {
return;
}
DS1302_WriteByte(DS1302_RAMSTART + (2 * addr), val);
DS1302_WriteByte(DS1302_CONTROL, 0x80);
delayUS_DWT(1);
}
uint8_t DS1302_ReadRam(uint8_t addr) {
if (addr >= RAMSIZE) {
return 0;
}
return DS1302_ReadByte(DS1302_RAMSTART + (2 * addr));
}
void DS1302_ClearRam(void) {
uint8_t i;
for(i=0; i< RAMSIZE; i++){
DS1302_WriteRam(i, 0x00);
}
}
void DS1302_ReadTimeBurst(uint8_t * buf) {
uint8_t temp[8] = {0, 0, 0, 0, 0, 0, 0, 0};
DS1302_ReadBurst(DS1302_CLKBURST, 8, temp);
buf[1] = BCD2HEX(temp[6]);
buf[2] = BCD2HEX(temp[4]);
buf[3] = BCD2HEX(temp[3]);
buf[4] = BCD2HEX(temp[2]);
buf[5] = BCD2HEX(temp[1]);
buf[6] = BCD2HEX(temp[0]);
buf[7] = BCD2HEX(temp[5]);
buf[0] = temp[7];
}
void DS1302_WriteTimeBurst(uint8_t * buf) {
uint8_t temp[8];
temp[0]=HEX2BCD(buf[6]);
temp[1]=HEX2BCD(buf[5]);
temp[2]=HEX2BCD(buf[4]);
temp[3]=HEX2BCD(buf[3]);
temp[4]=HEX2BCD(buf[2]);
temp[5]=HEX2BCD(buf[7]);
temp[6]=HEX2BCD(buf[1]);
temp[7]=buf[0];
DS1302_WriteBurst(DS1302_CLKBURST, 8, temp);
}
void DS1302_ReadRamBurst(uint8_t len, uint8_t * buf) {
uint8_t i;
if(len <= 0) {
return;
}
if (len > RAMSIZE) {
len = RAMSIZE;
}
for(i = 0; i < len; i++) {
buf[i] = 0;
}
DS1302_ReadBurst(DS1302_RAMBURST, len, buf);
}
void DS1302_WriteRamBurst(uint8_t len, uint8_t * buf) {
if(len <= 0) {
return;
}
if (len > RAMSIZE) {
len = RAMSIZE;
}
DS1302_WriteBurst(DS1302_RAMBURST, len, buf);
}
void DS1302_ClockStart(void)
{
uint8_t buf = 0x00;
DS1302_WriteByte(DS1302_CONTROL, 0x00);
delayUS_DWT(1);
buf = DS1302_ReadByte(DS1302_SEC) & 0x7F;
DS1302_WriteByte(DS1302_SEC, buf);
DS1302_WriteByte(DS1302_CONTROL, 0x80);
delayUS_DWT(1);
}
void DS1302_ClockStop(void)
{
uint8_t buf = 0x00;
DS1302_WriteByte(DS1302_CONTROL, 0x00);
delayUS_DWT(1);
buf = DS1302_ReadByte(DS1302_SEC) | 0x80;
DS1302_WriteByte(DS1302_SEC, buf);
DS1302_WriteByte(DS1302_CONTROL, 0x80);
delayUS_DWT(1);
}
void DS1302_ClockClear(void)
{
DS1302_WriteByte(DS1302_CONTROL, 0x00);
delayUS_DWT(1);
DS1302_WriteByte(DS1302_SEC, 0x80);
DS1302_WriteByte(DS1302_MIN, 0x00);
DS1302_WriteByte(DS1302_HOUR, 0x00);
DS1302_WriteByte(DS1302_DATE, 0x00);
DS1302_WriteByte(DS1302_MONTH, 0x00);
DS1302_WriteByte(DS1302_DAY, 0x00);
DS1302_WriteByte(DS1302_YEAR, 0x00);
DS1302_WriteByte(DS1302_CONTROL, 0x80);
delayUS_DWT(1);
}
uint32_t DWT_Delay_Init(void) {
CoreDebug->DEMCR &= ~CoreDebug_DEMCR_TRCENA_Msk;
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CTRL &= ~DWT_CTRL_CYCCNTENA_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
DWT->CYCCNT = 0;
__ASM volatile ("NOP");
__ASM volatile ("NOP");
__ASM volatile ("NOP");
if(DWT->CYCCNT)
{
return 0;
}
else
{
return 1;
}
}
#ifndef DWT_DELAY_H
#define DWT_DELAY_H
#ifdef __cplusplus
extern "C" {
#endif
#include "stm32f1xx_hal.h"
uint32_t DWT_Delay_Init(void);
__STATIC_INLINE void delayUS_DWT(volatile uint32_t microseconds)
{
uint32_t clk_cycle_start = DWT->CYCCNT;
microseconds *= (HAL_RCC_GetHCLKFreq() / 1000000);
while ((DWT->CYCCNT - clk_cycle_start) < microseconds);
}
#ifdef __cplusplus
}
#endif
#endif
main主程序代码
#include "main.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "stdio.h"
#include "DS1302.h"
void SystemClock_Config(void);
int main(void)
{
DS1302_Time_t time = {0};
const char *WEEK[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM6_Init();
printf("Hello World \r\n");
DWT_Delay_Init();
DS1302_Init();
uint32_t TimerUART = HAL_GetTick();
while (1)
{
if ((HAL_GetTick() - TimerUART) > 1500)
{
DS1302_ReadTime(&time);
printf("Current Time: 20%02d-%02d-%02d %02d:%02d:%02d T=%s \r\n", time.year, time.month, time.date, time.hour, time.minute, time.second, WEEK[time.week]);
TimerUART = HAL_GetTick();
HAL_GPIO_TogglePin(GPIOE, LED_Pin);
}
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
| RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif
工程源码
- ✨申明:本文章仅发表在CSDN网站,任何其他网站,未注明来源,见此内容均为盗链和爬取,请多多尊重和支持原创!
- 对于文中所提供的相关资源链接将作不定期更换。
链接: https:
提取码: m7jc