stm32F103 串口中断驱动
时间: 2023-07-12 18:59:20 浏览: 101
stm32 串口中断程序
使用中断驱动的方式可以提高串口通信的效率和稳定性,因为它可以在数据接收或发送完成后立即中断CPU,从而及时处理数据。
下面是一个使用中断驱动的串口程序,用于通过USART1进行数据的发送和接收。
```c
#include "stm32f10x.h"
#include <string.h>
#define BUF_SIZE 64
uint8_t rx_buf[BUF_SIZE]; // 接收缓冲区
uint8_t tx_buf[BUF_SIZE]; // 发送缓冲区
uint8_t rx_pos = 0; // 接收缓冲区当前位置
uint8_t tx_pos = 0; // 发送缓冲区当前位置
void USART1_Init(void)
{
// 使能USART1和GPIOA的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA9为USART1的TX引脚
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置PA10为USART1的RX引脚
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置USART1的参数:波特率、数据位、停止位、校验位等
USART_InitTypeDef USART_InitStruct;
USART_InitStruct.USART_BaudRate = 115200;
USART_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_InitStruct.USART_StopBits = USART_StopBits_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);
// 配置USART1的中断
NVIC_InitTypeDef NVIC_InitStruct;
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);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); // 使能USART1的接收中断
// 使能USART1
USART_Cmd(USART1, ENABLE);
}
void USART1_SendString(char *str)
{
uint8_t len = strlen(str);
for (int i = 0; i < len; i++) {
tx_buf[i] = str[i];
}
tx_pos = 0;
USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 使能USART1的发送中断
}
void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { // 接收中断
rx_buf[rx_pos++] = USART_ReceiveData(USART1);
if (rx_pos >= BUF_SIZE) {
rx_pos = 0;
}
}
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) { // 发送中断
USART_SendData(USART1, tx_buf[tx_pos++]);
if (tx_pos >= BUF_SIZE) {
tx_pos = 0;
USART_ITConfig(USART1, USART_IT_TXE, DISABLE); // 禁止USART1的发送中断
}
}
}
int main(void)
{
// 初始化USART1
USART1_Init();
// 发送一条字符串
char str[] = "Hello, world!\r\n";
USART1_SendString(str);
while(1);
}
```
在这个程序中,我们首先定义了一个接收缓冲区`rx_buf`和一个发送缓冲区`tx_buf`,以及它们的当前位置`rx_pos`和`tx_pos`。然后在`USART1_Init`函数中,我们配置了USART1的参数和中断。其中,`NVIC_InitTypeDef`结构体用于配置中断优先级和使能中断。
在`USART1_SendString`函数中,我们将输入的字符串复制到发送缓冲区`tx_buf`中,并使能USART1的发送中断。
在中断处理函数`USART1_IRQHandler`中,我们先判断是接收中断还是发送中断,并根据情况进行处理。在接收中断中,我们将接收到的数据存储到接收缓冲区`rx_buf`中,并更新当前位置`rx_pos`。在发送中断中,我们将发送缓冲区`tx_buf`中的数据发送出去,并更新当前位置`tx_pos`。当发送缓冲区发送完毕后,我们禁止USART1的发送中断。
在主函数中,我们首先调用`USART1_Init`函数进行初始化。然后通过`USART1_SendString`函数发送一条字符串。最后进入死循环。当有数据接收或发送完成时,中断处理函数`USART1_IRQHandler`会被调用,从而及时处理数据。
阅读全文