stm32双串口rtthread程序
时间: 2023-08-31 15:08:41 浏览: 75
以下是一个基于RT-Thread的双串口STM32程序示例:
```c
#include <rtthread.h>
#include "stm32f10x.h"
#define USART1_GPIO_TX GPIO_Pin_9
#define USART1_GPIO_RX GPIO_Pin_10
#define USART2_GPIO_TX GPIO_Pin_2
#define USART2_GPIO_RX GPIO_Pin_3
#define USART1_RX_BUFSIZE 128
#define USART2_RX_BUFSIZE 128
static rt_uint8_t usart1_rx_buffer[USART1_RX_BUFSIZE];
static rt_uint8_t usart2_rx_buffer[USART2_RX_BUFSIZE];
static struct rt_semaphore usart1_rx_sem;
static struct rt_semaphore usart2_rx_sem;
static struct rt_serial_device serial1;
static struct rt_serial_device serial2;
static void USART1_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = USART1_GPIO_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = USART1_GPIO_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
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);
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
}
static void USART2_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
GPIO_InitStructure.GPIO_Pin = USART2_GPIO_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = USART2_GPIO_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
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(USART2, &USART_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
static rt_err_t serial1_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = cfg->baud_rate;
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;
if (cfg->data_bits == DATA_BITS_9) {
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
}
if (cfg->stop_bits == STOP_BITS_2) {
USART_InitStructure.USART_StopBits = USART_StopBits_2;
}
if (cfg->parity == PARITY_ODD) {
USART_InitStructure.USART_Parity = USART_Parity_Odd;
} else if (cfg->parity == PARITY_EVEN) {
USART_InitStructure.USART_Parity = USART_Parity_Even;
}
USART_Init(USART1, &USART_InitStructure);
return RT_EOK;
}
static rt_err_t serial2_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = cfg->baud_rate;
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;
if (cfg->data_bits == DATA_BITS_9) {
USART_InitStructure.USART_WordLength = USART_WordLength_9b;
}
if (cfg->stop_bits == STOP_BITS_2) {
USART_InitStructure.USART_StopBits = USART_StopBits_2;
}
if (cfg->parity == PARITY_ODD) {
USART_InitStructure.USART_Parity = USART_Parity_Odd;
} else if (cfg->parity == PARITY_EVEN) {
USART_InitStructure.USART_Parity = USART_Parity_Even;
}
USART_Init(USART2, &USART_InitStructure);
return RT_EOK;
}
static rt_err_t serial1_control(struct rt_serial_device *serial, int cmd, void *arg)
{
switch (cmd) {
case RT_DEVICE_CTRL_CLR_INT:
USART_ITConfig(USART1, USART_IT_RXNE, DISABLE);
break;
case RT_DEVICE_CTRL_SET_INT:
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
break;
}
return RT_EOK;
}
static rt_err_t serial2_control(struct rt_serial_device *serial, int cmd, void *arg)
{
switch (cmd) {
case RT_DEVICE_CTRL_CLR_INT:
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
break;
case RT_DEVICE_CTRL_SET_INT:
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
break;
}
return RT_EOK;
}
static int serial1_putc(struct rt_serial_device *serial, char c)
{
USART_SendData(USART1, (uint16_t)c);
while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
return 1;
}
static int serial2_putc(struct rt_serial_device *serial, char c)
{
USART_SendData(USART2, (uint16_t)c);
while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
return 1;
}
static int serial1_getc(struct rt_serial_device *serial)
{
rt_int32_t ch = -1;
rt_sem_take(&usart1_rx_sem, RT_WAITING_FOREVER);
if (serial1.rx_index > 0) {
ch = serial1.rx_buffer[0];
rt_memcpy(serial1.rx_buffer, serial1.rx_buffer + 1, serial1.rx_index - 1);
serial1.rx_index--;
}
return ch;
}
static int serial2_getc(struct rt_serial_device *serial)
{
rt_int32_t ch = -1;
rt_sem_take(&usart2_rx_sem, RT_WAITING_FOREVER);
if (serial2.rx_index > 0) {
ch = serial2.rx_buffer[0];
rt_memcpy(serial2.rx_buffer, serial2.rx_buffer + 1, serial2.rx_index - 1);
serial2.rx_index--;
}
return ch;
}
static const struct rt_uart_ops serial1_ops = {
serial1_configure,
serial1_control,
serial1_putc,
serial1_getc,
};
static const struct rt_uart_ops serial2_ops = {
serial2_configure,
serial2_control,
serial2_putc,
serial2_getc,
};
static void USART1_IRQHandler(void)
{
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
rt_int32_t ch = USART_ReceiveData(USART1);
if (serial1.rx_index < USART1_RX_BUFSIZE) {
serial1.rx_buffer[serial1.rx_index++] = ch;
}
rt_sem_release(&usart1_rx_sem);
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
static void USART2_IRQHandler(void)
{
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
rt_int32_t ch = USART_ReceiveData(USART2);
if (serial2.rx_index < USART2_RX_BUFSIZE) {
serial2.rx_buffer[serial2.rx_index++] = ch;
}
rt_sem_release(&usart2_rx_sem);
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
}
}
void usart_init(void)
{
rt_sem_init(&usart1_rx_sem, "usart1_rx", 0, RT_IPC_FLAG_FIFO);
rt_sem_init(&usart2_rx_sem, "usart2_rx", 0, RT_IPC_FLAG_FIFO);
USART1_Configuration();
USART2_Configuration();
rt_memset(&serial1, 0, sizeof(serial1));
rt_memset(&serial2, 0, sizeof(serial2));
serial1.ops = &serial1_ops;
serial1.config.baud_rate = 115200;
serial1.config.data_bits = DATA_BITS_8;
serial1.config.stop_bits = STOP_BITS_1;
serial1.config.parity = PARITY_NONE;
serial2.ops = &serial2_ops;
serial2.config.baud_rate = 115200;
serial2.config.data_bits = DATA_BITS_8;
serial2.config.stop_bits = STOP_BITS_1;
serial2.config.parity = PARITY_NONE;
rt_hw_serial_register(&serial1, "usart1", RT_DEVICE_FLAG_RDWR);
rt_hw_serial_register(&serial2, "usart2", RT_DEVICE_FLAG_RDWR);
}
```
该程序中使用了RT-Thread的串口设备框架,同时实现了双串口接收中断,并通过信号量来触发接收完成事件。在初始化时,定义了两个串口设备serial1和serial2,分别对应USART1和USART2。在serial1和serial2的配置、控制、读写函数中,分别对应了STM32的USART1和USART2。在USART1_IRQHandler和USART2_IRQHandler中,分别判断是否是接收中断,并将接收到的字符存储到对应的缓冲区中,并通过信号量触发接收完成事件。最后,通过rt_hw_serial_register将serial1和serial2注册为RT-Thread串口设备,实现对串口的操作。
阅读全文