MCU:stm32f103 系列,串口有3种工作模式:查询、中断、DMA 1,查询 如要发送一个字节: USART_SendData(EVAL_COM1, (uint8_t) ch); /* Loop until the end of transmission */ 一直要等到发送完成后,才能继续,要知道串口的速度很低,MCU的速度很快,简直就是浪费。 上面程序可改进为: USART1->DR = (u8) ch; while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) 2, 中断 在我的项目中,3个串口都用上,分别接控制台(console)、GSM 模块、汽车OBDII 的 KWP (k-line, k线), 2.1, 串口发送环形队列 u8 *out_last; bool empty; 当需要发送数据时,只需要往队列里放入数据,in_last指针加1即可,当然会根据 in_last, out_last 指针,检查buffer 是否满,满的时候会加1ms延时,大约能发12个字节(以115200 k/b 估算); 只要empty标志不为真,就打开发送中断,开始发送数据,当然,如果缓冲为空时,会自动关闭发送中断,在中断里,会自动把 out_last 加1。 在应用程序更新指针及标志时,需要关闭发送中断,以免更新过程中,发生中断,相关指针被修改,从而影响判断结果。 2.2, 串口接收环形队列 u8 *out_last; bool empty; 接收队列稍微复杂一点,当应用程序需要从buffer里取数据时,需要判断队列是否为空,如果标志 empty 为真,则无数据,否则可以取数据;另外,也要检查lost_data 标志,如果为真,说明接收队列已满,无法接受新数据,直接把新数据做丢弃处理,此时需要检查应用程序架构设计是否合理,因为mcu的速度是很快的(如72MHz),而串口速度比较慢(如115200 baud,约12k字节/秒),这样的条件下都发生接收数据丢失,真的需要改进应用程序。 3, DMA 方式 u32 buf1_cnt; bool use_buf1; 接收功能没有用DMA方式,但原理是一样的,都可以开2个缓存,应用程序处理起来就麻烦一点。 如果有高人有很高效的办法,不妨介绍一下,谢谢。 上文提到的3种模式的驱动:stm32_uart.rar |
|