generated from hulk/gd32e23x_template
	添加board_config.h作为全部板上IO的宏定义位置,独立soft_i2c为单独文件
This commit is contained in:
		| @@ -29,6 +29,7 @@ set(TARGET_C_SRC | ||||
|         ${CMAKE_SOURCE_DIR}/src/rs485.c | ||||
|         ${CMAKE_SOURCE_DIR}/src/led.c | ||||
|         ${CMAKE_SOURCE_DIR}/src/i2c.c | ||||
|         ${CMAKE_SOURCE_DIR}/src/soft_i2c.c | ||||
| ) | ||||
|  | ||||
| add_executable(xlsw_3dp_LDC1612 ${TARGET_C_SRC}) | ||||
|   | ||||
							
								
								
									
										21
									
								
								inc/board_config.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								inc/board_config.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| // | ||||
| // Created by dell on 24-12-28. | ||||
| // | ||||
|  | ||||
| #ifndef BOARD_CONFIG_H | ||||
| #define BOARD_CONFIG_H | ||||
|  | ||||
| /******************************************************************************/ | ||||
|  | ||||
| #define I2C_SPEED       20000 | ||||
| #define RCU_GPIO_I2C    RCU_GPIOF | ||||
| #define RCU_I2C         RCU_I2C0 | ||||
| #define I2C_SCL_PORT    GPIOF | ||||
| #define I2C_SCL_PIN     GPIO_PIN_1 | ||||
| #define I2C_SDA_PORT    GPIOF | ||||
| #define I2C_SDA_PIN     GPIO_PIN_0 | ||||
| #define I2C_GPIO_AF     GPIO_AF_1 | ||||
|  | ||||
| /******************************************************************************/ | ||||
|  | ||||
| #endif //BOARD_CONFIG_H | ||||
							
								
								
									
										29
									
								
								inc/i2c.h
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								inc/i2c.h
									
									
									
									
									
								
							| @@ -15,16 +15,7 @@ | ||||
| #include <stdlib.h> | ||||
| #include <math.h> | ||||
|  | ||||
| /******************************************************************************/ | ||||
|  | ||||
| #define I2C_SPEED       20000 | ||||
| #define RCU_GPIO_I2C    RCU_GPIOF | ||||
| #define RCU_I2C         RCU_I2C0 | ||||
| #define I2C_SCL_PORT    GPIOF | ||||
| #define I2C_SCL_PIN     GPIO_PIN_1 | ||||
| #define I2C_SDA_PORT    GPIOF | ||||
| #define I2C_SDA_PIN     GPIO_PIN_0 | ||||
| #define I2C_GPIO_AF     GPIO_AF_1 | ||||
| #include "board_config.h" | ||||
|  | ||||
| /******************************************************************************/ | ||||
|  | ||||
| @@ -55,24 +46,6 @@ typedef enum { | ||||
|  | ||||
| void i2c_gpio_config(void); | ||||
|  | ||||
| void si2c_config(void); | ||||
|  | ||||
| void i2c_delay(void); | ||||
|  | ||||
| void i2c_start(void); | ||||
|  | ||||
| void i2c_stop(void); | ||||
|  | ||||
| void i2c_send_ack(void); | ||||
|  | ||||
| void i2c_send_nack(void); | ||||
|  | ||||
| uint8_t i2c_wait_ack(void); | ||||
|  | ||||
| void i2c_send_byte(uint8_t byte); | ||||
|  | ||||
| uint8_t i2c_receive_byte(uint8_t ack); | ||||
|  | ||||
| void i2c_config(void); | ||||
|  | ||||
| void i2c_bus_reset(void); | ||||
|   | ||||
							
								
								
									
										37
									
								
								inc/soft_i2c.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								inc/soft_i2c.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| // | ||||
| // Created by dell on 24-12-28. | ||||
| // | ||||
|  | ||||
| #ifndef SOFT_I2C_H | ||||
| #define SOFT_I2C_H | ||||
|  | ||||
| #include "gd32e23x_it.h" | ||||
| #include "gd32e23x.h" | ||||
| #include "systick.h" | ||||
| #include "main.h" | ||||
|  | ||||
| #include "board_config.h" | ||||
|  | ||||
| /******************************************************************************/ | ||||
|  | ||||
| #define I2C_SCL_HIGH()      gpio_bit_set(I2C_SCL_PORT, I2C_SCL_PIN) | ||||
| #define I2C_SCL_LOW()       gpio_bit_reset(I2C_SCL_PORT, I2C_SCL_PIN) | ||||
| #define I2C_SDA_HIGH()      gpio_bit_set(I2C_SDA_PORT, I2C_SDA_PIN) | ||||
| #define I2C_SDA_LOW()       gpio_bit_reset(I2C_SDA_PORT, I2C_SDA_PIN) | ||||
| #define I2C_SDA_READ()      gpio_input_bit_get(I2C_SDA_PORT, I2C_SDA_PIN) | ||||
|  | ||||
| /******************************************************************************/ | ||||
|  | ||||
| void i2c_delay(void); | ||||
|  | ||||
| void soft_i2c_config(void); | ||||
|  | ||||
| void soft_i2c_start(void); | ||||
| void soft_i2c_stop(void); | ||||
| void soft_i2c_send_ack(void); | ||||
| void soft_i2c_send_nack(void); | ||||
| uint8_t soft_i2c_wait_ack(void); | ||||
| void soft_i2c_send_byte(uint8_t data); | ||||
| uint8_t soft_i2c_receive_byte(uint8_t ack); | ||||
|  | ||||
| #endif //SOFT_I2C_H | ||||
							
								
								
									
										137
									
								
								src/i2c.c
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								src/i2c.c
									
									
									
									
									
								
							| @@ -25,143 +25,6 @@ void i2c_gpio_config(void) { | ||||
|     gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN); | ||||
| } | ||||
|  | ||||
| void i2c_delay(void) { | ||||
|     delay_us(20); // Adjust delay as needed | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      configure the software IIC GPIO | ||||
|     \param[in]  none | ||||
|     \param[out] none | ||||
|     \retval     none | ||||
| */ | ||||
| void si2c_config(void) { | ||||
|     rcu_periph_clock_enable(RCU_GPIO_I2C); | ||||
|  | ||||
|     gpio_mode_set(I2C_SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SCL_PIN); | ||||
|     gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN); | ||||
|  | ||||
|     gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SDA_PIN); | ||||
|     gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN); | ||||
|  | ||||
|     I2C_SCL_HIGH(); | ||||
|     I2C_SDA_HIGH(); | ||||
| } | ||||
|  | ||||
| // void sda_out(void) { | ||||
| //     gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SDA_PIN); | ||||
| //     gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN); | ||||
| // } | ||||
| // | ||||
| // void sda_in(void) { | ||||
| //     gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, I2C_SDA_PIN); | ||||
| // } | ||||
|  | ||||
| void i2c_start(void) { | ||||
|     // sda_out(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SDA_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_LOW(); | ||||
|     i2c_delay(); | ||||
|     i2c_delay(); | ||||
|     // 从全高开始,SCL为高期间,SDA下降沿表示start信号,再拉低SCL | ||||
| } | ||||
|  | ||||
| void i2c_stop(void) { | ||||
|     // sda_out(); | ||||
|     I2C_SCL_LOW(); | ||||
|     I2C_SDA_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     // 从全低开始,SCL为高期间,SDA上升沿表示stop | ||||
| } | ||||
|  | ||||
| void i2c_send_ack(void) { | ||||
|     // sda_out(); | ||||
|     I2C_SDA_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     // SCL产生一个正常的时钟周期,其间SDA始终为低电平,表示ACK | ||||
| } | ||||
|  | ||||
| void i2c_send_nack(void) { | ||||
|     // sda_out(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     // SCL产生一个正常的时钟周期,其间SDA始终为高电平,表示NACK | ||||
| } | ||||
|  | ||||
| uint8_t i2c_wait_ack(void) { | ||||
|     // sda_in(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     uint8_t ack = !I2C_SDA_READ(); | ||||
|     //ACK信号是第九个时钟期间,SDA被从机在SCL高期间,拉低并保持低电平。此处判断SDA是否被拉低,被拉低则返回0,取反为1,表示收到ACK | ||||
|     I2C_SCL_LOW(); | ||||
|     return ack; | ||||
| } | ||||
|  | ||||
| void i2c_send_byte(uint8_t byte) { | ||||
|     // sda_out(); | ||||
|     for (int i = 0; i < 8; i++) { | ||||
|         if (byte & 0x80) { //通过&操作获取第一位是1还是0 | ||||
|             I2C_SDA_HIGH(); //SCL低电平期间,SDA高电平表示1 | ||||
|         } else { | ||||
|             I2C_SDA_LOW(); //SCL低电平期间,SDA低电平表示0 | ||||
|         } | ||||
|         byte <<= 1; //左移一位,把原本第二位的数据移到第一位,再判断高低电平 | ||||
|         i2c_delay(); | ||||
|         I2C_SCL_HIGH(); //SCL拉高电平,SDA电平状态保持不变 | ||||
|         i2c_delay(); | ||||
|         I2C_SCL_LOW(); //SCL拉低电平 | ||||
|         delay_us(5); | ||||
|     } | ||||
|     // i2c_wait_ack(); | ||||
| } | ||||
|  | ||||
| uint8_t i2c_receive_byte(uint8_t ack) { | ||||
|     // sda_in(); | ||||
|     uint8_t byte = 0; | ||||
|     I2C_SDA_HIGH(); //从高开始 | ||||
|     for (int i = 0; i < 8; i++) { | ||||
|         byte <<= 1; | ||||
|         I2C_SCL_HIGH(); | ||||
|         i2c_delay(); | ||||
|         if (I2C_SDA_READ()) { | ||||
|             byte |= 0x01; | ||||
|         } | ||||
|         I2C_SCL_LOW(); | ||||
|         i2c_delay(); | ||||
|     } | ||||
|     if (ack) { | ||||
|         i2c_send_ack(); | ||||
|     } else { | ||||
|         i2c_send_nack(); | ||||
|     } | ||||
|     return byte; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| /*! | ||||
|     \brief      configure the I2CX interface | ||||
|     \param[in]  none | ||||
|   | ||||
							
								
								
									
										38
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -12,6 +12,7 @@ | ||||
| #include "rs485.h" | ||||
| #include "led.h" | ||||
| #include "i2c.h" | ||||
| #include "soft_i2c.h" | ||||
| #include "ldc1612.h" | ||||
| #include "tmp112.h" | ||||
|  | ||||
| @@ -75,10 +76,26 @@ int main(void) { | ||||
|     watchdog_init(); | ||||
|  | ||||
|     while (1) { | ||||
|         si2c_config(); | ||||
|         soft_i2c_config(); | ||||
|         printf("111\n"); | ||||
|  | ||||
|         i2c_start(); | ||||
|         i2c_send_byte((0x2B << 1)); | ||||
|         if (!i2c_wait_ack()) | ||||
|         { | ||||
|             printf("NACK\n"); | ||||
|         } | ||||
|  | ||||
|  | ||||
|         i2c_send_byte(0x7E); | ||||
|         if (!i2c_wait_ack()) | ||||
|         { | ||||
|             printf("NACK\n"); | ||||
|         } | ||||
|  | ||||
|         i2c_delay(); | ||||
|         i2c_start(); | ||||
|  | ||||
|         i2c_send_byte((0x2B << 1) + 1); | ||||
|         if (!i2c_wait_ack()) | ||||
|         { | ||||
| @@ -87,30 +104,11 @@ int main(void) { | ||||
|  | ||||
|         i2c_delay(); | ||||
|  | ||||
|         i2c_send_byte(0x7E); | ||||
|         // if (!i2c_wait_ack()) | ||||
|         // { | ||||
|         //     printf("NACK\n"); | ||||
|         // } | ||||
|  | ||||
|         i2c_delay(); | ||||
|         i2c_start(); | ||||
|  | ||||
|         i2c_send_byte((0x2B << 1)); | ||||
|         if (!i2c_wait_ack()) | ||||
|         { | ||||
|             printf("NACK\n"); | ||||
|         } | ||||
|  | ||||
|         i2c_delay(); | ||||
|  | ||||
|         data[0] = i2c_receive_byte(1); | ||||
|         i2c_delay(); | ||||
|         data[1] = i2c_receive_byte(0); | ||||
|  | ||||
|         delay_us(5); | ||||
|         i2c_stop(); | ||||
|         // printf("OK\n"); | ||||
|  | ||||
|         printf("0x%x 0x%x\n", data[0], data[1]); | ||||
|  | ||||
|   | ||||
							
								
								
									
										179
									
								
								src/soft_i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										179
									
								
								src/soft_i2c.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,179 @@ | ||||
| // | ||||
| // Created by dell on 24-12-28. | ||||
| // | ||||
|  | ||||
| #include "soft_i2c.h" | ||||
|  | ||||
| /*! | ||||
|     \brief      delay | ||||
|     \param[in]  none | ||||
|     \param[out] none | ||||
|     \retval     none | ||||
| */ | ||||
| void i2c_delay(void) { | ||||
|     delay_us(20); // Adjust delay as needed | ||||
|     /* delay to freq | ||||
|      *  20KHz: delay_us(20); | ||||
|      *  65KHz: delay_us(1); | ||||
|      */ | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      configure the software IIC GPIO | ||||
|     \param[in]  none | ||||
|     \param[out] none | ||||
|     \retval     none | ||||
| */ | ||||
| void soft_i2c_config(void) { | ||||
|     rcu_periph_clock_enable(RCU_GPIO_I2C); | ||||
|  | ||||
|     gpio_mode_set(I2C_SCL_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SCL_PIN); | ||||
|     gpio_output_options_set(I2C_SCL_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SCL_PIN); | ||||
|  | ||||
|     gpio_mode_set(I2C_SDA_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, I2C_SDA_PIN); | ||||
|     gpio_output_options_set(I2C_SDA_PORT, GPIO_OTYPE_OD, GPIO_OSPEED_50MHZ, I2C_SDA_PIN); | ||||
|  | ||||
|     I2C_SCL_HIGH(); | ||||
|     I2C_SDA_HIGH(); | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      generate I2C start signal | ||||
|     \param[in]  none | ||||
|     \param[out] none | ||||
|     \retval     none | ||||
| */ | ||||
| void soft_i2c_start(void) { | ||||
|     // sda_out(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SDA_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_LOW(); | ||||
|     // i2c_delay(); | ||||
|     // 从全高开始,SCL为高期间,SDA下降沿表示start信号,再拉低SCL | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      generate I2C stop signal | ||||
|     \param[in]  none | ||||
|     \param[out] none | ||||
|     \retval     none | ||||
| */ | ||||
| void soft_i2c_stop(void) { | ||||
|     // sda_out(); | ||||
|     I2C_SCL_LOW(); | ||||
|     I2C_SDA_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     // 从全低开始,SCL为高期间,SDA上升沿表示stop | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      send I2C ACK signal | ||||
|     \param[in]  none | ||||
|     \param[out] none | ||||
|     \retval     none | ||||
| */ | ||||
| void soft_i2c_send_ack(void) { | ||||
|     // sda_out(); | ||||
|     I2C_SDA_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     // SCL产生一个正常的时钟周期,其间SDA始终为低电平,表示ACK | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      send I2C NACK signal | ||||
|     \param[in]  none | ||||
|     \param[out] none | ||||
|     \retval     none | ||||
| */ | ||||
| void soft_i2c_send_nack(void) { | ||||
|     // sda_out(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_LOW(); | ||||
|     i2c_delay(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     // SCL产生一个正常的时钟周期,其间SDA始终为高电平,表示NACK | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      wait I2C ACK signal | ||||
|     \param[in]  none | ||||
|     \param[out] none | ||||
|     \retval     0: ACK received, 1: ACK not received | ||||
| */ | ||||
| uint8_t soft_i2c_wait_ack(void) { | ||||
|     // sda_in(); | ||||
|     I2C_SDA_HIGH(); | ||||
|     i2c_delay(); | ||||
|     I2C_SCL_HIGH(); | ||||
|     i2c_delay(); | ||||
|     uint8_t ack = !I2C_SDA_READ(); | ||||
|     //ACK信号是第九个时钟期间,SDA被从机在SCL高期间,拉低并保持低电平。此处判断SDA是否被拉低,被拉低则返回0,取反为1,表示收到ACK | ||||
|     I2C_SCL_LOW(); | ||||
|     return ack; | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      send a byte via I2C | ||||
|     \param[in]  byte: byte to be sent | ||||
|     \param[out] none | ||||
|     \retval     none | ||||
| */ | ||||
| void soft_i2c_send_byte(uint8_t byte) { | ||||
|     // sda_out(); | ||||
|     for (int i = 0; i < 8; i++) { | ||||
|         if (byte & 0x80) { //通过&操作获取第一位是1还是0 | ||||
|             I2C_SDA_HIGH(); //SCL低电平期间,SDA高电平表示1 | ||||
|         } else { | ||||
|             I2C_SDA_LOW(); //SCL低电平期间,SDA低电平表示0 | ||||
|         } | ||||
|         byte <<= 1; //左移一位,把原本第二位的数据移到第一位,再判断高低电平 | ||||
|         i2c_delay(); | ||||
|         I2C_SCL_HIGH(); //SCL拉高电平,SDA电平状态保持不变 | ||||
|         i2c_delay(); | ||||
|         I2C_SCL_LOW(); //SCL拉低电平 | ||||
|         delay_us(5); | ||||
|     } | ||||
|     // i2c_wait_ack(); | ||||
| } | ||||
|  | ||||
| /*! | ||||
|     \brief      receive a byte via I2C | ||||
|     \param[in]  ack: 1: send ACK, 0: send NACK | ||||
|     \param[out] none | ||||
|     \retval     received byte | ||||
| */ | ||||
| uint8_t soft_i2c_receive_byte(uint8_t ack) { | ||||
|     // sda_in(); | ||||
|     uint8_t byte = 0; | ||||
|     I2C_SDA_HIGH(); //从高开始 | ||||
|     for (int i = 0; i < 8; i++) { | ||||
|         byte <<= 1; | ||||
|         I2C_SCL_HIGH(); | ||||
|         i2c_delay(); | ||||
|         if (I2C_SDA_READ()) { | ||||
|             byte |= 0x01; | ||||
|         } | ||||
|         I2C_SCL_LOW(); | ||||
|         i2c_delay(); | ||||
|     } | ||||
|     if (ack) { | ||||
|         soft_i2c_send_ack(); | ||||
|     } else { | ||||
|         soft_i2c_send_nack(); | ||||
|     } | ||||
|     return byte; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user