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;

}

相关推荐
多看多敲多思考9 小时前
华润微CS32ME10 MCU使用教程(2)---CS32ME10之UART串口模块使用
stm32·单片机·嵌入式硬件·mcu
黑白园10 小时前
STM32系统时钟由72M修改为36M验证示例
stm32·单片机·嵌入式硬件
LCG元10 小时前
基于ARM7的LCD设计与实现:S3C4510B通用IO口控制液晶模块
stm32·单片机·嵌入式硬件
山后太阳10 小时前
Keil5(MDK-ARM)完整下载安装教程+入门教程:从零搭建STM32开发环境
arm开发·stm32·嵌入式硬件
Ww.xh11 小时前
STM32按键去抖动软件实现详解
stm32·单片机·嵌入式硬件
ghie909012 小时前
基于STM32的CAN通信完整例程(HAL库实现)
stm32·单片机·嵌入式硬件
lzj_pxxw12 小时前
W25Q64存储芯片 软件设计刚需常识
stm32·单片机·嵌入式硬件·mcu·学习
吃米饭17 小时前
HC32L021C8UB 移植 FreeRTOS
stm32·嵌入式·freertos·rtos
振南的单片机世界17 小时前
开漏输出:只能拉低,不能拉高,高电平靠“外部”帮忙
stm32·单片机·嵌入式硬件
黑白园20 小时前
STM32 通过I2C 读写EEPR0M AT24C02
stm32·单片机·嵌入式硬件