/*
如何使用:
1.根据所使用的控制器替换头文件 "stm32f3xx_hal.h"。我使用的是STM32F103VC。
2.重新分配与芯片连接的端口和引脚(DS1302_GPIO、DS1302_SCLK、DS1302_SDA、DS1302_RST)。
3.在主函数中执行 DS1302_Init();。
现在就可以使用了。
*/#ifndef_DS1302_H#define_DS1302_H#include"stm32f1xx_hal.h"#include"dwt_delay.h"//----------------------------------------------------------------------------------//将下面列出的端口和引脚根据自己的需求进行重新分配//----------------------------------------------------------------------------------#defineDS1302_CLK_PinGPIO_PIN_7#defineDS1302_IO_PinGPIO_PIN_6#defineDS1302_RST_PinGPIO_PIN_4#defineDS1302_GPIOGPIOA#defineDS1302_SCLKDS1302_CLK_Pin#defineDS1302_SDADS1302_IO_Pin#defineDS1302_RSTDS1302_RST_Pin//存放时间typedefstruct_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;/* 初始化 *//* 配置 STM32 端口,启动微秒定时器,并将时钟从省电模式唤醒 */voidDS1302_Init(void);/* Reads time byte by byte to 'buf' */voidDS1302_ReadTime(DS1302_Time_t* time);/* Writes time byte by byte from 'buf' */voidDS1302_WriteTime(uint8_t*buf);/* Writes 'val' to ram address 'addr' *//* Ram addresses range from 0 to 30 */voidDS1302_WriteRam(uint8_t addr,uint8_t val);/* Чтение из RAM по адресу 'addr' */uint8_tDS1302_ReadRam(uint8_t addr);/* Очистка RAM памяти */voidDS1302_ClearRam(void);/* Reads time in burst mode, includes control byte */voidDS1302_ReadTimeBurst(uint8_t* temp);/* Writes time in burst mode, includes control byte */voidDS1302_WriteTimeBurst(uint8_t* buf);/* Reads ram in burst mode 'len' bytes into 'buf' */voidDS1302_ReadRamBurst(uint8_t len,uint8_t* buf);/* Writes ram in burst mode 'len' bytes from 'buf' */voidDS1302_WriteRamBurst(uint8_t len,uint8_t* buf);//Запуск часов.voidDS1302_ClockStart(void);//Остановка часов.voidDS1302_ClockStop(void);//Сброс часовvoidDS1302_ClockClear(void);#endif//_DS1302_H
🌿DS1302.c文件
#include"DS1302.h"// Регистры DS1302#defineDS1302_SEC0x80#defineDS1302_MIN0x82#defineDS1302_HOUR0x84#defineDS1302_DATE0x86#defineDS1302_MONTH0x88#defineDS1302_DAY0x8A#defineDS1302_YEAR0x8C#defineDS1302_CONTROL0x8E#defineDS1302_CHARGER0x90#defineDS1302_CLKBURST0xBE#defineDS1302_RAMBURST0xFE#defineRAMSIZE0x31// Размер RAM в байтах#defineDS1302_RAMSTART0xC0// Первый адрес RAM#defineHEX2BCD(v)((v)%10+(v)/10*16)#defineBCD2HEX(v)((v)%16+(v)/16*10)// SDA Write(output) ModestaticvoidwriteSDA(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);}// SDA Read(input) ModestaticvoidreadSDA(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);}/* Отправка адреса или команды */staticvoidDS1302_SendCmd(uint8_t cmd){uint8_t i;for(i =0; i <8; i ++){// DS1302_SDA = (bit)(addr & 1);HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA,(cmd &1)? GPIO_PIN_SET : GPIO_PIN_RESET);// DS1302_SCK = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);delayUS_DWT(1);// DS1302_SCK = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);delayUS_DWT(1);
cmd >>=1;}}/* Прочитать байт по адресу 'addr' */staticvoidDS1302_WriteByte(uint8_t addr,uint8_t d){uint8_t i;// DS1302_RST = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_SET);//addr = addr & 0xFE;DS1302_SendCmd(addr);// Отправка адресаfor(i =0; i <8; i ++){// DS1302_SDA = (bit)(d & 1);HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA,(d &1)? GPIO_PIN_SET : GPIO_PIN_RESET);// DS1302_SCK = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);delayUS_DWT(1);// DS1302_SCK = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);delayUS_DWT(1);
d >>=1;}// DS1302_RST = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);// DS1302_SDA = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, GPIO_PIN_RESET);}/* Sends 'cmd' command and writes in burst mode 'len' bytes from 'temp' */staticvoidDS1302_WriteBurst(uint8_t cmd,uint8_t len,uint8_t* temp){uint8_t i, j;DS1302_WriteByte(DS1302_CONTROL,0x00);// Отключить защиту от записи// DS1302_RST = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_SET);DS1302_SendCmd(cmd);// Sends burst write commandfor(j =0; j < len; j++){for(i =0; i <8; i ++){// DS1302_SDA = (bit)(d & 1);HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA,(temp[j]&1)? GPIO_PIN_SET : GPIO_PIN_RESET);// DS1302_SCK = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);delayUS_DWT(1);// DS1302_SCK = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);delayUS_DWT(1);
temp[j]>>=1;}}// DS1302_RST = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);// DS1302_SDA = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, GPIO_PIN_RESET);DS1302_WriteByte(DS1302_CONTROL,0x80);// Включить защиту от записи}/* Reads a byte from addr */staticuint8_tDS1302_ReadByte(uint8_t addr){uint8_t i;uint8_t temp =0;// DS1302_RST = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_SET);
addr = addr |0x01;// Generate Read AddressDS1302_SendCmd(addr);// Sends addressreadSDA();for(i =0; i <8; i ++){
temp >>=1;// if(DS1302_SDA)if(HAL_GPIO_ReadPin(DS1302_GPIO, DS1302_SDA))
temp |=0x80;// DS1302_SCK = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);delayUS_DWT(1);// DS1302_SCK = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);delayUS_DWT(1);}writeSDA();// DS1302_RST = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);// DS1302_SDA = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, GPIO_PIN_RESET);return temp;}/* Sends 'cmd' command and reads in burst mode 'len' bytes into 'temp' */staticvoidDS1302_ReadBurst(uint8_t cmd,uint8_t len,uint8_t* temp){uint8_t i, j;// DS1302_RST = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_SET);
cmd = cmd |0x01;// Generate read commandDS1302_SendCmd(cmd);// Sends burst read commandreadSDA();for(j =0; j < len; j ++){
temp[j]=0;for(i =0; i <8; i ++){
temp[j]>>=1;// if(DS1302_SDA)if(HAL_GPIO_ReadPin(DS1302_GPIO, DS1302_SDA))
temp[j]|=0x80;// DS1302_SCK = 1;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_SET);delayUS_DWT(1);// DS1302_SCK = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);delayUS_DWT(1);}}writeSDA();// DS1302_RST = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SDA, GPIO_PIN_RESET);}/* Writes time byte by byte from 'buf' */voidDS1302_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);}/* Reads time byte by byte to 'buf' */voidDS1302_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);}/* DS1302初始化 */voidDS1302_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);// Отключить Trickle Charger// DS1302_RST = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_RST, GPIO_PIN_RESET);// DS1302_SCK = 0;HAL_GPIO_WritePin(DS1302_GPIO, DS1302_SCLK, GPIO_PIN_RESET);delayUS_DWT(10);// 不小于10微秒的延时。.DS1302_ClockStart();}/* Writes 'val' to ram address 'addr' *//* Ram addresses range from 0 to 30 */voidDS1302_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);}/* Reads ram address 'addr' */uint8_tDS1302_ReadRam(uint8_t addr){if(addr >= RAMSIZE){return0;}returnDS1302_ReadByte(DS1302_RAMSTART +(2* addr));}/* Clears the entire ram writing 0 */voidDS1302_ClearRam(void){uint8_t i;for(i=0; i< RAMSIZE; i++){DS1302_WriteRam(i,0x00);}}/* Reads time in burst mode, includes control byte */voidDS1302_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]);// Year
buf[2]=BCD2HEX(temp[4]);// Month
buf[3]=BCD2HEX(temp[3]);// Date
buf[4]=BCD2HEX(temp[2]);// Hour
buf[5]=BCD2HEX(temp[1]);// Min
buf[6]=BCD2HEX(temp[0]);// Sec
buf[7]=BCD2HEX(temp[5]);// Day
buf[0]= temp[7];// Control}/* Writes time in burst mode, includes control byte */voidDS1302_WriteTimeBurst(uint8_t* buf){uint8_t temp[8];
temp[0]=HEX2BCD(buf[6]);// Sec
temp[1]=HEX2BCD(buf[5]);// Min
temp[2]=HEX2BCD(buf[4]);// Hour
temp[3]=HEX2BCD(buf[3]);// Date
temp[4]=HEX2BCD(buf[2]);// Month
temp[5]=HEX2BCD(buf[7]);// Day
temp[6]=HEX2BCD(buf[1]);// Year
temp[7]=buf[0];// ControlDS1302_WriteBurst(DS1302_CLKBURST,8, temp);}/* Reads ram in burst mode 'len' bytes into 'buf' */voidDS1302_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);}/* Writes ram in burst mode 'len' bytes from 'buf' */voidDS1302_WriteRamBurst(uint8_t len,uint8_t* buf){if(len <=0){return;}if(len > RAMSIZE){
len = RAMSIZE;}DS1302_WriteBurst(DS1302_RAMBURST, len, buf);}//启动时钟。//DS1302 最初处于 Halt 模式(已停止,省电模式)。//为了开始计时,需要执行此函数一次。voidDS1302_ClockStart(void){uint8_t buf =0x00;DS1302_WriteByte(DS1302_CONTROL,0x00);// 禁用写入保护。delayUS_DWT(1);
buf =DS1302_ReadByte(DS1302_SEC)&0x7F;// 写入 8 位中的零的同时,保留当前秒数的值DS1302_WriteByte(DS1302_SEC, buf);DS1302_WriteByte(DS1302_CONTROL,0x80);// 启用写入保护。delayUS_DWT(1);}//停止时钟。//为了进入 Halt 模式(省电模式),此功能可能并不实用 voidDS1302_ClockStop(void){uint8_t buf =0x00;DS1302_WriteByte(DS1302_CONTROL,0x00);// 禁用写入保护delayUS_DWT(1);
buf =DS1302_ReadByte(DS1302_SEC)|0x80;// 写入 8 位中的1的同时,保留当前秒数的值DS1302_WriteByte(DS1302_SEC, buf);DS1302_WriteByte(DS1302_CONTROL,0x80);// 启用写入保护delayUS_DWT(1);}//重置时钟//将0写入所有时钟寄存器(从0x80到0x8C)并将 DS1302 传输到 Halt 模式(省电模式)。//要启动时钟,请使用 DS1302_ClockStart() 函数。voidDS1302_ClockClear(void){DS1302_WriteByte(DS1302_CONTROL,0x00);// 禁用写入保护delayUS_DWT(1);DS1302_WriteByte(DS1302_SEC,0x80);//重置秒并进入 Halt 模式。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);}
🌿dwt_delay.c文件
uint32_tDWT_Delay_Init(void){/* Disable TRC */
CoreDebug->DEMCR &=~CoreDebug_DEMCR_TRCENA_Msk;// ~0x01000000;/* Enable TRC */
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;// 0x01000000;/* Disable clock cycle counter */
DWT->CTRL &=~DWT_CTRL_CYCCNTENA_Msk;//~0x00000001;/* Enable clock cycle counter */
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;//0x00000001;/* Reset the clock cycle counter value */
DWT->CYCCNT =0;/* 3 NO OPERATION instructions */
__ASM volatile("NOP");
__ASM volatile("NOP");
__ASM volatile("NOP");/* Check if clock cycle counter has started */if(DWT->CYCCNT){return0;/*clock cycle counter started*/}else{return1;/*clock cycle counter not started*/}}
🌿dwt_delay.h文件
#ifndefDWT_DELAY_H#defineDWT_DELAY_H#ifdef__cplusplusextern"C"{#endif#include"stm32f1xx_hal.h"/**
* @brief Initializes DWT_Cycle_Count for DWT_Delay_us function
* @return Error DWT counter
* 1: DWT counter Error
* 0: DWT counter works
*/uint32_tDWT_Delay_Init(void);/**
* @brief This function provides a delay (in microseconds)
* @param microseconds: delay in microseconds
*/
__STATIC_INLINE voiddelayUS_DWT(volatileuint32_t microseconds){uint32_t clk_cycle_start = DWT->CYCCNT;/* Go to number of cycles for system */
microseconds *=(HAL_RCC_GetHCLKFreq()/1000000);/* Delay till end */while((DWT->CYCCNT - clk_cycle_start)< microseconds);}#ifdef__cplusplus}#endif#endif//DWT_DELAY_H
📝main主程序代码
/* USER CODE BEGIN Header *//**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*//* USER CODE END Header *//* Includes ------------------------------------------------------------------*/#include"main.h"#include"tim.h"#include"usart.h"#include"gpio.h"/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes */#include"stdio.h"#include"DS1302.h"/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV *//* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/voidSystemClock_Config(void);/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 *//* USER CODE END 0 *//**
* @brief The application entry point.
* @retval int
*/intmain(void){/* USER CODE BEGIN 1 */
DS1302_Time_t time ={0};// uint8_t buf[8]={23,4,3,14,34,8,1};constchar*WEEK[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};/* 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();MX_TIM6_Init();/* USER CODE BEGIN 2 */printf("Hello World \r\n");DWT_Delay_Init();DS1302_Init();// DS1302_WriteTime(buf);uint32_t TimerUART =HAL_GetTick();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while(1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */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);}}/* USER CODE END 3 */}/**
* @brief System Clock Configuration
* @retval None
*/voidSystemClock_Config(void){
RCC_OscInitTypeDef RCC_OscInitStruct ={0};
RCC_ClkInitTypeDef RCC_ClkInitStruct ={0};/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
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();}/** Initializes the CPU, AHB and APB buses clocks
*/
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();}}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//**
* @brief This function is executed in case of error occurrence.
* @retval None
*/voidError_Handler(void){/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while(1){}/* USER CODE END Error_Handler_Debug */}#ifdefUSE_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
*/voidassert_failed(uint8_t*file,uint32_t line){/* USER CODE BEGIN 6 *//* 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) *//* USER CODE END 6 */}#endif/* USE_FULL_ASSERT */