This paper uses analog IIC to drive sht35 temperature and humidity sensor
Stamping point: The IIC pull-up resistor of the purchased module is 10KΩ, which will cause IIC instability, poor anti-interference, and easy to cause timing errors; it is recommended to replace it with 4.7KΩ
1. CubeMx configuration
The rest are default, generate the project
1, us precise delay
Delay_Driver.c
/********************************************** ************************* *file: timer high precision delay *author:remnant dream *date:2022.9.26 *note: Note: Users are prohibited from using and changing The timer configuration: Frequency division factor -- 24, period -- 65535 No need to enable interrupt ***************************************************** *********************/ #include "Delay_Driver.h" /****************************** @function:us delay @param:us--time to be delayed @return: void @date:2022.9.26 @remark: *******************************/ void Delay_us(unsigned int us) {<!-- --> if(!us){<!-- -->return;} us = (us > 6553)?6553:us; us *= 10;//Basic is 100ns _DelayTIM_Handle.Instance->CNT = 0; HAL_TIM_Base_Start( & amp;_DelayTIM_Handle); while(_DelayTIM_Handle.Instance->CNT < us); HAL_TIM_Base_Stop( & amp;_DelayTIM_Handle); } /****************************** @function:ms delay @param:ms--time to be delayed @return: void @date:2022.9.26 @remark: *******************************/ void Delay_ms(unsigned int ms) {<!-- --> unsigned int i = 0; if(!ms){<!-- -->return;} while(ms) {<!-- --> i = (ms < 6)?(ms):6; Delay_us(i*1000); ms -= i; } } /****************************** @function:s delay @param:s--time to be delayed @return: void @date:2022.9.26 @remark: *******************************/ void Delay_s(unsigned int s) {<!-- --> unsigned int i = 0; if(!s){<!-- -->return;} while(s) {<!-- --> i = (s < 60)?(s):60; Delay_ms(i*1000); s -= i; } }
Delay_Driver.h
#ifndef _Delay_Driver_H_ #define _Delay_Driver_H_ #include "tim.h" #define _DelayTIM_Handle htim17 extern void Delay_us(unsigned int us); extern void Delay_ms(unsigned int ms); extern void Delay_s(unsigned int s); #endif
2. Pin analog IIC communication
IIC_simulate.c
/********************************************** ************************* *file: Simulate IIC file *author:remnant dream *date:2023.5.20 *note:V2.0 This file simulates the IIC host, and the functions use the simIIC_StructDef structure entity, which is convenient for multiple peripherals to use eg: #define dSHT3X_SDA_CLOCK __HAL_RCC_GPIOB_CLK_ENABLE() #define dSHT3X_SDA_PORT GPIOB #define dSHT3X_SDA_PIN GPIO_PIN_3 #define dSHT3X_SCL_CLOCK __HAL_RCC_GPIOB_CLK_ENABLE() #define dSHT3X_SCL_PORT GPIOB #define dSHT3X_SCL_PIN GPIO_PIN_4 #define dSHT3X_IIC_ADDRESS 0x44 void SHT3x_GPIO_EnableColock(void)//sht3x initializes the GPIO clock enable function of SDA|SCL of IIC { dSHT3X_SDA_CLOCK; dSHT3X_SCL_CLOCK; } simIIC_StructDef SHT3X_IIC;//Initialize the IIC structure variable SHT3X_IIC.SDA_Pin = dSHT3X_SDA_PIN; SHT3X_IIC.SCL_Pin = dSHT3X_SCL_PIN; SHT3X_IIC.SDA_GPIO = dSHT3X_SDA_PORT; SHT3X_IIC.SCL_GPIO = dSHT3X_SCL_PORT; SHT3X_IIC.GPIO_EnableColock = &SHT3x_GPIO_EnableColock; SHT3X_IIC.DelayMicrosecond = 1;//IIC speed: 500KHz SHT3X_IIC.Delay_us = & amp;Delay_us;//External us delay precise function simIIC_Init(SHT3X_IIC);//Initialize IIC uint8_t data[6] = {0}; if(simIIC_Read(SHT3X_IIC,data,6,dSHT3X_IIC_ADDRESS) < 0)return -1;//Read 6 bytes of data if(simIIC_Write(SHT3X_IIC,data,2,dSHT3X_IIC_ADDRESS) < 0) return -1;//write 6 bytes of data ***************************************************** *********************/ #include "IIC_simulate.h" #define dxSET_PIN(GPIOx,Pin) GPIOx->BSRR = Pin //pin set 1 #define dxRESET_PIN(GPIOx,Pin) GPIOx->BSRR = ((uint32_t)Pin << 16u) //pin set 0 #define dxREAD_PIN(GPIOx,Pin) (GPIOx->IDR & Pin)?1:0 #define dxSET_LEVEL_PIN(gpio,pin,level) if(level){<!-- -->dxSET_PIN(gpio,pin);}else dxRESET_PIN(gpio,pin) //IO direction setting #define dxPIN_MODE_IN(gpio,pin) {<!-- -->gpio->MODER & amp;= ~(3<<(pin*2));gpio->MODER |= 0<<(pin*2) ;}//input mode #define dxPIN_MODE_OUT(gpio,pin) {<!-- -->gpio->MODER & amp;= ~(3<<(pin*2));gpio->MODER |= 1<<(pin*2) ;}//output mode #define dIIC_SCL(simIIC,x) dxSET_LEVEL_PIN(simIIC.SCL_GPIO,simIIC.SCL_Pin,x) #define dIIC_SDA(simIIC,x) dxSET_LEVEL_PIN(simIIC.SDA_GPIO,simIIC.SDA_Pin,x) #define dIIC_SDA_IN(simIIC) dxPIN_MODE_IN(simIIC.SDA_GPIO,simIIC.SDA_Pin) #define dIIC_SDA_OUT(simIIC) dxPIN_MODE_OUT(simIIC.SDA_GPIO,simIIC.SDA_Pin) #define dIIC_SDA_READ(simIIC) dxREAD_PIN(simIIC.SDA_GPIO,simIIC.SDA_Pin) static void simIIC_DelayUs(simIIC_StructDef simIIC); /****************************** @function: Simulate IIC delay function @param: @return: void @note: *******************************/ static void simIIC_DelayUs(simIIC_StructDef simIIC) {<!-- --> if(simIIC. DelayMicrosecond == 0) return; simIIC.Delay_us(simIIC.DelayMicrosecond); } /****************************** @function: Simulate IIC initialization @param: simIIC-- simIIC_StructDef to be initialized @return: void @note: *******************************/ void simIIC_Init(simIIC_StructDef simIIC) {<!-- --> GPIO_InitTypeDef GPIO_InitStruct = {<!-- -->0}; simIIC.GPIO_EnableColock(); GPIO_InitStruct.Pin = simIIC.SDA_Pin; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct. Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(simIIC.SDA_GPIO, &GPIO_InitStruct); GPIO_InitStruct.Pin = simIIC.SCL_Pin; HAL_GPIO_Init(simIIC.SCL_GPIO, &GPIO_InitStruct); dIIC_SCL(simIIC,1); dIIC_SDA(simIIC,1); } /****************************** @function: IIC start signal @param: simIIC-- simIIC_StructDef to be initialized @return: void @note: *******************************/ void simIIC_Start(simIIC_StructDef simIIC) {<!-- --> dIIC_SDA_OUT(simIIC); dIIC_SDA(simIIC,1); dIIC_SCL(simIIC,1); simIIC_DelayUs(simIIC); dIIC_SDA(simIIC,0); simIIC_DelayUs(simIIC); dIIC_SCL(simIIC,0); } /****************************** @function: IIC end signal @param: simIIC-- simIIC_StructDef to be initialized @return: void @note: *******************************/ void simIIC_Stop(simIIC_StructDef simIIC) {<!-- --> dIIC_SCL(simIIC,0); dIIC_SDA(simIIC,0); simIIC_DelayUs(simIIC); dIIC_SCL(simIIC,1); simIIC_DelayUs(simIIC); dIIC_SDA(simIIC,1); simIIC_DelayUs(simIIC); } /****************************** @function: IIC write data (do not use it otherwise) @param: data--data to be sent @return: 0--write success, -1--write failure (slave address does not exist) @note: Does not contain IIC start, IIC end *******************************/ signed int simIIC_WriteOneByte(simIIC_StructDef simIIC, unsigned char data) {<!-- --> unsigned char ack = 0, mask = 0; dIIC_SDA_OUT(simIIC); for(mask=0x80;mask != 0;mask >>= 1) {<!-- --> dIIC_SDA(simIIC,((mask & amp; data) ? 1 : 0)); simIIC_DelayUs(simIIC); dIIC_SCL(simIIC,1); simIIC_DelayUs(simIIC); dIIC_SCL(simIIC,0); } dIIC_SDA(simIIC,1); dIIC_SDA_IN(simIIC); simIIC_DelayUs(simIIC); dIIC_SCL(simIIC,1); simIIC_DelayUs(simIIC); ack = dIIC_SDA_READ(simIIC); dIIC_SCL(simIIC,0); dIIC_SDA_OUT(simIIC); return (ack? -1:0); } /****************************** @function: IIC read data (do not use it otherwise) @param: ack: 0--answer, 1--no answer @return: the data read @note: Does not contain IIC start, IIC end *******************************/ unsigned char simIIC_ReadOneByte(simIIC_StructDef simIIC, simIIC_xACK_EnumDef ack) {<!-- --> unsigned char mask = 0, data = 0; dIIC_SDA(simIIC,1); dIIC_SDA_IN(simIIC); for(mask=0x80;mask != 0;mask >>= 1) {<!-- --> simIIC_DelayUs(simIIC); dIIC_SCL(simIIC,1); simIIC_DelayUs(simIIC); data |= ((dIIC_SDA_READ(simIIC))?mask:0); dIIC_SCL(simIIC,0); } dIIC_SDA_OUT(simIIC); dIIC_SDA(simIIC,ack); simIIC_DelayUs(simIIC); dIIC_SCL(simIIC,1); simIIC_DelayUs(simIIC); dIIC_SCL(simIIC,0); return data; } /****************************** @function: IIC write data @param: data--data to be sent byteNum - the number of data bytes, excluding address bytes address--slave address @return: 0--write success, -1--write failure (slave address does not exist | data bytes 0) @note: *******************************/ signed int simIIC_Write(simIIC_StructDef simIIC, unsigned char *data, unsigned int byteNum, unsigned char address) {<!-- --> unsigned int pos = 0; if(byteNum == 0) return -1; simIIC_Start(simIIC); if(simIIC_WriteOneByte(simIIC,address << 1) < 0){<!-- -->simIIC_Stop(simIIC);return -1;}//address access: write for(pos=0;pos < byteNum;pos + + ){<!-- -->if(simIIC_WriteOneByte(simIIC,data[pos]) < 0){<!-- -->simIIC_Stop(simIIC);return -1;}} simIIC_Stop(simIIC); return 0; } /****************************** @function: IIC read data @param: data-- the read data byteNum--the number of data bytes to be read, excluding address bytes address--slave address @return: 0--read successfully, -1--read failed (slave address does not exist | read error) @note: *******************************/ signed int simIIC_Read(simIIC_StructDef simIIC, unsigned char *data, unsigned int byteNum, unsigned char address) {<!-- --> unsigned int pos = 0; if(byteNum == 0) return -1; address = (address << 1) | 0x01; simIIC_Start(simIIC); if(simIIC_WriteOneByte(simIIC,address) < 0){<!-- -->simIIC_Stop(simIIC);return -1;}//address access: read for(pos=0;pos < byteNum;pos + + ){<!-- -->data[pos] = simIIC_ReadOneByte(simIIC,(pos == (byteNum-1))?simIIC_NACK:simIIC_ACK);} simIIC_Stop(simIIC); return 0; }
IIC_simulate.h
#ifndef _IIC_simulate_H_ #define _IIC_simulate_H_ #include "gpio.h" typedef struct {<!-- --> uint32_t SDA_Pin;//SDA pin uint32_t SCL_Pin;//SCL pin GPIO_TypeDef *SDA_GPIO;//SDA port GPIO_TypeDef *SCL_GPIO;//SCL port void (*GPIO_EnableColock)(void);//Enable the GPIO clock function of SDA and SCL, user-defined: eg:void SHT3x_GPIO_EnableColock(void) unsigned short int DelayMicrosecond;//IIC delay time, the frequency is close to 1/(2*DelayMicrosecond) * 1000000; when it is 0, there is no delay; note that the actual delay of IIC will be slightly longer than this time, because there is still a pin flip time consume void (*Delay_us)(unsigned int us);//microsecond delay precise function, user-defined: eg:void Delay_us(unsigned int us) } simIIC_StructDef; typedef enum {<!-- --> simIIC_ACK = 0, //IIC response simIIC_NACK = 1 //IIC does not respond } simIIC_xACK_EnumDef; void simIIC_Init(simIIC_StructDef simIIC); void simIIC_Start(simIIC_StructDef simIIC); void simIIC_Stop(simIIC_StructDef simIIC); signed int simIIC_WriteOneByte(simIIC_StructDef simIIC, unsigned char data); unsigned char simIIC_ReadOneByte(simIIC_StructDef simIIC,simIIC_xACK_EnumDef ack); signed int simIIC_Write(simIIC_StructDef simIIC, unsigned char *data, unsigned int byteNum, unsigned char address); signed int simIIC_Read(simIIC_StructDef simIIC, unsigned char *data, unsigned int byteNum, unsigned char address); #endif
3. sht3x temperature and humidity sensor driver
sht3x_Driver.c
/********************************************** ************************* *file: sht3x temperature and humidity sensor driver *author:remnant dream *date:2023.5.22 *note: ***************************************************** *********************/ #include "sht3x_Driver.h" #include "IIC_simulate.h" #include "Delay_Driver.h" #define dSHT3X_SDA_CLOCK __HAL_RCC_GPIOB_CLK_ENABLE() #define dSHT3X_SDA_PORT GPIOB #define dSHT3X_SDA_PIN GPIO_PIN_3 #define dSHT3X_SCL_CLOCK __HAL_RCC_GPIOB_CLK_ENABLE() #define dSHT3X_SCL_PORT GPIOB #define dSHT3X_SCL_PIN GPIO_PIN_4 #define dSHT3X_IIC_ADDRESS 0x44 static simIIC_StructDef SHT3X_IIC; static uint8_t SHT3x_CRC_CAL(uint16_t DAT); static int SHT3x_WriteByte(uint8_t MSB,uint8_t LSB); static void SHT3x_SoftReset(void); /****************************** @function: CRC check, CRC polynomial is: x^8 + x^5 + x^4 + 1, which is 0x31 @param:DAT The data to be verified @return: check code @note: *******************************/ static uint8_t SHT3x_CRC_CAL(uint16_t DAT) {<!-- --> uint8_t i,t,temp; uint8_t CRC_BYTE; CRC_BYTE = 0xFF; temp = (DAT>>8) & 0xFF; for(t = 0; t < 2; t ++ ) {<!-- --> CRC_BYTE ^= temp; for(i = 0;i < 8;i ++ ) {<!-- --> if(CRC_BYTE & 0x80) {<!-- --> CRC_BYTE <<= 1; CRC_BYTE ^= 0x31; } else {<!-- --> CRC_BYTE <<= 1; } } if(t == 0) {<!-- --> temp = DAT & 0xFF; } } return CRC_BYTE; } /****************************** @function: Send two bytes of data @param: MSB high 8 bits; LSB low 8 bits @return: -1--write failed, 0--success @note: *******************************/ static int SHT3x_WriteByte(uint8_t MSB, uint8_t LSB) {<!-- --> uint8_t data[2] = {<!-- -->0}; data[0] = MSB; data[1] = LSB; return (simIIC_Write(SHT3X_IIC,data,2,dSHT3X_IIC_ADDRESS) < 0) ? -1 : 0; } /*software reset SHT3x*/ static void SHT3x_SoftReset(void) {<!-- --> SHT3x_WriteByte(0x30,0xA2); //Reinitialize SHT3x } /****************************** @function:sht3x Initialize the SDA|SCL GPIO clock enable function of IIC @param: void @return: void @note: *******************************/ void SHT3x_GPIO_EnableColock(void) {<!-- --> dSHT3X_SDA_CLOCK; dSHT3X_SCL_CLOCK; } /****************************** @function: sht3x initialization @param: void @return: -1--initialization failed, 0--success @note: Set the periodic data collection mode (10 times per second, Medium Repeatability) *******************************/ int SHT3x_Init(void) {<!-- --> int xreturn = 0; SHT3X_IIC.SDA_Pin = dSHT3X_SDA_PIN; SHT3X_IIC.SCL_Pin = dSHT3X_SCL_PIN; SHT3X_IIC.SDA_GPIO = dSHT3X_SDA_PORT; SHT3X_IIC.SCL_GPIO = dSHT3X_SCL_PORT; SHT3X_IIC.GPIO_EnableColock = &SHT3x_GPIO_EnableColock; SHT3X_IIC.DelayMicrosecond = 1;//IIC speed: 500KHz SHT3X_IIC.Delay_us = &Delay_us; simIIC_Init(SHT3X_IIC); SHT3x_SoftReset(); xreturn = SHT3x_WriteByte(0X27,0X21);//periodic data acquisition mode (10 times per second, Medium Repeatability) float Hum = 0.0f,Temp = 0.0f; ReadSHT3x( & amp; Hum, & amp; Temp); return xreturn; } /****************************** @function: read SHT3x data @param: *Hum humidity, *Temp temperature @return: -1--failure, 0--success @note: When the reading period is less than the setting period, the reading will be wrong; the current setting period is 100ms, and the first reading will be wrong *******************************/ int ReadSHT3x(float *Hum, float *Temp) {<!-- --> uint16_t HumData = 0,TempData = 0,HumCRC = 0,TempCRC = 0;//declare variables to store the read data uint8_t data[6] = {<!-- -->0}; if(SHT3x_WriteByte(0XE0,0X00) < 0) return -1; //Send command, get data, for periodic data acquisition mode if(simIIC_Read(SHT3X_IIC,data,6,dSHT3X_IIC_ADDRESS) < 0) return -1; TempData = ((uint16_t)data[0] << 8) | (uint16_t)data[1];//Temperature high 8-bit data | temperature low 8-bit data TempCRC = data[2];//Temperature CRC check data HumData = ((uint16_t)data[3] << 8) | (uint16_t)data[4];//High humidity 8-bit data | Humidity low 8-bit data HumCRC = data[5];//humidity CRC check data if((SHT3x_CRC_CAL(HumData) != HumCRC) || (SHT3x_CRC_CAL(TempData) !=TempCRC)) return -1;//Check the received data by CRC *Hum = (float)HumData*100.0f/(65536-1); //Convert the received 16-bit binary data into decimal humidity data *Temp = (float)TempData*175.0f/(65536-1)-45.0f; //Convert the received 16-bit binary data into decimal temperature data return 0; }
sht3x_Driver.h
#ifndef _sht3x_Driver_H_ #define _sht3x_Driver_H_ #include "main.h" int SHT3x_Init(void); int ReadSHT3x(float *Hum, float *Temp); #endif
4. Read temperature and humidity main.c
main.c
/* USER CODE BEGIN Header */ /** ***************************************************** ***************************** * @file : main.c * @brief : Main program body ***************************************************** ***************************** * @attention * * <h2><center> & amp;copy; Copyright (c) 2023 STMicroelectronics. * All rights reserved.</center></h2> * * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ***************************************************** ***************************** */ /* USER CODE END Header */ /* Includes ----------------------------------------------- -------------------*/ #include "main.h" #include "tim.h" #include "usart.h" #include "gpio.h" /* Private includes ---------------------------------------------- ------------*/ /* USER CODE BEGIN Includes */ #include "IIC_simulate.h" #include "Delay_Driver.h" #include "sht3x_Driver.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 --------------------------------------------- --*/ void SystemClock_Config(void); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code --------------------------------------------- ------------*/ /* USER CODE BEGIN 0 */ float Hum = 0.0f,Temp = 0.0f; /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) {<!-- --> /* USER CODE BEGIN 1 */ /* 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_TIM17_Init(); /* USER CODE BEGIN 2 */ SHT3x_Init(); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) {<!-- --> /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ HAL_Delay(1000); if(ReadSHT3x( & amp;Hum, & amp;Temp) < 0){<!-- -->printf("error\\ ");} else printf("%.2fRH %.2f℃\\ ",Hum,Temp); } /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) {<!-- --> RCC_OscInitTypeDef RCC_OscInitStruct = {<!-- -->0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {<!-- -->0}; /** Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {<!-- -->} /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 4; RCC_OscInitStruct.PLL.PLLN = 60; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig( & RCC_OscInitStruct) != HAL_OK) {<!-- --> Error_Handler(); } /** Initializes the CPU, AHB and APB bus clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; if (HAL_RCC_ClockConfig( & RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {<!-- --> Error_Handler(); } } /* USER CODE BEGIN 4 */ /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_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 */ } #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 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\\ ", file, line) */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
5. Results, IIC waveform
Complete project and information:
Link: https://pan.baidu.com/s/1fZVBOykei0jTcVZT9ijiTQ
Extraction code: gvgc