STM32 uart 中断fifo 收发例程 标准库
时间: 2023-08-06 07:08:37 浏览: 134
STM32的USART1接收中断例程
4星 · 用户满意度95%
下面是一个基于STM32标准库的UART中断FIFO收发例程:
```c
#include "stm32f10x.h"
#include <stdio.h>
#define RX_BUFFER_SIZE 128
#define TX_BUFFER_SIZE 128
volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
volatile uint8_t rx_buffer_head = 0;
volatile uint8_t rx_buffer_tail = 0;
volatile uint8_t tx_buffer_head = 0;
volatile uint8_t tx_buffer_tail = 0;
volatile uint8_t tx_busy = 0;
void USART1_IRQHandler(void)
{
// Check if data received
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
{
// Read data from the USART and put it into the RX buffer
uint8_t data = USART_ReceiveData(USART1);
uint8_t next_head = (rx_buffer_head + 1) % RX_BUFFER_SIZE;
if (next_head != rx_buffer_tail)
{
rx_buffer[rx_buffer_head] = data;
rx_buffer_head = next_head;
}
}
// Check if data transmitted
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
{
// Send the next byte from the TX buffer
if (tx_buffer_head != tx_buffer_tail)
{
USART_SendData(USART1, tx_buffer[tx_buffer_tail]);
tx_buffer_tail = (tx_buffer_tail + 1) % TX_BUFFER_SIZE;
}
else
{
// Disable the USART TX empty interrupt if the TX buffer is empty
USART_ITConfig(USART1, USART_IT_TXE, DISABLE);
tx_busy = 0;
}
}
}
void USART1_Init(void)
{
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
// Enable the USART1 peripheral
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
// Configure the USART1 pins
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// Configure the USART1 peripheral
USART_InitStructure.USART_BaudRate = 115200;
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_Init(USART1, &USART_InitStructure);
// Enable the USART1 interrupt
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
// Enable the USART1 peripheral
USART_Cmd(USART1, ENABLE);
}
void USART1_Send(uint8_t *data, uint16_t length)
{
while (tx_busy);
tx_busy = 1;
for (uint16_t i = 0; i < length; i++)
{
uint8_t next_head = (tx_buffer_head + 1) % TX_BUFFER_SIZE;
if (next_head != tx_buffer_tail)
{
tx_buffer[tx_buffer_head] = data[i];
tx_buffer_head = next_head;
}
else
{
// TX buffer is full, wait for space to become available
while (next_head == tx_buffer_tail);
tx_buffer[tx_buffer_head] = data[i];
tx_buffer_head = next_head;
}
}
USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}
uint8_t USART1_ReadByte(void)
{
if (rx_buffer_head == rx_buffer_tail)
{
return 0; // RX buffer is empty
}
uint8_t data = rx_buffer[rx_buffer_tail];
rx_buffer_tail = (rx_buffer_tail + 1) % RX_BUFFER_SIZE;
return data;
}
int main(void)
{
USART1_Init();
while (1)
{
// Read and echo any data received
uint8_t data = USART1_ReadByte();
if (data != 0)
{
USART1_Send(&data, 1);
}
}
}
```
在此示例中,我们将接收到的数据存储在一个循环队列(FIFO)中,并在需要发送数据时将数据存储在另一个队列中。在每个USART中断中,我们检查是否有数据可用于接收和发送。如果有,我们将数据读入和写入适当的队列中。如果发送队列为空,则禁用USART的TX空中断。在主循环中,我们读取接收队列中的任何数据并将其回传。
阅读全文