引言
STM32是一款功能强大的微控制器,广泛应用于嵌入式系统中。数据传输是嵌入式系统设计中的关键部分,而串口和I2C是两种常见的通信方式。本文将带你从基础入手,了解STM32的串口和I2C通信,并提供实践指南,帮助你轻松上手。
1. STM32串口通信
1.1 串口基础
串口通信是一种串行传输数据的方式,通过TX(发送)和RX(接收)两个引脚进行数据传输。STM32的串口通信基于USART(通用同步/异步收发传输器)模块。
1.2 串口配置
- 选择USART模块:STM32有多个USART模块,根据实际需求选择合适的模块。
- 配置波特率:波特率决定了数据传输的速度,单位为bps(比特每秒)。
- 配置数据位、停止位和校验位:数据位表示数据传输的位数,停止位表示传输结束的标志,校验位用于数据校验。
1.3 串口编程
#include "stm32f10x.h"
void USART_Config(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 使能USARTx时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// 使能USARTx GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// USARTx TX配置为复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// USARTx RX配置为浮空输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 填充USART_InitStructure结构体
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
// 初始化USART
USART_Init(USART1, &USART_InitStructure);
// 使能USART
USART_Cmd(USART1, ENABLE);
}
void USART_SendChar(USART_TypeDef* USARTx, char c)
{
// 等待发送缓冲区为空
while (USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
// 发送数据
USART_SendData(USARTx, c);
}
void USART_ReceiveChar(USART_TypeDef* USARTx, char* c)
{
// 等待接收缓冲区不为空
while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);
// 读取数据
*c = USART_ReceiveData(USARTx);
}
2. STM32 I2C通信
2.1 I2C基础
I2C是一种多主从通信协议,通过两根线(SCL和SDA)进行数据传输。STM32的I2C通信基于I2C接口。
2.2 I2C配置
- 选择I2C接口:STM32有多个I2C接口,根据实际需求选择合适的接口。
- 配置时钟频率:时钟频率决定了数据传输的速度。
- 配置地址和模式:地址用于标识设备,模式包括标准模式和快速模式。
2.3 I2C编程
#include "stm32f10x.h"
void I2C_Config(void)
{
I2C_InitTypeDef I2C_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
// 使能I2Cx时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
// 使能I2Cx GPIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
// I2Cx SCL配置为复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// I2Cx SDA配置为复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// 填充I2C_InitStructure结构体
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_Acknowledgemode = I2C_Acknowledgemode_Fast;
I2C_InitStructure.I2C_ClockSpeed = 100000;
// 初始化I2C
I2C_Init(I2C1, &I2C_InitStructure);
// 使能I2C
I2C_Cmd(I2C1, ENABLE);
}
void I2C_Start(void)
{
// 发送起始信号
I2C_GenerateSTART(I2C1, ENABLE);
// 等待起始信号发送完成
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT) == RESET);
}
void I2C_Stop(void)
{
// 发送停止信号
I2C_GenerateSTOP(I2C1, ENABLE);
// 等待停止信号发送完成
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_RESET) == RESET);
}
void I2C_SendByte(uint8_t byte)
{
// 发送数据
I2C_SendData(I2C1, byte);
// 等待数据发送完成
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED) == RESET);
}
uint8_t I2C_ReceiveByte(void)
{
// 接收数据
I2C_AcknowledgeConfig(I2C1, ENABLE);
// 等待数据接收完成
while (I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED) == RESET);
// 读取数据
uint8_t byte = I2C_ReceiveData(I2C1);
// 禁用应答信号
I2C_AcknowledgeConfig(I2C1, DISABLE);
return byte;
}
3. 总结
通过本文的学习,相信你已经对STM32的串口和I2C通信有了更深入的了解。在实际应用中,根据需求选择合适的通信方式,并熟练掌握编程技巧,将有助于提高嵌入式系统的性能和稳定性。希望本文对你有所帮助!
