【前言】
在当今科技飞速发展的时代,电子设备之间的通信变得至关重要。无论是智能手机、电脑、还是各种嵌入式系统,它们都需要一种可靠且高效的方式来进行数据交换。而在众多通信技术中,UART(Universal Asynchronous Receiver/Transmitter,通用异步收发传输器)以其独特的优势占据着重要的一席之地。 UART 作为一种古老而又经典的串行通信协议,历经多年的发展与演进,至今仍然广泛应用于各种领域。它的出现,为不同设备之间的数据传输提供了一种简单而有效的解决方案。从早期的计算机外设连接,到如今的物联网设备、工业控制系统等,UART 都发挥着不可或缺的作用。
【软件环境】
e2Studio
【FSP配置】
RA6E2有0-9号UART可供配置使用。从他的用户手册中,Arduino Interfaces接口图上,我选择了P410、P411做为UART0的输出接口。

1、生成一个基础工程,新建一个Stack-》UART

2、进入属性,默认为P411、P410为RX、TX接口,FSP默认生成了115200的波特率配置,我们只需要开启中断,来实现中断接收,同时配置中断回调函数为user_uart0_callback。中断优先级别可根据自己需要修改。
配置如下图所示:

3、为了配合实现接收,我们再配置一个定时器,实现1ms中断,添加一个普通定时器,配置溢出计数为100,000,000即1ms中断。同时实现中断回调函数为timer0_callback。

【代码实现】
1、生成工程后打开hal_entry.c实现用户代码,最先我们要对定时器中断进行实现。
/* Callback function */
void timer0_callback(timer_callback_args_t *p_args)
{
        /* TODO: add your own code here */
        if (TIMER_EVENT_CYCLE_END == p_args->event)
        {
            if(Rx_flag==1)
            {
                printf_usart();
                Rx_flag=0;
            }
        }
}代码的功能是如果产生空闲中断,则进行串口输出,重置接收标志。
2、定义串口接收数组与标志:
void printf_usart(void); fsp_err_t err = FSP_SUCCESS; volatile bool uart_send_complete_flag = false; uint8_t RxBuff[1]; //进入中断接收数据的数组 uint8_t DataBuff[5000]; //保存接收到的数据的数组 int RxLine=0; //接收到的数据长度 int Rx_flag=0; //接受到数据标志 int Rx_flag_finish=0; //接受完成或者时间溢出
3、实现UART中断接收函数
void user_uart0_callback (uart_callback_args_t * p_args)
{
    if(p_args->event == UART_EVENT_TX_COMPLETE)
    {
        uart_send_complete_flag = true;
    }
    if(p_args->event ==     UART_EVENT_RX_CHAR)
    {
        RxBuff[0] = (uint8_t )p_args->data;
        RxLine++;                      //每接收到一个数据,进入回调数据长度加1
        DataBuff[RxLine-1]=RxBuff[0];  //把每次接收到的数据保存到缓存数组
        Rx_flag=1;
        if(RxBuff[0]==0xff)            //接收结束标志位,这个数据可以自定义,根据实际需求,这里只做示例使用,不一定是0xff
        {
            Rx_flag_finish=1;
        }
        RxBuff[0]=0;
        err = R_GPT_Reset(&g_timer0_ctrl);
        assert(FSP_SUCCESS == err);
    }
}4、为了打印方便,实现串口重定向:
#ifdef __GNUC__                                 //串口重定向
    #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
    #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
        err = R_SCI_UART_Write(&g_uart0_ctrl, (uint8_t *)&ch, 1);
        if(FSP_SUCCESS != err) __BKPT();
        while(uart_send_complete_flag == false){}
        uart_send_complete_flag = false;
        return ch;
}
int _write(int fd,char *pBuffer,int size)
{
    for(int i=0;i<size;i++)
    {
        __io_putchar(*pBuffer++);
    }
    return size;
}
void printf_usart(void)
{
    printf("length=%d\r\n",RxLine);
    for(int i=0;i<RxLine;i++)
        printf("data:[%d] = 0x%x\r\n",i,DataBuff[i]);
    memset(DataBuff,0,sizeof(DataBuff));  //清空缓存数组
    //memset()作用:可以方便的清空一个结构类型的变量或数组。
    //例句:memset(aTxbuffer,0,sizeof(aTxbuffer))  用memset清空aTxbuffer。
    RxLine=0;  //清空接收长度
    Rx_flag_finish=0;
    Rx_flag = 0;
}5、在主函数中添加启动串口与定时器的函数:
    /* Open the transfer instance with initial configuration. */
    err = R_SCI_UART_Open(&g_uart0_ctrl, &g_uart0_cfg);
    assert(FSP_SUCCESS == err);
    /* Initializes the module. */
    //err = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
    err = R_GPT_Open(&g_timer0_ctrl, &g_timer0_cfg);
    /* Handle any errors. This function should be defined by the user. */
    assert(FSP_SUCCESS == err);
    /* Start the timer. */
    (void) R_GPT_Start(&g_timer0_ctrl);
          while(1)
          {
              R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS); // NOLINT100->160
              if(Rx_flag_finish==1)
              {
                      printf_usart();
              }
          }编译下载后就可以看到如期的结果了。

 
					
				
 
			
			
			
						
			 
					
				 
					
				 
					
				 我要赚赏金
 我要赚赏金 STM32
STM32 MCU
MCU 通讯及无线技术
通讯及无线技术 物联网技术
物联网技术 电子DIY
电子DIY 板卡试用
板卡试用 基础知识
基础知识 软件与操作系统
软件与操作系统 我爱生活
我爱生活 小e食堂
小e食堂

