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/rs485.c | ||||||
|         ${CMAKE_SOURCE_DIR}/src/led.c |         ${CMAKE_SOURCE_DIR}/src/led.c | ||||||
|         ${CMAKE_SOURCE_DIR}/src/i2c.c |         ${CMAKE_SOURCE_DIR}/src/i2c.c | ||||||
|  |         ${CMAKE_SOURCE_DIR}/src/soft_i2c.c | ||||||
| ) | ) | ||||||
|  |  | ||||||
| add_executable(xlsw_3dp_LDC1612 ${TARGET_C_SRC}) | 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 <stdlib.h> | ||||||
| #include <math.h> | #include <math.h> | ||||||
|  |  | ||||||
| /******************************************************************************/ | #include "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 |  | ||||||
|  |  | ||||||
| /******************************************************************************/ | /******************************************************************************/ | ||||||
|  |  | ||||||
| @@ -55,24 +46,6 @@ typedef enum { | |||||||
|  |  | ||||||
| void i2c_gpio_config(void); | 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_config(void); | ||||||
|  |  | ||||||
| void i2c_bus_reset(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); |     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 |     \brief      configure the I2CX interface | ||||||
|     \param[in]  none |     \param[in]  none | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								src/main.c
									
									
									
									
									
								
							| @@ -12,6 +12,7 @@ | |||||||
| #include "rs485.h" | #include "rs485.h" | ||||||
| #include "led.h" | #include "led.h" | ||||||
| #include "i2c.h" | #include "i2c.h" | ||||||
|  | #include "soft_i2c.h" | ||||||
| #include "ldc1612.h" | #include "ldc1612.h" | ||||||
| #include "tmp112.h" | #include "tmp112.h" | ||||||
|  |  | ||||||
| @@ -75,10 +76,26 @@ int main(void) { | |||||||
|     watchdog_init(); |     watchdog_init(); | ||||||
|  |  | ||||||
|     while (1) { |     while (1) { | ||||||
|         si2c_config(); |         soft_i2c_config(); | ||||||
|         printf("111\n"); |         printf("111\n"); | ||||||
|  |  | ||||||
|         i2c_start(); |         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); |         i2c_send_byte((0x2B << 1) + 1); | ||||||
|         if (!i2c_wait_ack()) |         if (!i2c_wait_ack()) | ||||||
|         { |         { | ||||||
| @@ -87,30 +104,11 @@ int main(void) { | |||||||
|  |  | ||||||
|         i2c_delay(); |         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); |         data[0] = i2c_receive_byte(1); | ||||||
|         i2c_delay(); |  | ||||||
|         data[1] = i2c_receive_byte(0); |         data[1] = i2c_receive_byte(0); | ||||||
|  |  | ||||||
|         delay_us(5); |         delay_us(5); | ||||||
|         i2c_stop(); |         i2c_stop(); | ||||||
|         // printf("OK\n"); |  | ||||||
|  |  | ||||||
|         printf("0x%x 0x%x\n", data[0], data[1]); |         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