一:基础知识
UART 只需两根信号线即可完成双向通信,对硬件要求低,使得很多模块都预留 UART 接口来实现与其他模块或者控制器进行数据传输,比如 GSM 模块,WIF模块、蓝牙模块等等。在硬件设计时,注意还需要一根“共地线”。
我们经常使用 UART 来实现控制器与电脑之间的数据传输。这使得我们调试程序非常方便,比如我们可以把一些变量的值、函数的返回值、寄存器标志位等等通过 UART 发送到串口调试助手这样我们可以非常清楚程序的运行状态,当我们正式发布程序时再把这些调试信息去除即可。我们不仅仅可以将数据发送到串口调试助手,我们还可以在串口调试助手发送数据给控制器,控制器程序根据接收到的数据进行下一步工作。
首先,我们来编写一个程序实现开发板与电脑通信,在开发板上电时通过 UART 发送一串字符串给电脑,然后开发板进入中断接收等待状态,如果电脑有发送数据过来,开发板就会产生中断我们在中断服务函数接收数据,并马上把数据返回发送给电脑。
二:硬件连接:
可见,RA0E2的P100,P101引脚板载调试相连接;
三:FSP库配置:
这里需要注意的式,需要打开串口的接收中断,并且配置中断的优先级别。
四:软件代码:
4.1 串口中断的标志位如下所示:
typedef enum e_sf_event { UART_EVENT_RX_COMPLETE = (1UL << 0), ///< Receive complete event UART_EVENT_TX_COMPLETE = (1UL << 1), ///< Transmit complete event UART_EVENT_RX_CHAR = (1UL << 2), ///< Character received UART_EVENT_ERR_PARITY = (1UL << 3), ///< Parity error event UART_EVENT_ERR_FRAMING = (1UL << 4), ///< Mode fault error event UART_EVENT_ERR_OVERFLOW = (1UL << 5), ///< FIFO Overflow error event UART_EVENT_BREAK_DETECT = (1UL << 6), ///< Break detect error event UART_EVENT_TX_DATA_EMPTY = (1UL << 7), ///< Last byte is transmitting, ready for more data } uart_event_t;
这里我使用的的标志位是:
UART_EVENT_RX_CHAR
在串口回调函数中,添加如下代码:
void g_uart0_callback(uart_callback_args_t *p_args) { switch (p_args->event) { /* case UART_EVENT_RX_COMPLETE: g_data_received_flag = true; R_UARTA_Write(&g_uart0_ctrl,( uint8_t )&(p_args->data),1); break;*/ case UART_EVENT_RX_CHAR: g_data_received_flag = true; R_UARTA_Write(&g_uart0_ctrl,(uint8_t *)&(p_args->data),1); break; case UART_EVENT_TX_COMPLETE: g_data_transmit_flag = true; break; default: break; } }
当串口每接收到一个字符数据时候,立即触发串口的回调函数,在串口接收中断里,将接收到的数据返回给串口,
4.2 官方提供的标志位中,有接收完一帧数据的状态位如下:
UART_EVENT_RX_COMPLETE
在串口中断中,接收完一帧完成的数据后触发,不过这里需要注意的是,当设定的数据长度全部接收后,才可以触发该中断,这样一帧数据才会进入一次中断;
可以使用该函数;
fsp_err_t R_UARTA_Read(uart_ctrl_t * const p_api_ctrl, uint8_t * const p_dest, uint32_t const bytes);
触发接收完成中断后,使用读取函数将串口接收寄存器中读取指定的字节到接收buffer里面,进行处理,当处理完成后,清空就可以。
使用该函数的缺点就是,需要用户明确知道一帧数据的具体个数。
五:实物验证如下: