stm32f103c8t6串口1使用中断数据收发代码
时间: 2023-08-03 16:02:44 浏览: 171
下面是一个使用中断方式进行数据收发的 STM32F103C8T6(蓝板)串口1示例代码:
```c
#include "stm32f10x.h"
#include <stdio.h>
// 缓冲区大小
#define BUFFER_SIZE 128
// 接收缓冲区
volatile char rxBuffer[BUFFER_SIZE];
// 发送缓冲区
volatile char txBuffer[BUFFER_SIZE];
// 接收缓冲区读写索引
volatile uint8_t rxIndex = 0;
// 发送缓冲区读写索引
volatile uint8_t txIndex = 0;
void USART1_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct;
USART_InitTypeDef USART_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
// 使能串口1和GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置USART1引脚
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; // USART1 Tx (PA9)
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; // 复用推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; // USART1 Rx (PA10)
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; // 浮空输入
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置USART1参数
USART_InitStruct.USART_BaudRate = 9600; // 波特率为9600
USART_InitStruct.USART_WordLength = USART_WordLength_8b; // 数据位长度为8位
USART_InitStruct.USART_StopBits = USART_StopBits_1; // 停止位为1位
USART_InitStruct.USART_Parity = USART_Parity_No; // 无奇偶校验
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // 无硬件流控制
USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // 同时使能接收和发送
USART_Init(USART1, &USART_InitStruct);
// 使能接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
// 配置中断优先级
NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
// 使能USART1
USART_Cmd(USART1, ENABLE);
}
void USART1_SendChar(char c) {
// 将字符放入发送缓冲区
txBuffer[txIndex++] = c;
// 如果发送缓冲区已满,则等待
if (txIndex >= BUFFER_SIZE) {
txIndex = 0;
}
// 使能发送中断
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
char USART1_GetChar(void) {
char c;
// 如果接收缓冲区为空,则返回空字符
if (rxIndex == txIndex) {
return '\0';
}
// 从接收缓冲区读取一个字符
c = rxBuffer[rxIndex++];
// 如果接收缓冲区已满,则重置读写索引
if (rxIndex >= BUFFER_SIZE) {
rxIndex = 0;
}
return c;
}
void USART1_IRQHandler(void) {
// 接收中断处理
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
// 读取接收数据寄存器
char data = USART_ReceiveData(USART1);
// 将数据存入接收缓冲区
rxBuffer[txIndex++] = data;
// 如果接收缓冲区已满,则重置读写索引
if (rxIndex >= BUFFER_SIZE) {
rxIndex = 0;
}
}
// 发送中断处理
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) {
// 如果发送缓冲区不为空,则发送下一个字符
if (txIndex != rxIndex) {
// 从发送缓冲区读取一个字符并发送
USART_SendData(USART1, txBuffer[txIndex++]);
// 如果发送缓冲区已满,则重置读写索引
if (txIndex >= BUFFER_SIZE) {
txIndex = 0;
}
} else {
// 发送缓冲区已空,禁用发送中断
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
}
}
}
int main(void) {
char receivedChar;
// 初始化串口1
USART1_Init();
while (1) {
// 接收字符
receivedChar = USART1_GetChar();
// 发送接收到的字符
USART1_SendChar(receivedChar);
// 延时一段时间
for (int i = 0; i < 1000000; i++);
}
}
```
这段代码使用了中断方式来处理串口数据的接收和发送。在 `USART1_IRQHandler()` 函数中,通过检查中断标志位来判断是接收中断还是发送中断,并进行相应的处理。
在 `USART1_SendChar()` 函数中,将要发送的字符存入发送缓冲区,并在发送缓冲区为空时启用发送中断,以便进行数据发送。
在 `USART1_GetChar()` 函数中,从接收缓冲区读取字符,并在接收缓冲区为空时返回空字符。如果接收缓冲区满了,则重置读写索引。
请注意,这只是一个简单的示例代码,用于演示如何使用中断方式进行串口数据收发。你可以根据自己的需求进行修改和扩展。
阅读全文