STM32F103硬件I2C主机发送数据和接收数据完整代码,亲测可用。
1.初始化I2C引脚。I2C1_Init(void),代码如下:
#include "t_I2C.h"
#include "stm32f10x_i2c.h"
#include "usart.h"
/***********************************************************
*全局变量定义*
***********************************************************/
#define I2C_OK 0
#define I2C_FAIL -1
#define I2C_LONG_TIMEOUT 1000//I2C时间超时
vu8 Tx_Idx = 0, Rx_Idx = 0, PEC_Value = 0;//计数
/****************************************************************************************************/
/**************************************************
函数名:I2C1_Init
功 能:I2C初始化
参 数:无
返回值:无
**************************************************/
void I2C1_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
/* 对应IO口的初始化 ----------------------------------------*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_Cmd(I2C1, ENABLE);
/* I2C1 configuration ------------------------------------------------------*/
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x30;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &I2C_InitStructure);
}
2.主机发送数据代码段如下:
/**************************************************
函数名:I2C1_Master_BufferWrite
功 能:主机发送数据
参 数:I2C1_SLAVE_ADDRESS7:从机地址
I2Cx: I2C
buf: 发送的数据buffer
len: 发送的数据长度
返回值:无
**************************************************/
uint8_t I2C1_Master_BufferWrite(I2C_TypeDef * I2Cx,uint8_t I2C_SLAVE_ADDRESS7, uint8_t *buf, uint8_t len)
{
int32_t i2c_timeout;//I2C超时定义
int8_t ret = I2C_OK;
/*----- 主机发送过程 -----*/
i2c_timeout = I2C_LONG_TIMEOUT;
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY))//检测I2C总线是否占线
{
if((i2c_timeout--) == 0)
{
ret = -1;
}
}
// printf("\r\n-----------I2C BUS State:%d--------------\r\n",I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2Cx, ENABLE);/* 发送起始条件 */
printf("\r\n-----------Send START Condition --------------\r\n");
i2c_timeout = I2C_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)) /*检测I2C1事件 EV5 并清除它*/
{
if((i2c_timeout--) == 0)
{
ret = -2;
goto I2CW_ERR;
}
}
I2C_Send7bitAddress(I2Cx, I2C_SLAVE_ADDRESS7, I2C_Direction_Transmitter);/*发送I2C从机地址*/
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))/* 检测I2C1事件EV6 并清除*/
{
if((i2c_timeout--) == 0)
{
ret = -3;
goto I2CW_ERR;
}
}
i2c_timeout = I2C_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING))//检测事件EV8
{
if((i2c_timeout--) == 0)
{
ret = -4;
goto I2CW_ERR;
}
}
while (Tx_Idx < len)
{
if(Tx_Idx == len - 1)
{
I2C_SendData(I2Cx, buf[Tx_Idx]);
printf("\r\n-----------DATA:%d-----------\r\n",buf[Tx_Idx]);
i2c_timeout = I2C_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED))//检测事件EV8-2
{
if((i2c_timeout--) == 0)
{
ret = -6;
goto I2CW_ERR;
}
}
//I2C_GenerateSTOP(I2C1, ENABLE);
Tx_Idx = 0;//发送计数清零
break;
}
printf("\r\n-----------DATA:%d-----------\r\n",buf[Tx_Idx]);
I2C_SendData(I2Cx, buf[Tx_Idx++]);
i2c_timeout = I2C_FLAG_TIMEOUT;
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTING))//检测事件EV8
{
if((i2c_timeout--) == 0)
{
ret = -5;
goto I2CW_ERR;
}
}
}
I2CW_ERR:
printf("\r\n-----------STOP--------------\r\n");
I2C_GenerateSTOP(I2Cx, ENABLE);/* 发送停止条件*/
return ret;
}
3.主机接收数据代码段如下:
/**************************************************
函数名:I2C_Master_BufferRead
功 能:主机接收数据
参 数:I2Cx: I2C
SlaveAddress: 从机地址
pBuffer: 接收的数据buffer
NumByteToRead:接收的数据长度
返回值:return: 0或1
**************************************************/
uint8_t I2C_Master_BufferRead(I2C_TypeDef * I2Cx, uint8_t SlaveAddress, uint8_t* pBuffer, uint32_t NumByteToRead)
{
if(NumByteToRead==0)
return 1;
while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
I2C_AcknowledgeConfig(I2Cx, ENABLE);
/* 3.开始*/
I2C_GenerateSTART(I2Cx, ENABLE);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
/* 4.设备地址·/读 */
I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* 5.连续写数据 */
while (NumByteToRead)
{
if(NumByteToRead==1)
{
I2C_AcknowledgeConfig(I2Cx, DISABLE);
I2C_GenerateSTOP(I2Cx, ENABLE);//6.停止,非应答
}
while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
*pBuffer++ = I2C_ReceiveData(I2Cx);
NumByteToRead--;
}
I2C_AcknowledgeConfig(I2Cx, ENABLE);
return 0;
}
4.main主函数如下:
int main(void)
{
//系统初始化
ModuleInit();
I2C_TWO_BOARD_RECEIVE_Init();
delay_init();
while(1)
{
printf("\r\n*****************************开始程序**************************************\r\n");
//I2C1_Master_BufferWrite(I2C1,0x30,I2C_Buffer,4);
// //delay_ms(10);
// I2C_Master_BufferRead(I2C1,0x30,I2C1_Buffer_Rx,4);
//
// printf("\r\n I2C1_Buffer_Rx[0] : %d \r\n",I2C1_Buffer_Rx[0]);
// printf("\r\n I2C1_Buffer_Rx[1] : %d \r\n",I2C1_Buffer_Rx[1]);
// printf("\r\n I2C1_Buffer_Rx[2] : %d \r\n",I2C1_Buffer_Rx[2]);
// printf("\r\n I2C1_Buffer_Rx[3] : %d \r\n",I2C1_Buffer_Rx[3]);
//
// printf("\r\n-----------I2C BUS State:%d--------------\r\n",I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
delay_ms(1000);
printf("\r\n*****************************结束程序**************************************\r\n");
}
}
5.源程序下载地址:STM32F103 I2C主机收发数据