在gpio_i2c.c中加入:
#include "gpio_i2c.h"
#define AW_I2C_SCL_1() HAL_GPIO_WritePin(i2c_hw_info.SCL_GPIO_INFO.GPIOx, i2c_hw_info.SCL_GPIO_INFO.gpio_pin, GPIO_PIN_SET)
#define AW_I2C_SCL_0() HAL_GPIO_WritePin(i2c_hw_info.SCL_GPIO_INFO.GPIOx, i2c_hw_info.SCL_GPIO_INFO.gpio_pin, GPIO_PIN_RESET)
#define AW_I2C_SDA_1() HAL_GPIO_WritePin(i2c_hw_info.SDA_GPIO_INFO.GPIOx, i2c_hw_info.SDA_GPIO_INFO.gpio_pin, GPIO_PIN_SET)
#define AW_I2C_SDA_0() HAL_GPIO_WritePin(i2c_hw_info.SDA_GPIO_INFO.GPIOx, i2c_hw_info.SDA_GPIO_INFO.gpio_pin, GPIO_PIN_RESET)
#define AW_I2C_SDA_READ() HAL_GPIO_ReadPin(i2c_hw_info.SDA_GPIO_INFO.GPIOx, i2c_hw_info.SDA_GPIO_INFO.gpio_pin)
#define AW_I2C_DELAY_US(x) soft_udelay(1)
//clock = 72Hz
static void soft_udelay(unsigned int us){
int i = 50;
while(us!=0){
i=50;
while(i!=0)
i--;
us--;
}
}
static I2C_HWINFO_STRUCT i2c_hw_info = {
//scl info
{
GPIOB,
GPIO_PIN_10,
},
//sda info
{
GPIOB,
GPIO_PIN_11,
},
};
static void aw_i2c_stop(void){
AW_I2C_SCL_1();
AW_I2C_SDA_0();
AW_I2C_DELAY_US(1);
AW_I2C_SDA_1();
AW_I2C_DELAY_US(3);
};
static void aw_i2c_start(void){
AW_I2C_SDA_1();
AW_I2C_DELAY_US(1);
AW_I2C_SCL_1();
AW_I2C_DELAY_US(1);
AW_I2C_SDA_0();
AW_I2C_DELAY_US(1);
};
static signed char aw_i2c_wait_ack(void){
unsigned char i=0;
AW_I2C_SCL_1();
for(i=0;i<5;i++){
if(0 == AW_I2C_SDA_READ()){
AW_I2C_DELAY_US(1);
AW_I2C_SCL_0();
AW_I2C_DELAY_US(1);
return 0;
}
AW_I2C_DELAY_US(1);
}
aw_i2c_stop();
return -1; // timeout
}
static void aw_i2c_master_send_ack(void){
AW_I2C_SDA_0();
AW_I2C_SCL_1();
AW_I2C_DELAY_US(1);
AW_I2C_SCL_0();
AW_I2C_DELAY_US(1);
}
static signed char aw_i2c_send_byte(unsigned char data){
unsigned char i=0;
data &= 0xFF;
AW_I2C_SCL_0();
AW_I2C_DELAY_US(1);
for(i=0;i<8;i++){
if(data>>(7-i)&0x01){
AW_I2C_SDA_1();
}
else{
AW_I2C_SDA_0();
}
AW_I2C_SCL_1();
AW_I2C_DELAY_US(1);
AW_I2C_SCL_0();
AW_I2C_DELAY_US(1);
}
return aw_i2c_wait_ack();
}
static char aw_i2c_receive_byte(unsigned char *data){
unsigned char i = 0;
*data = 0x00;
for(i=0;i<8;i++){
AW_I2C_SCL_1();
AW_I2C_DELAY_US(1);
*data <<= 1;
if(AW_I2C_SDA_READ() == 0x01){
*data = *data | 0x01;
}
AW_I2C_SCL_0();
AW_I2C_DELAY_US(1);
}
aw_i2c_master_send_ack();
return 0;
}
signed char aw_gpio_i2c_read_exc(unsigned char dev_addr, unsigned char reg_addr, unsigned char *p_data, unsigned int data_num){
int re = 0;
unsigned char i=0;
aw_i2c_start();
//write flag
re = aw_i2c_send_byte(dev_addr<<1&(~(0x01)));
re = aw_i2c_send_byte(reg_addr);
if(re < 0){
return -1;
}
aw_i2c_start();
// read flag
re = aw_i2c_send_byte(dev_addr<<1|0x01);
for(i=0;i<data_num;i++){
re = aw_i2c_receive_byte(p_data+i);
if(re < 0){
aw_i2c_stop();
return -1;
}
}
aw_i2c_stop();
return 0;
}
signed char aw_gpio_i2c_write_exc(unsigned char dev_addr, unsigned char reg_addr, unsigned char *p_data, unsigned int data_num){
signed char re = 0;
unsigned char i=0;
aw_i2c_start();
re = aw_i2c_send_byte(dev_addr<<1&(~0x01));
re = aw_i2c_send_byte(reg_addr);
if(re < 0){
return -1;
}
for(i=0;i<data_num;i++){
re = aw_i2c_send_byte((unsigned char)*(p_data+i));
if(re < 0){
return -1;
}
}
aw_i2c_stop();
return 0;
}
signed char aw_gpio_i2c_read_reg(unsigned char dev_addr, unsigned char reg_addr, unsigned char *value){
return aw_gpio_i2c_read_exc(dev_addr, reg_addr, value, 1);
}
signed char aw_gpio_i2c_write_reg(unsigned char dev_addr, unsigned char reg_addr, unsigned int value){
unsigned char val = (unsigned char)value;
return aw_gpio_i2c_write_exc(dev_addr, reg_addr, &val, 1);
}
void i2c_gpio_init(void){
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pin = i2c_hw_info.SCL_GPIO_INFO.gpio_pin;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(i2c_hw_info.SCL_GPIO_INFO.GPIOx, &GPIO_InitStruct);
GPIO_InitStruct.Pin = i2c_hw_info.SDA_GPIO_INFO.gpio_pin;
HAL_GPIO_Init(i2c_hw_info.SDA_GPIO_INFO.GPIOx, &GPIO_InitStruct);
}
在gpio_i2c.h中加入:
#ifndef __GPIO_I2C_H__
#define __GPIO_I2C_H__
#include "stm32l4xx_hal.h"
#include "stm32l4xx_hal_gpio.h"
#include "stm32l4xx_hal_rcc.h"
typedef struct{
GPIO_TypeDef * GPIOx;
uint16_t gpio_pin;
}GPIO_INFO_STRUCT;
typedef struct{
GPIO_INFO_STRUCT SCL_GPIO_INFO;
GPIO_INFO_STRUCT SDA_GPIO_INFO;
}I2C_HWINFO_STRUCT;
extern void i2c_gpio_init(void);
extern signed char aw_gpio_i2c_read_reg(unsigned char dev_addr, unsigned char reg_addr, unsigned char *value);
extern signed char aw_gpio_i2c_write_reg(unsigned char dev_addr, unsigned char reg_addr, unsigned int value);
extern signed char aw_gpio_i2c_read_exc(unsigned char dev_addr, unsigned char reg_addr, unsigned char *p_data, unsigned int data_num);
extern signed char aw_gpio_i2c_write_exc(unsigned char dev_addr, unsigned char reg_addr, unsigned char *p_data, unsigned int data_num);
#endif