STM32 인스턴스 소스 분석(소프트웨어 에뮬레이션 IIC)
33735 단어 STM32 심층 분석 실천
#include "I2C1_soft.h"
// Software I2C1_ driver
// I2C1 pinout (SCL: PB8, SDA: PB9)
void I2C1_delay(void)
{
volatile int i = 14;// ,
while (i) {
i--;
}
}
bool I2C1_Start(void)
{
I2C1_SDA_H;
I2C1_SCL_H;
I2C1_delay();
if (!I2C1_SDA_read)
{
return false;
}
I2C1_SDA_L;
I2C1_delay();
if (I2C1_SDA_read)
{
return false;
}
I2C1_SDA_L;
I2C1_delay();
return true;
}
void I2C1_Stop(void)
{
I2C1_SCL_L;
I2C1_delay();
I2C1_SDA_L;
I2C1_delay();
I2C1_SCL_H;
I2C1_delay();
I2C1_SDA_H;
I2C1_delay();
}
void I2C1_Ack(void)
{
I2C1_SCL_L;
I2C1_delay();
I2C1_SDA_L;
I2C1_delay();
I2C1_SCL_H;
I2C1_delay();
I2C1_SCL_L;
I2C1_delay();
}
void I2C1_NoAck(void)
{
I2C1_SCL_L;
I2C1_delay();
I2C1_SDA_H;
I2C1_delay();
I2C1_SCL_H;
I2C1_delay();
I2C1_SCL_L;
I2C1_delay();
}
bool I2C1_WaitAck(void)
{
I2C1_SCL_L;
I2C1_delay();
I2C1_SDA_H;
I2C1_delay();
I2C1_SCL_H;
I2C1_delay();
if (I2C1_SDA_read) {
I2C1_SCL_L;
return false;
}
I2C1_SCL_L;
return true;
}
void I2C1_SendByte(uint8_t byte)
{
uint8_t i = 8;
while (i--) {
I2C1_SCL_L;
I2C1_delay();
if (byte & 0x80) {
I2C1_SDA_H;
} else {
I2C1_SDA_L;
}
byte <<= 1;
I2C1_delay();
I2C1_SCL_H;
I2C1_delay();
}
I2C1_SCL_L;
}
uint8_t I2C1_ReceiveByte(void)
{
uint8_t i = 8;
uint8_t byte = 0;
I2C1_SDA_H;
while (i--) {
byte <<= 1;
I2C1_SCL_L;
I2C1_delay();
I2C1_SCL_H;
I2C1_delay();
if (I2C1_SDA_read) {
byte |= 0x01;
}
}
I2C1_SCL_L;
return byte;
}
bool I2C1_WriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data)
{
int i;
if (!I2C1_Start()) {
return false;
}
I2C1_SendByte(addr << 1 | I2C1_Direction_Transmitter);
if (!I2C1_WaitAck()) {
I2C1_Stop();
return false;
}
I2C1_SendByte(reg);
I2C1_WaitAck();
for (i = 0; i < len; i++) {
I2C1_SendByte(data[i]);
if (!I2C1_WaitAck()) {
I2C1_Stop();
return false;
}
}
I2C1_Stop();
return true;
}
bool I2C1_Write(uint8_t addr, uint8_t reg, uint8_t data)
{
if (!I2C1_Start()) {
return false;
}
I2C1_SendByte(addr << 1 | I2C1_Direction_Transmitter);
if (!I2C1_WaitAck()) {
I2C1_Stop();
return false;
}
I2C1_SendByte(reg);
I2C1_WaitAck();
I2C1_SendByte(data);
I2C1_WaitAck();
I2C1_Stop();
return true;
}
bool I2C1_Write_1(uint8_t addr, uint8_t data)
{
if (!I2C1_Start())
{
return false;
}
I2C1_SendByte(addr << 1 | I2C1_Direction_Transmitter);
if (I2C1_WaitAck())
{
I2C1_Stop();
return false;
}
I2C1_SendByte(data);
I2C1_WaitAck();
I2C1_Stop();
return true;
}
bool I2C1_Read(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf)
{
if (!I2C1_Start()) {
return false;
}
I2C1_SendByte(addr << 1 | I2C1_Direction_Transmitter);
if (!I2C1_WaitAck()) {
I2C1_Stop();
return false;
}
I2C1_SendByte(reg);
I2C1_WaitAck();
I2C1_Start();
I2C1_SendByte(addr << 1 | I2C1_Direction_Receiver);
I2C1_WaitAck();
while (len) {
*buf = I2C1_ReceiveByte();
if (len == 1) {
I2C1_NoAck();
} else {
I2C1_Ack();
}
buf++;
len--;
}
I2C1_Stop();
return true;
}
bool I2C1_Read_buf(uint8_t addr, uint8_t len, uint8_t *buf)
{
if (!I2C1_Start())
{
return false;
}
I2C1_SendByte(addr << 1 | I2C1_Direction_Receiver);
I2C1_WaitAck();
while (len)
{
*buf = I2C1_ReceiveByte();
if (len == 1)
{
I2C1_NoAck();
}
else
{
I2C1_Ack();
}
buf++;
len--;
}
I2C1_Stop();
return true;
}
그h
#ifndef __I2C1_SOFT_H__
#define __I2C1_SOFT_H__
#include
#include "stm32f4xx_hal.h"
#define I2C1_SCL_H HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET)
#define I2C1_SCL_L HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET)
#define I2C1_SDA_H HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET)
#define I2C1_SDA_L HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET)
#define I2C1_SCL_read HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8)
#define I2C1_SDA_read HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9)
#define I2C1_Direction_Transmitter 0x00
#define I2C1_Direction_Receiver 0x01
void I2C1_SendByte(uint8_t byte);
uint8_t I2C1_ReceiveByte(void);
bool I2C1_WriteBuffer(uint8_t addr, uint8_t reg, uint8_t len, uint8_t * data);
bool I2C1_Write(uint8_t addr, uint8_t reg, uint8_t data);
bool I2C1_Read(uint8_t addr, uint8_t reg, uint8_t len, uint8_t *buf);
bool I2C1_Read_buf(uint8_t addr, uint8_t len, uint8_t *buf);
bool I2C1_Write_1(uint8_t addr, uint8_t data);
bool I2C1_Start(void);
bool I2C1_WaitAck(void);
void I2C1_Stop(void);
void I2C1_Ack(void);
void I2C1_NoAck(void);
#endif