#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;
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;
}
STM32 Bit-Bang I2C
猜你喜欢
转载自blog.csdn.net/zoosenpin/article/details/73321178
今日推荐
周排行