softiic.h
1 #ifndef __SOFTI2C_H_ 2 #define __SOFTI2C_H_ 3 4 #include "main.h" 5 //使用IICX PD6,PC1 6 7 #define SDA_IN() {GPIOC->MODER &= ~(3 << 1 * 2);GPIOC->MODER = (0 << 1 * 2);} 8 #define SDA_OUT() {GPIOC->MODER &= ~(3 << 1 * 2);GPIOC->MODER = (1 << 1 * 2);} 9 10 //IO操作函数 11 #define i2c_scl_low() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_RESET) 12 #define i2c_scl_high() HAL_GPIO_WritePin(GPIOD, GPIO_PIN_6, GPIO_PIN_SET) 13 14 #define i2c_sda_low() HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_RESET) 15 #define i2c_sda_high() HAL_GPIO_WritePin(GPIOC, GPIO_PIN_1, GPIO_PIN_SET) 16 17 #define i2c_read_sda() HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1) 18 19 extern uint32_t delay1us; 20 21 void delay_1us(uint32_t delay_1us); 22 23 void analog_i2c_delay(void); 24 25 void bsp_analog_i2c_init(void); 26 27 void bsp_analog_i2c_start(void); 28 29 void bsp_analog_i2c_stop(void); 30 31 uint8_t bsp_analog_i2c_wait_ack(void); 32 33 void bsp_analog_i2c_ack(void); 34 35 void bsp_analog_i2c_nack(void); 36 37 void bsp_analog_i2c_send_byte(uint8_t data); 38 39 uint8_t bsp_analog_i2c_read_byte(void); 40 41 #endif
soft.c
1 #include "softi2c.h" 2 3 uint32_t delay1us; 4 5 /** 6 * @brief: 1us延时 7 * @param {uint32_t} delay_1us 8 * @return {*} 9 */ 10 void delay_1us(uint32_t delay_1us) 11 { 12 HAL_TIM_Base_Start_IT(&htim3); 13 delay1us = delay_1us; 14 while (delay1us); 15 HAL_TIM_Base_Stop_IT(&htim3); 16 } 17 18 /** 19 * @brief: IIC延时时间 20 * @return {*} 21 */ 22 void analog_i2c_delay(void) 23 { 24 delay_1us(2); 25 } 26 27 /** 28 * @brief: 软件模拟I2C初始化 29 * @return {*} 30 */ 31 void bsp_analog_i2c_init(void) 32 { 33 GPIO_InitTypeDef GPIO_InitStruct = {0}; 34 35 __HAL_RCC_GPIOD_CLK_ENABLE(); 36 __HAL_RCC_GPIOC_CLK_ENABLE(); 37 38 /*Configure GPIO pins : PD6 */ 39 GPIO_InitStruct.Pin = GPIO_PIN_6; 40 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 41 GPIO_InitStruct.Pull = GPIO_NOPULL; 42 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 43 HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); 44 45 /*Configure GPIO pins : PC1 */ 46 GPIO_InitStruct.Pin = GPIO_PIN_1; 47 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; 48 GPIO_InitStruct.Pull = GPIO_NOPULL; 49 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; 50 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); 51 52 bsp_analog_i2c_stop(); 53 } 54 55 /** 56 * @brief: I2C 开始,SCL为高电平的时候SDA产生一个下降沿信号 57 * @return {*} 58 */ 59 void bsp_analog_i2c_start(void) 60 { 61 /* _____ 62 *SDA \_____________ 63 * __________ 64 *SCL \________ 65 */ 66 i2c_sda_high(); 67 i2c_scl_high(); 68 analog_i2c_delay(); 69 i2c_sda_low(); 70 analog_i2c_delay(); 71 i2c_scl_low(); 72 analog_i2c_delay(); 73 } 74 75 /** 76 * @brief: I2C 停止,SCL为高电平的时候SDA产生一个上升沿信号 77 * @return {*} 78 */ 79 void bsp_analog_i2c_stop(void) 80 { 81 /* _______ 82 *SDA __________/ 83 * ____________ 84 *SCL _____/ 85 */ 86 i2c_sda_low(); 87 i2c_scl_high(); 88 analog_i2c_delay(); 89 i2c_sda_high(); 90 analog_i2c_delay(); 91 } 92 93 /** 94 * @brief: I2C 等待响应 95 * @return {*} 96 */ 97 uint8_t bsp_analog_i2c_wait_ack(void) 98 { 99 uint32_t timeout = 0; 100 101 i2c_sda_high(); 102 SDA_IN(); 103 analog_i2c_delay(); 104 i2c_scl_high(); 105 analog_i2c_delay(); 106 while(i2c_read_sda()) 107 { 108 timeout++; 109 if(timeout > 2000) 110 { 111 return 1; 112 } 113 } 114 i2c_scl_low(); 115 analog_i2c_delay(); 116 return 0; 117 } 118 119 /** 120 * @brief: I2C 响应 121 * @return {*} 122 */ 123 void bsp_analog_i2c_ack(void) 124 { 125 /* ____ 126 *SCL ______/ \______ 127 * ____ _____ 128 *SDA \_______/ 129 */ 130 i2c_sda_low(); 131 analog_i2c_delay(); 132 i2c_scl_high(); 133 analog_i2c_delay(); 134 i2c_scl_low(); 135 analog_i2c_delay(); 136 i2c_sda_high(); 137 } 138 139 /** 140 * @brief: I2C 不响应 141 * @return {*} 142 */ 143 void bsp_analog_i2c_nack(void) 144 { 145 /* ____ 146 *SCL ______/ \______ 147 * __________________ 148 *SDA 149 */ 150 i2c_sda_high(); 151 analog_i2c_delay(); 152 i2c_scl_high(); 153 analog_i2c_delay(); 154 i2c_scl_low(); 155 analog_i2c_delay(); 156 } 157 158 /** 159 * @brief: I2C 发送一个字节数据 160 * @param {uint8_t} data 161 * @return {*} 162 */ 163 void bsp_analog_i2c_send_byte(uint8_t data) 164 { 165 uint8_t i; 166 167 SDA_OUT(); 168 for(i = 0; i < 8; i++) 169 { 170 if(data & 0x80) 171 { 172 i2c_sda_high(); 173 } 174 else 175 { 176 i2c_sda_low(); 177 } 178 179 analog_i2c_delay(); 180 i2c_scl_high(); 181 analog_i2c_delay(); 182 i2c_scl_low(); 183 if(i == 7) 184 { 185 i2c_sda_high(); 186 } 187 data <<= 1; 188 analog_i2c_delay(); 189 } 190 } 191 192 /** 193 * @brief: I2C 读一个字节数据 194 * @return {*} 195 */ 196 uint8_t bsp_analog_i2c_read_byte(void) 197 { 198 uint8_t i, data = 0; 199 200 i2c_sda_high(); 201 SDA_IN(); 202 for(i = 0; i < 8; i++ ) 203 { 204 data <<= 1; 205 i2c_scl_high(); 206 analog_i2c_delay(); 207 if(i2c_read_sda()) 208 { 209 data++; 210 } 211 i2c_scl_low(); 212 analog_i2c_delay(); 213 } 214 215 return data; 216 }
部分改写,原处:https://blog.csdn.net/weixin_43808708/article/details/126961103