#include "i2c_drv.h"
#include "usart_drv.h"
I2C_HandleTypeDef i2c1;
I2C_HandleTypeDef i2c2;
DMA_HandleTypeDef i2c1_txdma;
DMA_HandleTypeDef i2c1_rxdma;
//uint8_t wdata[16] ={2,2,3,4,5,6,7,8,1,2,3,4,5,6,7,12}; //给从机发送数据
//uint8_t rdata[16] ={0}; //读取从机的数据
uint16_t i ;
uint8_t rx_flag=0;
uint8_t tx_data[21]={"01234567890abcdef123"};
uint8_t rx_data[20]={0}; //接收缓冲区必需大于主机发送数据量,否则会一直进入中断
uint8_t tx_data2[21]={"01234567890abcdef123"};
uint8_t rx_data2[20]={0};
//uint8_t reg_data[1];
#define slave_addr (0x01<<1)
#define slave_addr2 (0x02<<1)
void i2c_reset();
void I2C_Drv_Init(void)
{
uint8_t i;
i2c1.Instance = I2C1;
i2c1.Init.Timing=0x00602173;
//i2c1.Init.Timing = 0xC010EBFF;
i2c1.Init.OwnAddress1 = slave_addr; //从机地址
i2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
i2c1.Init.DualAddressMode = I2C_DUALADDRESS_ENABLE;
i2c1.Init.OwnAddress2 = slave_addr2;
i2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
i2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&i2c1);
i2c2.Instance = I2C2;
i2c2.Init.Timing=0x00602173;
//i2c1.Init.Timing = 0xC010EBFF;
i2c2.Init.OwnAddress1 = slave_addr; //从机地址
i2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
i2c2.Init.DualAddressMode = I2C_DUALADDRESS_ENABLE;
i2c2.Init.OwnAddress2 = slave_addr2;
i2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
i2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
// HAL_I2C_Init(&i2c2);
// for(i=0;i<21;i++)
// {
// tx_data[i]=21-i;
// }
//
// for(i=0;i<21;i++)
// {
// tx_data2[i]=21-i;
// }
HAL_I2C_EnableListen_IT(&i2c1); //启动侦听地址
HAL_I2C_EnableListen_IT(&i2c2); //启动侦听地址
}
void I2C_Drv_Init2(void)
{
i2c2.Instance = I2C2;
i2c2.Init.Timing=0x00602173;
//i2c1.Init.Timing = 0xC010EBFF;
i2c2.Init.OwnAddress1 = slave_addr; //从机地址
i2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
i2c2.Init.DualAddressMode = I2C_DUALADDRESS_ENABLE;
i2c2.Init.OwnAddress2 = slave_addr2;
i2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
i2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&i2c2);
HAL_I2C_EnableListen_IT(&i2c2); //启动侦听地址
}
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
{
GPIO_InitTypeDef GPIO_InitTypeDefStructur;
if(hi2c ->Instance == I2C1)
{
__HAL_RCC_I2C1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitTypeDefStructur.Pin =GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitTypeDefStructur.Mode = GPIO_MODE_AF_OD;
GPIO_InitTypeDefStructur.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitTypeDefStructur.Pull=GPIO_NOPULL;
GPIO_InitTypeDefStructur.Alternate=GPIO_AF6_I2C1;
HAL_GPIO_Init(GPIOB,&GPIO_InitTypeDefStructur);
HAL_NVIC_SetPriority(I2C1_IRQn,0,2);
HAL_NVIC_EnableIRQ(I2C1_IRQn);
__I2C1_FORCE_RESET();
__I2C1_RELEASE_RESET();
hi2c->Instance->CR1 = I2C_CR1_SWRST; //复位I2C
hi2c->Instance->CR1 = 0; //解除复位
// //I2C RX
// i2c1_txdma.Instance = DMA1_Channel2;
// i2c1_txdma.Init.Request = DMA_REQUEST_I2C1_TX;
// i2c1_txdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
// i2c1_txdma.Init.PeriphInc = DMA_PINC_DISABLE;
// i2c1_txdma.Init.MemInc = DMA_MINC_ENABLE;
// i2c1_txdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
// i2c1_txdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
// i2c1_txdma.Init.Mode = DMA_NORMAL;
// i2c1_txdma.Init.Priority = DMA_PRIORITY_MEDIUM;
// __HAL_LINKDMA(hi2c,hdmatx,i2c1_txdma);
// HAL_DMA_Init(&i2c1_txdma);
//
// //I2C RX
// i2c1_rxdma.Instance = DMA1_Channel3;
// i2c1_rxdma.Init.Request = DMA_REQUEST_I2C1_RX;
// i2c1_rxdma.Init.Direction = DMA_PERIPH_TO_MEMORY;
// i2c1_rxdma.Init.PeriphInc = DMA_PINC_DISABLE;
// i2c1_rxdma.Init.MemInc = DMA_MINC_ENABLE;
// i2c1_rxdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
// i2c1_rxdma.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
// i2c1_rxdma.Init.Mode = DMA_NORMAL;
// i2c1_rxdma.Init.Priority = DMA_PRIORITY_MEDIUM;
// __HAL_LINKDMA(hi2c,hdmarx,i2c1_rxdma);
// HAL_DMA_Init(&i2c1_rxdma);
// HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
}
if(hi2c ->Instance == I2C2)
{
__HAL_RCC_I2C2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDefStructur.Pin =GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitTypeDefStructur.Mode = GPIO_MODE_AF_OD;
GPIO_InitTypeDefStructur.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitTypeDefStructur.Pull=GPIO_PULLUP;
GPIO_InitTypeDefStructur.Alternate=GPIO_AF6_I2C2;
HAL_GPIO_Init(GPIOA,&GPIO_InitTypeDefStructur);
HAL_NVIC_SetPriority(I2C2_IRQn,0,1);
HAL_NVIC_EnableIRQ(I2C2_IRQn);
__I2C2_FORCE_RESET();
__I2C2_RELEASE_RESET();
hi2c->Instance->CR1 = I2C_CR1_SWRST; //复位I2C
hi2c->Instance->CR1 = 0;
}
}
void i2c_reset()
{
/* 开漏输出,关闭I2C输入通道,并尝试将总线拉高 */
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8 | GPIO_PIN_9, GPIO_PIN_SET);
// SCL PB8 拉高
for (uint8_t i = 0; i < 10; i++) {
if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8) == GPIO_PIN_SET)
{
//rt_kprintf("retry %d\n", i);
break;
}
/* 该延时循环的周期和时长,请根据你的实际主机对I2C通讯出错的处理来修改 */
HAL_Delay(10);
}
/* 归还总线控制权 */
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* 复位I2C */
i2c1.Instance->CR1 |= I2C_CR1_SWRST;
i2c1.Instance->CR1 &= ~I2C_CR1_SWRST;
/* 重新初始化I2C */
I2C_Drv_Init();
}
//侦听完成
void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c)
{
if(hi2c ->Instance == I2C1)
{
HAL_I2C_EnableListen_IT(&i2c1); //启动侦听地址
u1_printf("I2C1侦听地址完成\r\n");
}
else if(hi2c ->Instance == I2C2)
{
HAL_I2C_EnableListen_IT(&i2c2); //启动侦听地址
u1_printf("I2C2侦听地址完成\r\n");
}
}
void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode)
{
if(hi2c ->Instance == I2C1)
{
if((AddrMatchCode == slave_addr) || (AddrMatchCode == slave_addr2))
{
if(TransferDirection ==I2C_DIRECTION_RECEIVE) //准备给主机发送数据
{
if(rx_data[0]==0x01)
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c1,tx_data,2,I2C_LAST_FRAME);
//HAL_I2C_Slave_Transmit_IT(&i2c1,tx_data,1);
}
if(rx_data[0]==0x08)
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c1,&tx_data[3],2,I2C_LAST_FRAME);
}
if(rx_data[0]==0x21)
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c2,tx_data,21,I2C_LAST_FRAME);
}
else
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c1,&tx_data[3],2,I2C_LAST_FRAME);
}
//HAL_I2C_Slave_Transmit_DMA(&i2c1,wdata,16);
// HAL_I2C_Slave_Transmit_IT(&i2c1,tx_data[1],2);
}else if(TransferDirection == I2C_DIRECTION_TRANSMIT ) //准备接收主机的数据
{
HAL_I2C_Slave_Seq_Receive_IT(&i2c1,rx_data,1,I2C_FIRST_FRAME);
}
}
}
if(hi2c ->Instance == I2C2)
{
if((AddrMatchCode == slave_addr) || (AddrMatchCode == slave_addr2))
{
if(TransferDirection ==I2C_DIRECTION_RECEIVE) //准备给主机发送数据
{
if(rx_data2[0]==0x01)
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c2,tx_data2,2,I2C_LAST_FRAME);
//HAL_I2C_Slave_Transmit_IT(&i2c1,tx_data,1);
}
else if(rx_data2[0]==0x08)
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c2,&tx_data2[3],2,I2C_LAST_FRAME);
}
else if(rx_data2[0]==0x09)
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c2,&tx_data2[5],2,I2C_LAST_FRAME);
}
else if(rx_data2[0]==0x21)
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c2,tx_data2,21,I2C_LAST_FRAME);
}
else
{
HAL_I2C_Slave_Seq_Transmit_IT(&i2c2,&tx_data2[7],2,I2C_LAST_FRAME);
}
}else if(TransferDirection == I2C_DIRECTION_TRANSMIT ) //准备接收主机的数据
{
HAL_I2C_Slave_Seq_Receive_IT(&i2c2,rx_data2,1,I2C_FIRST_FRAME);
}
}
}
}
//从机发送完成
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if(hi2c ->Instance == I2C1)
{
// hi2c ->PreviousState = HAL_I2C_MODE_NONE;
u1_printf("从机发送完成\r\n");
}
if(hi2c ->Instance == I2C2)
{
// hi2c ->PreviousState = HAL_I2C_MODE_NONE;
u1_printf("从机发送完成\r\n");
}
}
//从机接收完成
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
if(hi2c ->Instance == I2C1)
{
hi2c ->PreviousState = HAL_I2C_MODE_NONE;
//
// u1_printf("从机接收中断完成 %d\r\n",__HAL_I2C_GET_FLAG(hi2c,I2C_FLAG_BUSY));
//u1_printf("从机接收完成 %d\r\n",rx_data[0]);
rx_flag=0;
// if(rx_data[0] == 0x01)
// {
// HAL_I2C_Slave_Seq_Transmit_IT(&i2c1,tx_data,1,I2C_FIRST_AND_LAST_FRAME);
// }
u1_printf("rx_data%X\r\n",rx_data[0]);
}
else if(hi2c ->Instance == I2C2){
u1_printf("OK2\n") ;
//u1_printf("从机接收完成 %d\r\n",rx_data[0]);
}
}
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c)
{
if(hi2c ->Instance == I2C1)
{
// i2c_reset();
// I2C_Drv_Init();
}
}