STM32 Bit-Bang I2C

#include <stdio.h>

#include <stdlib.h>

#include "stm32l0xx_hal.h"

/**I2C1 GPIO Configuration

PB6 ------> I2C1_SCL

PB7 ------> I2C1_SDA

*/

#define SCL_0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET)

#define SCL_1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET)

#define SDA_0 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET)

#define SDA_1 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET)

#define IICport GPIOB

#define SCL GPIO_PIN_6

#define SDA GPIO_PIN_7

static void i2c_start(void);

static void i2c_stop(void);

static void wait_ack(void);

static void i2c_writebyte(unsigned char a);

static unsigned char i2c_readbyte(void);

static void SDAIN(void);

static void SDAOUT(void);

static void sendack(void);

static void sendnack(void);

static void i2c_writebit(unsigned char a);

void i2c1_sw_acc_init(void);

void i2c1_sw_acc_write(unsigned char sadd, unsigned char reg, unsigned char val);

unsigned char i2c1_sw_acc_read(unsigned char sadd, unsigned char reg);

/**

* @brief send ack signal at i2c bus

*/

static void sendack(void)

{

i2c_writebit(0);

}

/**

* @brief send nack signal at i2c bus

*/

static void sendnack(void)

{

i2c_writebit(1);

}

/**

* @brief realese the SDA

*/

static void SDAIN(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.Pin = GPIO_PIN_7;

GPIO_InitStructure.Mode = GPIO_MODE_INPUT;

HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);

}

/**

* @brief get the control of SDA

*/

static void SDAOUT(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.Pin = GPIO_PIN_7;

GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;

HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);

}

/**

* @brief delay

*/

static void delay5us(void)

{

unsigned short i;

i = 50;

while(i--);

}

/**

* @brief send start signal at i2c bus

*/

static void i2c_start(void)

{

SDAOUT();

SDA_1;

delay5us();

SCL_1;

delay5us();

SDA_0;

delay5us();

SCL_0;

delay5us();

}

/**

* @brief send stop signal at i2c bus

*/

static void i2c_stop(void)

{

SDAOUT();

SDA_0;

delay5us();

SCL_1;

delay5us();

SDA_1;

delay5us();

SCL_0;

delay5us();

}

/**

* @brief recieve ack signal at i2c bus

*/

static void wait_ack(void)

{

int i = 0;

SCL_0;

delay5us;

SDAIN();

delay5us;

SCL_1;

delay5us();

while (HAL_GPIO_ReadPin(IICport, SDA) && (i < 0x2b0)) {

i++;

}

SCL_0;

delay5us();

}

/**

* @brief write a byte at i2c bus

*

* @param the data to write

*/

static void i2c_writebyte(unsigned char a)

{

unsigned short i;

SDAOUT();

for (i = 0; i < 8; i++) {

SCL_0;

delay5us();

if (a & 0x80) {

SDA_1;

} else {

SDA_0;

}

a = a << 1;

delay5us();

SCL_1;

delay5us();

}

}

/**

* @brief write a bit at i2c bus

*

* @param the data to write

*/

static void i2c_writebit(unsigned char a)

{

SDAOUT();

SCL_0;

delay5us();

if (a == 0) {

SDA_0;

} else {

SDA_1;

}

delay5us();

SCL_1;

delay5us();

SCL_0;

delay5us();

}

/**

* @brief read a byte at i2c bus

*

* @retval the data read

*/

static unsigned char i2c_readbyte()

{

unsigned char i, temp;

temp = 0;

SDAIN();

SCL_0;

delay5us();

for (i = 0; i < 8; i++) {

SCL_1;

delay5us();

temp = (temp << 1) | HAL_GPIO_ReadPin(IICport, SDA);

delay5us();

SCL_0;

delay5us();

}

return temp;

}

/**

* @brief initial the i2c related gpios

*/

void i2c1_sw_acc_init(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

__GPIOB_CLK_ENABLE();

GPIO_InitStructure.Pin = GPIO_PIN_6|GPIO_PIN_7;

GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;

GPIO_InitStructure.Pull = GPIO_NOPULL;

GPIO_InitStructure.Speed = GPIO_SPEED_FAST; //GPIO_SPEED_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);

SDA_1;

SCL_1;

}

/**

* @brief write data at certain address on MPU6050

*

* @param add the in-chip address of the data

* @param Achar the data to write

*/

void i2c1_sw_acc_write(unsigned char sadd, unsigned char reg, unsigned char val)

{

i2c_start();

i2c_writebyte(sadd);

wait_ack();

i2c_writebyte(reg);

wait_ack();

i2c_writebyte(val);

wait_ack();

i2c_stop();

}

/**

* @brief read data from certain address of MPU6050

*

* @param add the in-chip address of the data

* @retval the data read

*/

unsigned char i2c1_sw_acc_read(unsigned char sadd, unsigned char reg)

{

unsigned char temp;

i2c_start();

i2c_writebyte(sadd);

wait_ack();

delay5us();

i2c_writebyte(reg);

wait_ack();

i2c_start();

i2c_writebyte(sadd + 1);

wait_ack();

temp = i2c_readbyte();

sendnack();

i2c_stop();

return temp;

}

相关推荐
羽获飞5 小时前
从零开始学嵌入式之STM32——9.STM32的时钟系统
stm32·单片机·嵌入式硬件
wotaifuzao8 小时前
STM32 + FreeRTOS 的订阅通知组件架构
stm32·嵌入式硬件·架构·freertos·事件驱动·嵌入式架构
小龙报9 小时前
【51单片机】深度解析 51 串口 UART:原理、配置、收发实现与工程化应用全总结
c语言·开发语言·c++·stm32·单片机·嵌入式硬件·51单片机
Lester_110116 小时前
STM32 高级定时器PWM互补输出模式--如果没有死区,突然关闭PWM有产生瞬间导通的可能吗
stm32·单片机·嵌入式硬件·嵌入式软件
小李独爱秋17 小时前
“bootmgr is compressed”错误:根源、笔记本与台式机差异化解决方案深度指南
运维·stm32·单片机·嵌入式硬件·文件系统·电脑故障
宵时待雨1 天前
STM32笔记归纳8:时钟
笔记·stm32·单片机·嵌入式硬件
JJRainbow1 天前
SN75176 芯片设计RS-232 转 RS-485 通信模块设计原理图
stm32·单片机·嵌入式硬件·fpga开发·硬件工程
不做无法实现的梦~1 天前
PX4编译环境配置和qgc配置安装教程(2)
linux·stm32
宁静致远20211 天前
STM32模拟IIC读取PCF8563
stm32·单片机·嵌入式硬件
听风吹雨yu1 天前
STM32F407-MD5码计算/Digest认证计算
stm32·单片机·嵌入式硬件