/***********************************iic.h*****************************/
#ifndef __IIC_H_
#define __IIC_H_
#include <stdint.h>
#include <stdbool.h>
#include "stm32f10x.h"
enum I2C_DevStaus{
StatusFree = 0,
StatusBusy,
StatusFinish,
StatusRd, //读取状态
StatusWr, //写入状态
StatusReadRegAddressHasSend,//读取寄存器地址已经发送
};
enum I2C_DevStatusRw{
StatusRead = 0,
StatusWrite,
};
typedef struct I2C_Dev
{
uint8_t SlaveAddress;
uint8_t RegAddress;
uint8_t OperateByteNum;
uint8_t DevStatusRw; // Distinguish the read and write status of the device
uint8_t DevStatus;
uint8_t IRQn;
uint8_t NVIC_IRQChannelPreemptionPriority;
uint8_t NVIC_IRQChannelSubPriority;
I2C_TypeDef* I2cx;
uint32_t SCL_PIN;
uint32_t SDO_PIN;
GPIO_TypeDef *GPIO_GROUP;
uint32_t RCC_APB1Periph;
uint32_t RCC_APB2Periph;
uint8_t *pData; // tx and rx buffer
uint8_t Pos;
}I2C_Dev_t;
extern void I2C1_Init(void);
extern bool I2C1_Read(uint8_t addr,uint8_t *pData,uint8_t len);
extern bool I2C1_Write(uint8_t addr,uint8_t *pData,uint8_t len);
#endif
/********************************iic.c***********************************/
#include "iic.h"
#include "main.h"
#include <stdio.h>
#include <stdbool.h>
#define AS5600_DEV_ADDR (0X36 <<1)
static I2C_Dev_t gI2C_Dev = {
AS5600_DEV_ADDR, //slave address
0,
0,
StatusWrite, //default read status
StatusFree,
I2C1_EV_IRQn, //intterupt number
1,
1,
I2C1,
GPIO_Pin_6,
GPIO_Pin_7,
GPIOB,
RCC_APB1Periph_I2C1,
RCC_APB2Periph_GPIOB,
};
void I2Cx_Init(I2C_Dev_t* I2C_Dev)
{
GPIO_InitTypeDef GPIO_InitStructure = {0};
I2C_InitTypeDef I2C_InitStructure = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
RCC_APB1PeriphClockCmd(I2C_Dev->RCC_APB1Periph, ENABLE);
RCC_APB2PeriphClockCmd(I2C_Dev->RCC_APB2Periph, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Pin = I2C_Dev->SCL_PIN | I2C_Dev->SDO_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_Dev->GPIO_GROUP, &GPIO_InitStructure);
I2C_DeInit(I2C_Dev->I2cx);
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 400000;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_OwnAddress1 = 0x55;
I2C_Init(I2C_Dev->I2cx, &I2C_InitStructure);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = I2C_Dev->IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = I2C_Dev->NVIC_IRQChannelPreemptionPriority;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = I2C_Dev->NVIC_IRQChannelSubPriority;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
I2C_ITConfig(I2C_Dev->I2cx, I2C_IT_EVT | I2C_IT_BUF,ENABLE);
I2C_Cmd(I2C_Dev->I2cx, ENABLE);
}
void I2C1_Init(void)
{
I2Cx_Init(&gI2C_Dev);
}
#define FLAG_Mask ((uint32_t)0x00FFFFFF)
ErrorStatus I2Cx_CheckEvent(I2C_TypeDef* I2Cx,uint32_t SR1,uint32_t SR2,uint32_t I2C_EVENT)
{
uint32_t lastevent = 0;
uint32_t flag1 = 0, flag2 = 0;
ErrorStatus status = ERROR;
/* Read the I2Cx status register */
flag1 = SR1;
flag2 = SR2;
flag2 = flag2 << 16;
/* Get the last event value from I2C status register */
lastevent = (flag1 | flag2) & FLAG_Mask;
/* Check whether the last event is equal to I2C_EVENT */
if (lastevent == I2C_EVENT )
{
/* SUCCESS: last event is equal to I2C_EVENT */
status = SUCCESS;
}
else
{
/* ERROR: last event is different from I2C_EVENT */
status = ERROR;
}
/* Return status */
return status;
}
static bool I2Cx_Read(I2C_Dev_t* I2C_Dev,uint8_t addr,uint8_t *pData,uint8_t len)
{
int ret = 0;
uint32_t u32TimeOut = 0;
while(I2C_Dev->DevStatus != StatusFree)
{
u32TimeOut++;
if(u32TimeOut > 0xfffffff)
{
I2C_Dev->DevStatus = StatusFree;
return false; //等待总线超时
}
}
I2C_Dev->DevStatusRw = StatusWrite; //先置位成写状态 发送器件的地址
I2C_Dev->RegAddress = addr;
I2C_Dev->OperateByteNum = len; //读取的字节数
I2C_Dev->pData = pData;
I2C_Dev->DevStatus = StatusRd;
I2C_Dev->Pos = 0;
I2C_AcknowledgeConfig(I2C_Dev->I2cx, DISABLE);
I2C_GenerateSTART(I2C_Dev->I2cx, ENABLE); //产生起始信号中断处理
u32TimeOut = 0;
while(I2C_Dev->DevStatus != StatusFinish)
{
u32TimeOut++;
if(u32TimeOut > 0xfffffff)
{
I2C_Dev->DevStatus = StatusFree;
return false; //等待总线超时
}
}
I2C_Dev->DevStatus = StatusFree;
return true;
}
bool I2C1_Read(uint8_t addr,uint8_t *pData,uint8_t len)
{
I2Cx_Read(&gI2C_Dev,addr,pData,len);
}
static bool I2Cx_Write(I2C_Dev_t* I2C_Dev,uint8_t addr,uint8_t *pData,uint8_t len)
{
int ret = 0;
uint32_t u32TimeOut = 0;
while(I2C_Dev->DevStatus != StatusFree)
{
u32TimeOut++;
if(u32TimeOut > 0xfffffff)
{
I2C_Dev->DevStatus = StatusFree;
return false; //等待总线超时
}
}
I2C_Dev->DevStatusRw = StatusWrite; //先置位成写状态 发送器件的地址
I2C_Dev->RegAddress = addr;
I2C_Dev->OperateByteNum = len; //写入的字节数
I2C_Dev->pData = pData;
I2C_Dev->DevStatus = StatusWr;
I2C_Dev->Pos = 0;
I2C_AcknowledgeConfig(I2C_Dev->I2cx, DISABLE);
I2C_GenerateSTART(I2C_Dev->I2cx, ENABLE); //产生起始信号中断处理
u32TimeOut = 0;
while(I2C_Dev->DevStatus != StatusFinish)
{
u32TimeOut++;
if(u32TimeOut > 0xfffffff)
{
I2C_Dev->DevStatus = StatusFree;
return false; //等待总线超时
}
}
I2C_Dev->DevStatus = StatusFree;
return true;
}
bool I2C1_Write(uint8_t addr,uint8_t *pData,uint8_t len)
{
I2Cx_Write(&gI2C_Dev,addr,pData,len);
}
void I2Cx_EV_Handler(I2C_Dev_t* I2C_Dev)
{
uint32_t SR1 = I2C_Dev->I2cx->SR1;
uint32_t SR2 = I2C_Dev->I2cx->SR2;
if( I2Cx_CheckEvent(I2C_Dev->I2cx,SR1,SR2,I2C_EVENT_MASTER_MODE_SELECT) ) //起始信号已经发送
{
if(I2C_Dev->DevStatusRw == StatusRead) //判断是否是读写的状态 发送器件地址
{
I2C_Dev->SlaveAddress |= 0x01;
}
else
{
I2C_Dev->SlaveAddress &= 0xfe;
}
I2C_Dev->I2cx->DR = I2C_Dev->SlaveAddress;
}
else if( I2Cx_CheckEvent(I2C_Dev->I2cx,SR1,SR2,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) ) //写命令发送完成
{
if(I2C_Dev->DevStatus == StatusRd)
{
I2C_SendData(I2C_Dev->I2cx, I2C_Dev->RegAddress); //发送寄存器的地址
}
else if(I2C_Dev->DevStatus == StatusWr)
{
}
}
else if(I2Cx_CheckEvent(I2C_Dev->I2cx,SR1,SR2,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) //读取命令已经发送完成
{
if(I2C_Dev->DevStatus == StatusRd)
{
if(I2C_Dev->OperateByteNum == 1)
{
I2C_AcknowledgeConfig(I2C_Dev->I2cx, DISABLE);
}
else
{
I2C_AcknowledgeConfig(I2C_Dev->I2cx, ENABLE);
}
}
}
else if( I2Cx_CheckEvent(I2C_Dev->I2cx,SR1,SR2,I2C_EVENT_MASTER_BYTE_TRANSMITTING) ) //发送寄存器为空
{
if(I2C_Dev->DevStatus == StatusRd)
{
I2C_GenerateSTART(I2C_Dev->I2cx, ENABLE); //读取再次产生起始信号
I2C_Dev->DevStatusRw = StatusRead;
}
else if(I2C_Dev->DevStatus == StatusWr)
{
I2C_SendData(I2C_Dev->I2cx, I2C_Dev->pData[I2C_Dev->Pos]);
I2C_Dev->Pos++;
I2C_Dev->OperateByteNum--;
if(I2C_Dev->OperateByteNum == 0)
{
I2C_GenerateSTOP(I2C_Dev->I2cx, ENABLE);
I2C_Dev->DevStatus = StatusFinish; //读取完成
}
}
}
else if( I2Cx_CheckEvent(I2C_Dev->I2cx,SR1,SR2,I2C_EVENT_MASTER_BYTE_RECEIVED) ) // 接收不为空
{
if( I2C_Dev->DevStatus == StatusRd)
{
I2C_Dev->pData[I2C_Dev->Pos] = I2C_ReceiveData(I2C_Dev->I2cx);
I2C_Dev->Pos++;
I2C_Dev->OperateByteNum--;
if(I2C_Dev->OperateByteNum == 1)
{
I2C_AcknowledgeConfig(I2C_Dev->I2cx, DISABLE);
}
else if(I2C_Dev->OperateByteNum == 0)
{
I2C_GenerateSTOP(I2C_Dev->I2cx, ENABLE);
I2C_Dev->DevStatus = StatusFinish; //读取完成
}
}
}
}
void I2C1_EV_IRQHandler(void)
{
I2Cx_EV_Handler(&gI2C_Dev);
}