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;

}

相关推荐
boneStudent1 小时前
BLDC电机无感FOC控制代码实例分享
stm32·单片机·嵌入式硬件
大神与小汪3 小时前
STM32WB55串口蓝牙模块
stm32·单片机·嵌入式硬件
独处东汉4 小时前
AI辅助Stm32l031项目开发调试板子之按键跟adc
stm32·单片机·嵌入式硬件
【 STM32开发 】4 小时前
【STM32 CubeMX】DAC 输出正弦波
stm32·信号·dac·正弦波·数模转换
YouEmbedded7 小时前
解码STM32定时器:原理、配置与实战
stm32·定时器·pwm·sg90舵机
羊小猪~~7 小时前
【QT】-- QT基础类
开发语言·c++·后端·stm32·单片机·qt
Q_21932764558 小时前
基于STM32的智能家居安防系统设计
网络·stm32·智能家居
BreezeJuvenile9 小时前
STM32_存储器与寄存器详细介绍
stm32·存储器·寄存器
小尧嵌入式9 小时前
【基础学习七十】ffmpeg命令
c++·stm32·嵌入式硬件·ffmpeg
Terasic友晶科技10 小时前
7-DE10-Nano的HDMI方块移动案例的整体实现(含Quartus完整工程免费下载)
fpga开发·i2c·pll·de10-nano·hdmi传输·方块移动案例·quartus prime