引言
I2C(Inter-Integrated Circuit)是一种串行通信协议,常用于在多个电子设备之间进行通信。在单片机中,I2C通信常用于连接传感器、存储器、显示屏等外部设备。本文将介绍单片机中使用I2C总线进行通信的实例。
I2C通信原理
I2C总线由两根线组成:SCL(时钟线)和SDA(数据线)。SCL由主设备产生和控制,用于同步数据传输。SDA用于双向传输数据。每个设备在总线上都有唯一的地址,可以让主设备通过地址选择要与之通信的设备。
I2C库函数的使用
许多单片机厂商都提供了用于配置和控制I2C总线通信的库函数。以STMicroelectronics的STM32微控制器为例,使用其标准固件库(StdPeriph Library)中的I2C库函数可以轻松实现I2C通信。
步骤1:初始化I2C总线
首先需要初始化I2C总线,设置通信速率、配置GPIO引脚等。
#include "stm32f10x.h"
#include "stm32f10x_i2c.h"
void I2C_Configuration()
{
I2C_InitTypeDef I2C_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // 使能I2C1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // 使能GPIOB时钟
// 配置I2C GPIO引脚
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStruct);
// 配置I2C通信参数
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStruct.I2C_OwnAddress1 = 0x00;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStruct.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &I2C_InitStruct);
I2C_Cmd(I2C1, ENABLE); // 使能I2C1
}
步骤2:发送数据
使用库函数I2C_SendData()
发送数据。以下是一个简单的发送数据的示例:
void I2C_SendData(uint8_t data)
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, slave_address, I2C_Direction_Transmitter);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, data);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
}
步骤3:接收数据
使用库函数I2C_ReceiveData()
接收数据。以下是一个简单的接收数据的示例:
uint8_t I2C_ReceiveData()
{
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, slave_address, I2C_Direction_Receiver);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
uint8_t data = I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1, ENABLE);
return data;
}
I2C通信实例:读取温度传感器数据
现在我们使用I2C总线通信的例子,读取连接在单片机上的温度传感器(例如LM75)的数据。
首先,需要查看传感器的数据手册,找到其I2C地址。假设传感器的地址是0x90。
然后,编写代码读取温度传感器的数据:
#include "stdio.h"
uint8_t slave_address = 0x90; // 温度传感器的地址
float read_temperature()
{
// 向温度传感器发送读取数据的命令
I2C_SendData(0x00); // 发送命令寄存器地址
// 接收温度传感器的数据
uint8_t high_byte, low_byte;
high_byte = I2C_ReceiveData();
low_byte = I2C_ReceiveData();
// 计算温度值
int16_t temperature_raw = (high_byte << 8) | low_byte;
float temperature = temperature_raw / 256.0;
return temperature;
}
int main()
{
I2C_Configuration();
float temperature = read_temperature();
printf("当前温度:%.2f℃\n", temperature);
return 0;
}
结论
本文介绍了单片机中使用I2C总线通信的实例。通过配置和控制I2C总线,我们可以轻松实现与各种外部设备的通信,如传感器、存储器等。希望本文对初学者理解和应用I2C通信有所帮助。
本文来自极简博客,作者:前端开发者说,转载请注明原文链接:单片机的I2C总线通信实例