STM32F103C8T6 标准库 硬件IIC中断主机读取设备调试代码

/***********************************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);
}

 

  

posted @ 2020-11-26 13:47  $(越来越不懂)  阅读(1290)  评论(0)    收藏  举报