上一个帖子是《UART的RX中断接收延时函数导致main函数无法正常运行?》
使用的方式是创建UART中断RX接收数据线程,但是不能使用rt_thread_mdelay函数导致我不能运行多任务。
链接:https://club.rt-thread.org/ask/question/434651.html
**现在使用中断信号量的方式,****优点是不需要使用rt_thread_mdelay函数。但是出现了,接收数据丢失的现象。**
同样也是参考了网上的教程:https://www.freesion.com/article/8553339673/
[tupian.png](https://oss-club.rt-thread.org/uploads/20220216/d7a9f93e6ff9c039a9c1957ed12b4861.png)
代码如下所示:
```
/* 接收数据回调函数 */
static rt_err_t uart_input(rt_device_t dev, rt_size_t size)
{
/* 串口接收到数据后产生中断,调用此回调函数,然后发送接收信号量 */
rt_sem_release(&rx_sem);
return RT_EOK;
}
static void serial_thread_entry(void *parameter)
{
char ch;
while (true)
{
/* 从串口读取一个字节的数据,没有读取到则等待接收信号量 */
while (rt_device_read(serial, -1, &ch, 1) != 1)
{
/* 阻塞等待接收信号量,等到信号量后再次读取数据 */
rt_sem_take(&rx_sem, RT_WAITING_FOREVER);
}
/* 读取到的数据通过串口输出 */
rt_device_write(serial, 0, &ch, 1);
}
}
/* 线程 */
int thread_serial(void)
{
rt_err_t ret = RT_EOK;
/* 查找串口设备 */
serial = rt_device_find(SAMPLE_UART_NAME);
if (!serial)
{
log_d("find %s failed!\n", SAMPLE_UART_NAME);
return RT_ERROR;
}
/* 初始化信号量 */
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
/* 以读写及中断接收方式打开串口设备 */
rt_device_open(serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
/* 设置接收回调函数 */
rt_device_set_rx_indicate(serial, uart_input);
/* 发送字符串 */
rt_device_write(serial, 0, str, (sizeof(str) - 1));
/* 创建 serial 线程 */
rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 2048, 10, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
}
else
{
ret = RT_ERROR;
}
return ret;
}
// 主函数main
int main(void)
{
// 开启UART的RX接收中断线程
thread_serial();
while (1)
{
do_someting();
rt_thread_mdelay(10);
}
}
rtt 使用串口时默认的参数是 115200 8n1,这部分是在 components/drivers/include/drivers/serial.h 中定义的,如下所示。在 rt_hw_usart_init() 函数中进行串口设备注册时就指定了串口的默认通讯参数 115200 8n1(所以你串口调试助手使用的波特率是921600,和开发板串口的波特率不一致)
#define RT_SERIAL_CONFIG_DEFAULT \
{ \
BAUD_RATE_115200, /* 115200 bits/s */ \
DATA_BITS_8, /* 8 databits */ \
STOP_BITS_1, /* 1 stopbit */ \
PARITY_NONE, /* No parity */ \
BIT_ORDER_LSB, /* LSB first sent */ \
NRZ_NORMAL, /* Normal mode */ \
RT_SERIAL_RB_BUFSZ, /* Buffer size */ \
RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \
0 \
}
在使用串口时,一般需要根据自己的需求去修改串口的通讯参数,修改串口通讯参数的函数为 rt_device_control(),例如修改波特率为921600,参考如下,只有修改后串口参数才能配置为自己想要的。
#define SAMPLE_UART_NAME "uart2" /* 串口设备名称 */
static rt_device_t serial; /* 串口设备句柄 */
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* 初始化配置参数 */
/* step1:查找串口设备 */
serial = rt_device_find(SAMPLE_UART_NAME);
/* step2:修改串口配置参数 */
config.baud_rate = BAUD_RATE_921600; //修改波特率为 921600
config.data_bits = DATA_BITS_8; //数据位 8
config.stop_bits = STOP_BITS_1; //停止位 1
config.bufsz = 128; //修改缓冲区 buff size 为 128
config.parity = PARITY_NONE; //无奇偶校验位
/* step3:控制串口设备。通过控制接口传入命令控制字,与控制参数 */
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
/* step4:打开串口设备。以中断接收及轮询发送模式打开串口设备 */
rt_device_open(serial, RT_DEVICE_FLAG_INT_RX);
我把波特率改成115200或230400就正常了。谢谢