STM32F103操作DS1302时钟芯片串口显示(标准库和HAL库)

2023-10-30

目录

DS1302的性能指标

DS1302的寄存器及片内RAM

标准库实现

HAL库实现

源码链接


单片机型号:STM32F103C8T6  

        在日常生活中,很多情况下会需要使用时间,单片机中虽然也是有定时器但并不能较为准备的实现计时功能,而且定时计时纯属浪费资源,因此,为了解决此问题,就引入了时钟芯片,时钟芯片能够实现较为精确计时,可实现电子钟/闹钟等功能。

        市面上时钟芯片种类很多,本文选用使用较为广泛的DS1302芯片。        

        DS1302是DALLAS公司推出的涓流充电时钟芯片,内含一个实时时钟/日历和31字节静态RAM,通过简单的串行接口与单片机进行通信。实时时钟/日历电路提供秒、分、时、日、周、月、年的信息,每月的天数和闰年的天数可自动调整。时钟操作可通过AM/PM指示决定采用24或12小时格式。DS1302与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三个口线: (1) RST复位(2) I/O数据线(3)SCLK串行时钟。

        时钟/RAM的读/写数据以一个字节或多达31个字节的字符组方式通信。DS1302工作时功耗很低保持数据和时钟信息时功率小于1mW。

下面是其电路图,通过自己设计也是可以实现的,电路图如下:

如果自己不想设计电路,也可以在网上购买时钟模块,其实就是按照上述电路图设计制成,效果图如下:

接下来简单介绍一下DS1302,网上关于其知识点很多,大家也可以自行学习:

  •  DS1302的性能指标

1)可以计算2100年之前的秒、分、时、日、星期、月、年,并且可以调整闰年。
2)内部有31个字节静态RAM,供用户访问
3)串行数据传送方式(SPI3线接口)
4)工作电压:2.0~5.5v
5) 工作电流:2v时,小于300nA(功耗低)
6)时钟或RAM数据的读写,有两种传送方式:单字节传送、多字节传送
7)主电源和负电源双电源供电(备份电源可以用电池或大电容实现)

  • DS1302的寄存器及片内RAM

DS1302内部包括1个控制寄存器,12个寄存器(7个与日历、时钟相关,存放的数据是BCD码形式)和31个RAM
1)控制寄存器
用于存放ds1302的控制命令字,DS1302的复位引脚回到高电平后写入的第一个字就是控制命令,控制着ds1302的读写过程

D7 D6 D5 D4 D3 D2 D1 D0
1 RAM/CK A4 A3 A2 A1 A0 RD/W
  • 其中:
  • D7:固定为1
  • D6:RAM/CK位,=1片内RAM,=0日历、时钟寄存器选择位。
  • D5-D1:地址位,用于选择进行读写的日历、时钟寄存器或片内RAM。对日历、时钟寄存器或片内RAM的选择。
  • D0:读写选择,=0写,=1读

 寄存器0:最高位 CH 是一个时钟停止标志位。如果时钟电路有备用电源,上电后,我们要先检测一下这一位,如果这一位是0,那说明时钟芯片在系统掉电后,由于备用电源的供给,时钟是持续正常运行的;如果这一位是1,那么说明时钟芯片在系统掉电后,时钟部分不工作了。如果 Vcc1 悬空或者是电池没电了,当我们下次重新上电时,读取这一位,那这一位就是1,我们可以通过这一位判断时钟在单片机系统掉电后是否还正常运行。剩下的7位高3位是秒的十位,低4位是秒的个位,这里再提请注意一次,DS1302 内部是 BCD 码,而秒的十位最大是5,所以3个二进制位就够了。

寄存器1:最高位未使用,剩下的7位中高3位是分钟的十位,低4位是分钟的个位。

寄存器2:bit7 是1的话代表是12小时制,0代表是24小时制;bit6 固定是0,bit5 在12小时制下 0代表的是上午,1代表的是下午,在24小时制下和 bit4 一起代表了小时的十位,低4位代表的是小时的个位。

寄存器3:高2位固定是0,bit5 和 bit4 是日期的十位,低4位是日期的个位。

寄存器4:高3位固定是0,bit4 是月的十位,低4位是月的个位。

寄存器5:高5位固定是0,低3位代表了星期。

寄存器6:高4位代表了年的十位,低4位代表了年的个位。请特别注意,这里的00~99指的是2000年~2099年。

寄存器7:最高位一个写保护位,如果这一位是1,那么是禁止给任何其它寄存器或者那31个字节的 RAM 写数据的。因此在写数据之前,这一位必须先写成0。
 

接下来是代码实现:

接线表设计:

时钟模块 STM32F103
VCC 5V/3.3V
GND GND
CLK PA0
DATA PA1
RST PA2
- PA9(串口1)
- PA10(串口1)

标准库实现:

DS1302.c

#include "ds1302.h"
#include "delay.h"

u8 read_time[7];

struct TIMEData TimeData;
char DS1302_data_1[10];
char DS1302_data_2[8];


 /*
  * SCLK 和 CE初始化
  */
void ds1302_gpio_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);	//
	GPIO_ResetBits(GPIOA,GPIO_Pin_2); 

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; 
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_Init(GPIOA, &GPIO_InitStructure);	//
	GPIO_ResetBits(GPIOA,GPIO_Pin_0); 
}

 /*
  * 数据端口输出配置
  */
void ds1302_DATAOUT_init()//配置双向I/O端口为输出态
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // DATA
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOA,&GPIO_InitStructure);			// 初始化
	GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}
 
 /*
  * 数据端口输入配置
  */
void ds1302_DATAINPUT_init()//配置双向I/O端口为输入态
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA.1 DATA
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.1
}
 
/*
 * /向DS1302发送一字节数据
 */
void ds1302_write_onebyte(uint8_t data)//向DS1302发送一字节数据
{
	uint8_t count=0;
	ds1302_DATAOUT_init(); // I/O配置为输出 
	SCLK_L; // 拉低时钟
	for(count=0;count<8;count++)
	{	
		SCLK_L; // 拉低时钟
		if(data&0x01)
		{
			DATA_H;
		}
		else
		{
			DATA_L;
		}//先准备好数据再发送
		SCLK_H; //拉高时钟线,发送数据
		data>>=1; 
	}
}

/*
 * 向DS1302发送指定数据
 */
void ds1302_wirte_rig(uint8_t address,uint8_t data)//向指定寄存器地址发送数据
{
	uint8_t temp1=address;
	uint8_t temp2=data;
	
	CE_L; // 拉低CE
	SCLK_L; // 拉低SCLK
	delay_us(1);
	CE_H; // 拉高CE
	delay_us(2);
	ds1302_write_onebyte(temp1); // 写命令
	ds1302_write_onebyte(temp2); // 写数据
	
	CE_L; // 拉低CE
	SCLK_L; // 拉低时钟
	delay_us(2);
}

/*
 * 从DS1302读取数据
 */
uint8_t ds1302_read_rig(uint8_t address)//从指定地址读取一字节数据
{
	uint8_t temp3=address;
	uint8_t count=0;
	uint8_t return_data=0x00;
	
	CE_L; // 拉低CE
	SCLK_L; // 拉低SCLK
	delay_us(3);
	CE_H; // 拉高CE
	delay_us(3);
	
	ds1302_write_onebyte(temp3); // 写地址
	
	ds1302_DATAINPUT_init();//配置I/O口为输入

	for(count=0;count<8;count++)
	{
		delay_us(2);//使电平持续一段时间
		return_data>>=1;
		SCLK_H;
		delay_us(4);//使高电平持续一段时间
		SCLK_L;
		delay_us(14);//延时14us后再去读取电压,更加准确
		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1))
		{return_data=return_data|0x80;}
	}
	delay_us(2);
	CE_L; // 拉低CE
	DATA_L; // 拉低SCLK
	
	return return_data; // 返回数据
}

/*
 * 初始化DS1302
 */
void ds1302_init()
{
	ds1302_wirte_rig(0x8e,0x00);//关闭写保护
	ds1302_wirte_rig(0x80,0x37);//seconds37秒
	ds1302_wirte_rig(0x82,0x58);//minutes58分
	ds1302_wirte_rig(0x84,0x23);//hours23时
	ds1302_wirte_rig(0x86,0x30);//date30日
	ds1302_wirte_rig(0x88,0x09);//months9月
	ds1302_wirte_rig(0x8a,0x07);//days星期日
	ds1302_wirte_rig(0x8c,0x20);//year2020年
	
	//ds1302_wirte_rig(0x80,0x19);
	
	ds1302_wirte_rig(0x8e,0x80);//关闭写保护
	
}

/*
 * 读取DS1302数据
 */
void ds1302_read_time(void)
{
	read_time[0]=ds1302_read_rig(0x81);//读秒
	read_time[1]=ds1302_read_rig(0x83);//读分
	read_time[2]=ds1302_read_rig(0x85);//读时
	read_time[3]=ds1302_read_rig(0x87);//读日
	read_time[4]=ds1302_read_rig(0x89);//读月
	read_time[5]=ds1302_read_rig(0x8B);//读星期
	read_time[6]=ds1302_read_rig(0x8D);//读年
}

void ds1302_read_realTime(void)
{
	ds1302_read_time();  //BCD码转换为10进制
	TimeData.second=(read_time[0]>>4)*10+(read_time[0]&0x0f);
	TimeData.minute=((read_time[1]>>4)&(0x07))*10+(read_time[1]&0x0f);
	TimeData.hour=(read_time[2]>>4)*10+(read_time[2]&0x0f);
	TimeData.day=(read_time[3]>>4)*10+(read_time[3]&0x0f);
	TimeData.month=(read_time[4]>>4)*10+(read_time[4]&0x0f);
	TimeData.week=read_time[5];
	TimeData.year=(read_time[6]>>4)*10+(read_time[6]&0x0f)+2000;
	DS1302_data_1[0]='2';
	DS1302_data_1[1]='0';
	DS1302_data_1[2]='0'+(TimeData.year-2000)/10;
	DS1302_data_1[3]='0'+(TimeData.year-2000)%10;
	DS1302_data_1[4]='-';
	DS1302_data_1[5]='0'+TimeData.month/10;
	DS1302_data_1[6]='0'+TimeData.month%10;
	DS1302_data_1[7]='-';
	DS1302_data_1[8]='0'+TimeData.day/10;
	DS1302_data_1[9]='0'+TimeData.day%10;
	
	DS1302_data_2[0]='0'+TimeData.hour/10;
	DS1302_data_2[1]='0'+TimeData.hour%10;
	DS1302_data_2[2]=':';
	DS1302_data_2[3]='0'+TimeData.minute/10;
	DS1302_data_2[4]='0'+TimeData.minute%10;
	DS1302_data_2[5]=':';
	DS1302_data_2[6]='0'+TimeData.second/10;
	DS1302_data_2[7]='0'+TimeData.second%10;
}

main.c

/**
  ******************************************************************************
  * @file    Project/STM32F10x_StdPeriph_Template/main.c 
  * @author  MCD Application Team
  * @version V3.5.0
  * @date    08-April-2011
  * @brief   Main program body
  ******************************************************************************
  * @attention
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
  ******************************************************************************
  */  

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "delay.h"
#include "usart.h"
#include "stdio.h"
#include "string.h"
#include "ds1302.h"
/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
	int i = 0;							//	循环变量
	char str[10] ="";				//	字符数组 
	char str2[100] ="";				//	字符数组 
	char str3[10] ="";				//	字符数组 
	char str4[100] ="";				//	字符数组 
	delay_init();						//	延时函数初始化
	uart_init(9600);				//	串口1函数初始化
	
	ds1302_gpio_init();//CE,SCLK端口初始化
	ds1302_init();
	
	
  /* Infinite loop 	*/
  while (1)
  {
		
		ds1302_read_realTime();
		delay_ms(10);
		for(i = 0;i < 10;i++)
		{
			sprintf(str3,"%c",DS1302_data_1[i]); 
			strcat(str4,str3); 
		}
		strcat(str4,"\r\n"); 
		
		for(i=0;i<strlen(str4);i++)
		{
			USART_SendData(USART1,str4[i]);
			delay_ms(20);
		}

		ds1302_read_realTime();
		delay_ms(10);
		for(i = 0;i < 8;i++)
		{
			sprintf(str,"%c",DS1302_data_2[i]); 
			strcat(str2,str); 
		}
		strcat(str2,"\r\n"); 
		
		for(i=0;i<strlen(str2);i++)
		{
			USART_SendData(USART1,str2[i]);
			delay_ms(20);
		}
		
		delay_ms(200); 
		
		memset(str2,0,sizeof(str2)); 
		memset(str4,0,sizeof(str4)); 
		
  }
}


/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/

实现效果:

HAL库实现:

ds1302.c

#include "main.h"
#include "ds1302.h"


uint8_t read_time[7];

struct TIMEData TimeData;
char DS1302_data_1[10];
char DS1302_data_2[8];


void ds1302_DATAOUT_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA,DATA_Pin, GPIO_PIN_RESET);
	
	/*Configure GPIO pin : DATA_Pin */
  GPIO_InitStruct.Pin = DATA_Pin;   
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(DATA_GPIO_Port, &GPIO_InitStruct);
}

void ds1302_DATAINPUT_init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOA_CLK_ENABLE();

	 /*Configure GPIO pin : PA2 */
  GPIO_InitStruct.Pin = DATA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(DATA_GPIO_Port, &GPIO_InitStruct);
}


/*
 * /向DS1302发送一字节数据
 */
void ds1302_write_onebyte(uint8_t data)//向DS1302发送一字节数据
{
	uint8_t count=0;
	ds1302_DATAOUT_init(); // I/O配置为输出 
	
	HAL_GPIO_WritePin(GPIOA,CLK_Pin, GPIO_PIN_RESET);// 拉低时钟
	
	for(count=0;count<8;count++)
	{	
		HAL_GPIO_WritePin(GPIOA,CLK_Pin, GPIO_PIN_RESET);// 拉低时钟
		if(data&0x01)
		{
			HAL_GPIO_WritePin(GPIOA,DATA_Pin, GPIO_PIN_SET);
		}
		else
		{
			HAL_GPIO_WritePin(GPIOA,DATA_Pin, GPIO_PIN_RESET);
		}//先准备好数据再发送
		HAL_GPIO_WritePin(GPIOA,CLK_Pin, GPIO_PIN_SET); //拉高时钟线,发送数据
		data>>=1; 
	}
}

/*
 * 向DS1302发送指定数据
 */
void ds1302_wirte_rig(uint8_t address,uint8_t data)//向指定寄存器地址发送数据
{
	uint8_t temp1=address;
	uint8_t temp2=data;
	
	
	HAL_GPIO_WritePin(GPIOA,RST_Pin, GPIO_PIN_RESET); // 拉低RST
	
	HAL_GPIO_WritePin(GPIOA,CLK_Pin, GPIO_PIN_RESET);// 拉低时钟
	delay_us(1);
	HAL_GPIO_WritePin(GPIOA,RST_Pin, GPIO_PIN_SET); // 拉高RST
	delay_us(2);
	ds1302_write_onebyte(temp1); // 写命令
	ds1302_write_onebyte(temp2); // 写数据
	
	HAL_GPIO_WritePin(GPIOA,RST_Pin, GPIO_PIN_RESET); // 拉低RST
	HAL_GPIO_WritePin(GPIOA,CLK_Pin, GPIO_PIN_RESET);// 拉低时钟
	delay_us(2);
}

/*
 * 从DS1302读取数据
 */
uint8_t ds1302_read_rig(uint8_t address)//从指定地址读取一字节数据
{
	uint8_t temp3=address;
	uint8_t count=0;
	uint8_t return_data=0x00;
	
	HAL_GPIO_WritePin(GPIOA,RST_Pin, GPIO_PIN_RESET); // 拉低RST
	HAL_GPIO_WritePin(GPIOA,CLK_Pin, GPIO_PIN_RESET);// 拉低时钟
	delay_us(3);
	HAL_GPIO_WritePin(GPIOA,RST_Pin, GPIO_PIN_SET); // 拉高RST
	delay_us(3);
	
	ds1302_write_onebyte(temp3); // 写地址
	
	ds1302_DATAINPUT_init();//配置I/O口为输入

	for(count=0;count<8;count++)
	{
		delay_us(2);//使电平持续一段时间
		return_data>>=1;
		HAL_GPIO_WritePin(GPIOA,CLK_Pin, GPIO_PIN_SET);// 拉高时钟
		delay_us(4);//使高电平持续一段时间
		HAL_GPIO_WritePin(GPIOA,CLK_Pin, GPIO_PIN_RESET);// 拉低时钟
		delay_us(14);//延时14us后再去读取电压,更加准确
		if(HAL_GPIO_ReadPin(GPIOA,DATA_Pin)) 
		{return_data=return_data|0x80;}
	}
	delay_us(2);
	HAL_GPIO_WritePin(GPIOA,RST_Pin, GPIO_PIN_RESET); // 拉低RST
	HAL_GPIO_WritePin(GPIOA,DATA_Pin, GPIO_PIN_RESET);	//	DATA拉低
	
	return return_data; // 返回数据
}

/*
 * 初始化DS1302
注意,写的时候D0配置为0
写入时
秒:1000 0000即0x80
分:1000 0010即0x82
时:1000 0100即0x84
日:1000 0110即0x86
月:1000 1000即0x88
周:1000 1010即0x8a
年:1000 1100即0x8c
 */
void ds1302_init()
{
	ds1302_wirte_rig(0x8e,0x00);//关闭写保护
	ds1302_wirte_rig(0x80,0x37);//seconds37秒
	ds1302_wirte_rig(0x82,0x58);//minutes58分
	ds1302_wirte_rig(0x84,0x23);//hours23时
	ds1302_wirte_rig(0x86,0x30);//date30日
	ds1302_wirte_rig(0x88,0x09);//months9月
	ds1302_wirte_rig(0x8a,0x07);//days星期日
	ds1302_wirte_rig(0x8c,0x20);//year2020年
	
	//ds1302_wirte_rig(0x80,0x19);
	
	ds1302_wirte_rig(0x8e,0x80);//关闭写保护
	
}

/*
 * 读取DS1302数据
注意,读的时候D0配置为1
读取时
秒:1000 0001即0x81
分:1000 0011即0x83
时:1000 0101即0x85
日:1000 0111即0x87
月:1000 1001即0x89
周:1000 1011即0x8b
年:1000 1101即0x8d
 */
void ds1302_read_time(void)
{
	read_time[0]=ds1302_read_rig(0x81);//读秒
	read_time[1]=ds1302_read_rig(0x83);//读分
	read_time[2]=ds1302_read_rig(0x85);//读时
	read_time[3]=ds1302_read_rig(0x87);//读日
	read_time[4]=ds1302_read_rig(0x89);//读月
	read_time[5]=ds1302_read_rig(0x8B);//读星期
	read_time[6]=ds1302_read_rig(0x8D);//读年
}

void ds1302_read_realTime(void)
{
	ds1302_read_time();  //BCD码转换为10进制
	TimeData.second=(read_time[0]>>4)*10+(read_time[0]&0x0f);
	TimeData.minute=((read_time[1]>>4)&(0x07))*10+(read_time[1]&0x0f);
	TimeData.hour=(read_time[2]>>4)*10+(read_time[2]&0x0f);
	TimeData.day=(read_time[3]>>4)*10+(read_time[3]&0x0f);
	TimeData.month=(read_time[4]>>4)*10+(read_time[4]&0x0f);
	TimeData.week=read_time[5];
	TimeData.year=(read_time[6]>>4)*10+(read_time[6]&0x0f)+2000;
	DS1302_data_1[0]='2';
	DS1302_data_1[1]='0';
	DS1302_data_1[2]='0'+(TimeData.year-2000)/10;
	DS1302_data_1[3]='0'+(TimeData.year-2000)%10;
	DS1302_data_1[4]='-';
	DS1302_data_1[5]='0'+TimeData.month/10;
	DS1302_data_1[6]='0'+TimeData.month%10;
	DS1302_data_1[7]='-';
	DS1302_data_1[8]='0'+TimeData.day/10;
	DS1302_data_1[9]='0'+TimeData.day%10;
	
	DS1302_data_2[0]='0'+TimeData.hour/10;
	DS1302_data_2[1]='0'+TimeData.hour%10;
	DS1302_data_2[2]=':';
	DS1302_data_2[3]='0'+TimeData.minute/10;
	DS1302_data_2[4]='0'+TimeData.minute%10;
	DS1302_data_2[5]=':';
	DS1302_data_2[6]='0'+TimeData.second/10;
	DS1302_data_2[7]='0'+TimeData.second%10;
}

main.c中mian函数

int main(void)
{
  /* USER CODE BEGIN 1 */
	char str[100] ="";				//	字符数组 
	char str2[100] ="";				//	字符数组 
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */
	
  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
	ds1302_init();		//	
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	
		ds1302_read_realTime();
		HAL_Delay(10);
		strcat(str,DS1302_data_2); 
		strcat(str,"\r\n");
		strcat(str2,DS1302_data_1); 
		strcat(str2,"\r\n");
		while(HAL_OK != HAL_UART_Transmit(&huart1,(unsigned char *)str2,strlen(str2), 500));
		while(HAL_OK != HAL_UART_Transmit(&huart1,(unsigned char *)str,strlen(str), 500));

		
		HAL_Delay(500); 
		memset(str,0,sizeof(str));
		memset(str2,0,sizeof(str2));
	
  }
  /* USER CODE END 3 */
}

 效果如下:

以上是将数据读取出来,然后通过串口发送出来,这样便于大家移植,祝大家学习愉快,还要沟通交流!!!

源码链接:

STM32F103操作DS1302时钟芯片串口显示(标准库和HAL库)-C文档类资源-CSDN文库

吾芯电子工作室

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STM32F103操作DS1302时钟芯片串口显示(标准库和HAL库) 的相关文章

  • Markdown语法之数学公式【总结】

    目录 数学运算符号 长空格 分数 角标 上下划线 无穷大 求和符号 累乘符号 余积符号 集合运算 上下位符号 圆括号 省略号 应用 根号 对数 积分 逻辑符号 箭头 三角函数 给公式编号 其他省略号 行列式 矩阵 向量 花括号 上下花括号

随机推荐

  • Linux - 快速进入目录的方法

    Linux 快速进入目录的方法 目录 cd命令技巧 其他常用方法 长目录 回到顶部 cd命令技巧 直接进入用户的home目录 cd 进入上一个目录 cd 进入当前目录的上一层目录 cd 进入当前目录的上两层目录 cd 回到顶部 其他常用方法
  • 汇编语言数据处理长度(X ptr指令解析)

    文章目录 1 通过寄存器名指明要处理的数据的尺寸 2 在没有寄存器名存在的情况下 用操作符 X ptr 指明内存单元的长度 X在汇编指令中可以为byte word或dword 3 其他方法 8086CPU的指令 可以处理两种尺寸的数据 by
  • 有序性保障:X86 CPU内存屏障和JSR内存屏障

    一 X86 CPU内存屏障 sfence 在sfence指令前的写操作当必须在sfence指令后的写操作前完成lfence 在Ifence指令前的读操作当必须在Ifence指令后的读操作前完成mfence 在mfence指令前的读写操作当必
  • 密钥繁多难记难管理?认识高效密钥管理体系

    密钥设置是否只要够安全就能够重复使用 定期修改密钥到底有没有必要 密钥不幸遗失该如何恢复 素未谋面的双方 如何才能安全地进行密钥协商 上一论我们了解到 基于密码学的隐私保护方案 其有效性很大程度上取决于能否有效管理好密钥 这里 我们将进一步
  • Oracle创建临时表

    Oracle临时表 临时表是一种特殊的表 当需要对某一 也可以是多个 表中的一批数据进行反复的操作时 通过为这批数据创建一个临时表 可能会简化操作并且有可能提高效率 语法 CREATE GLOBAL TEMPORARY TABLE 临时表空
  • 【C语言】——调试技巧

    目录 编辑 前言 1 什么是Bug 2 什么是调试 2 1调试的基本步骤 2 2Release与Debug 3 常用快捷键 4 如何写出好的代码 4 1常见的coding技巧 assert const const修饰指针 前言 调试是每个程
  • linux系统下部署python自动化程序并配置Jenkins定时执行

    问题 自动化测试脚本代码咱已经有了 项目地址Python接口自动化框架 那么该如何部署到我们的服务器上 在服务器上定时自动执行呢 思路 首先 我们要统一环境 大家知道 python2和python3的语法和库有很多改动 而大多服务器自带的p
  • spring boot 使用@ConfigurationProperties

    有时候有这样子的情景 我们想把配置文件的信息 读取并自动封装成实体类 这样子 我们在代码里面使用就轻松方便多了 这时候 我们就可以使用 ConfigurationProperties 它可以把同类的配置信息自动封装成实体类 首先在配置文件里
  • XSS之xss-labs-level3

    文章目录 0x01 XSS Labs 0x02 实验工具 0x03 实验环境 0x04 实验步骤 0x05 实验分析 0x06 参考链接 0x01 XSS Labs XSS 跨站脚本攻击 是指恶意攻击者往Web页面里插入恶意Script代码
  • css伪元素实现选中效果【打勾效果】

    css伪元素实现选中效果 item border 1px solid 00a9ff position relative after position absolute content width 0px height 0px top 0px
  • 基于SECS协议开发的简明教程(7)

    接着前面6篇SECS GEM开发教程系列 基于SECS协议开发的简明教程 1 怎么搭建支持SECS工程 基于SECS协议开发的简明教程 2 怎么编辑交换数据的ID 基于SECS协议开发的简明教程 3 怎么收 发控制命令和数据消息 基于SEC
  • FA萤火虫算法求解二元四峰函数的简单例子(python代码)

    这个代码是应付智能优化的课的 代码有些地方有些重复啰嗦 请大家担待 可视化都是自己搞得 好多for循环打印 有些地方完全可以构造函数 大家有需要可以自己改一下 import random import numpy as np import
  • python--支持向量机应用小例

    以下内容笔记出自 跟着迪哥学python数据分析与机器学习实战 外加个人整理添加 仅供个人复习使用 SVM的分类效果 软间隔的作用 复杂算法容易造成过拟合 如何解决 核函数的作用 核函数的作用 可以实现非线性分类 import numpy
  • SpringBoot整合vue-admin-template实现登录

    vue admin template简介 前后端分离开发模式越来越受开发人员的喜爱 开源项目vue admin template 是一个后台前端解决方案 它基于 vue 和 element ui实现 更多详情请阅读vue template
  • java打印模板_怎样做一个word模板,用java调用打印功能

    1 首先新建一个空白文档 并另存为 Normal dotm Word2007及以后版本 Normal dot Word2003 2007版本 2 进行需要的模板设置 对字体 段落 页眉页脚 页面边距等进行设置 3 对字体 段落的设置 在空白
  • JSON格式化异常:JsonMappingException

    使用RestTemplate请求post json接口报错 Caused by org codehaus jackson map JsonMappingException Can not instantiate value of type
  • 【Linux命令详解

    文章标题 简介 一 参数列表 二 使用介绍 1 打包文件和目录 2 解包归档文件 3 压缩归档文件 4 列出归档文件内容 5 排除特定文件 6 保留文件权限和所有权 7 保留时间戳 8 增量备份 9 使用文件列表 10 压缩级别控制 总结
  • html iframe post,iframe实现跨域post请求的技术细节

    在最近的一个项目中 我打算在页面上实现这样一个功能 在网页上画出某种图形 上传到服务器后 返回一个src地址 这个地址可以用来分享到各种社交媒体 这个功能看似非常简单 但要实现它还需要注意各种小的细节 首先说下思路和技术要点 用canvas
  • vue下载所有格式的文件

    vue下载所有格式的文件 vue下载所有格式的文件需要先安装downloadjs插件 downloadjs官网 https github com rndme download 下载插件 npm install downloadjs vue引
  • STM32F103操作DS1302时钟芯片串口显示(标准库和HAL库)

    目录 DS1302的性能指标 DS1302的寄存器及片内RAM 标准库实现 HAL库实现 源码链接 单片机型号 STM32F103C8T6 在日常生活中 很多情况下会需要使用时间 单片机中虽然也是有定时器但并不能较为准备的实现计时功能 而且