硬件:RA2E1开发板
软件:e2studio Version: 2024-10 (24.10.0)
调试器:J-link V9
对应定时器的学习大家可以参考之前的帖子,今天和大家分享瑞萨串口的应用方案;
一:瑞萨RA2E1 开发板串口知识分享:
SCI(Serial Communications Interface),意为串行通信接口,是相对与并行通信的概念,是串行通信技术的一种总称,包括了 UART,SPI等串行通信技术。RA2E1 的 SCI模块是一个有 4个通道的异步/同步串行接口,之前和大家分享过使用串口0的一些开发经验,今天具体和大家分享一下,该款开发板的串口部分;
SCI模块包含如下功能
UART
8位时钟同步接口
简易 IIC(只能用作主机)
简易 SP
智能卡接口(符合 ISO/IEC 7816-3 国际标准)
曼彻斯特接口
增强的串行接口
二:瑞萨串口的内部结构图
RXDn/SCLN/MISOn:
RXDn:UART 接收数据输人。
SCLn:I2C时钟信号输人或输出。
MISOn:SPI主机信号输人,从机信号输出。TXDnSDANMOSIn:
TXDn:UART 发送数据输出。
SDAn:数据输人或输出。
MOSIn:SPI从机信号输人,主机信号输出。SSn/CTSn RTSn:
SSn:片选信号输人,低电平有效。
CTSn_RTSn:清除以发送(Clearto Send)或请求以发送(Request to Send)。低电平有效。如果使能 RTS 流控制,当 UART 接收器准备好接收新数据时就会将 RTS 变成低电平;当接收寄存器已满时,RTS 将被设置为高电平。如果使能 CTS 流控制,发送器在发送下一帧数据之前会检测 CTS 引脚,如果为低电平,表示可以发送数据,如果为高电平则在发送完当前数据帧之后停止发送,该引脚只适用于硬件流控制。
CTSn (n =0,3 to 9):清除以发送(Clear to Send),适用于硬件流控制。
SCKn:时钟输出或输人引脚,适用于同步通信。
三:FSP的配置过程如下所示:
基本新建功能,请大家之前的帖子,这里不再重复介绍
【瑞萨RA2E1开发板】:使用定时器完成LED灯闪烁-电子产品世界论坛
3.1 配置SC1的功能引脚
3.2 配置串口的波特率、回调函数等等信息
注意“这里需要根据项目的中模块的重要性和执行时间、次数,配置合适的优先级别;
四:串口软件代码的编写步骤如下所示:
4.1 系统时钟配置:由于该款开发板没有外部高速时钟,我们配置的时候需要选择内部时钟。
4.2 选择和的硬件IO口,如下图所示,串口1 可以选择三种不同的引脚位置,我们在硬件设计时候,可以进行复用
4.3 串口参数的配置,依次点击红色框,增加串口功能:
点击 屏幕的右侧属性一栏,对系统的参数进行配置,这里注意通道的配置
4.4 最后点击 生成代码 按钮即可;
五:软件代码编写过程
5.1 程序流程图
5.2 初始化串口信息
err = R_SCI_UART_Open(&g_uart1_ctrl, &g_uart1_cfg); assert(FSP_SUCCESS == err); uart1_send_complete_flag = false;
5.3 串口发送数据的底层驱动函数
/*********************************************************************************************** * @brief void Dwin_Send_Example(uint8_t ch) * @param 串口发送一个字节 * @retval 无 * @author 聪聪哥哥 * @version V1.1.0 * @date 3-3-2025 *************************************************************************************************/ void Dwin_Send_Example(uint8_t ch) { /* 把串口需要发送的数据放置串口里面 */ R_SCI_UART_Write(&g_uart1_ctrl, (uint8_t *)&ch, 1); while(uart1_send_complete_flag == false); uart1_send_complete_flag = false; }
5.4 界面切换函数:
/*********************************************************************************************** * @brief void SendTestData(char ID) * @param 切换界面显示功能 * @retval 无 * @author 聪聪哥哥 * @version V1.1.0 * @date 3-3-2025 *************************************************************************************************/ void SendTestData(uint8_t ID) { static uint8_t DWIN_Buffer[64]; volatile int i = 0 ; ucDispMode = ID ; DWIN_Buffer[0] = 0x5A ; DWIN_Buffer[1] = 0xA5 ; DWIN_Buffer[2] = 0x07 ; DWIN_Buffer[3] = 0x82 ; DWIN_Buffer[4] = 0x00 ; DWIN_Buffer[5] = 0x84 ; DWIN_Buffer[6] = 0x5A ; DWIN_Buffer[7] = 0x01 ; DWIN_Buffer[8] = 0x00 ; DWIN_Buffer[9] = ID ; for(i= 0 ;i < 10 ; i++) { Dwin_Send_Example(DWIN_Buffer[i]); } }
5.5 变量显示函数:
/*********************************************************************************************** * @brief void Add_Write_Data1(unsigned int ucAdd,int uiDATA) * @param 向指定地址发送两字节数据 * @retval 无 * @author 聪聪哥哥 * @version V1.1.0 * @date 3-4-2024 *************************************************************************************************/ void Add_Write_Data(uint8_t ucAdd, uint16_t uiDATA) { static uint8_t DWIN_Buffer[64]; volatile int i = 0 ; volatile uint8_t Value = 0 ; volatile uint8_t data = 0 ; Value = (uint8_t)(uiDATA & 0x00FF) ; data = (uint8_t)(uiDATA & 0xFF00) ; DWIN_Buffer[0] = 0x5A; DWIN_Buffer[1] = 0xA5; DWIN_Buffer[2] = 0x05; DWIN_Buffer[3] = 0x82; DWIN_Buffer[4] = ucAdd>>8; DWIN_Buffer[5] = ucAdd ; DWIN_Buffer[6] = data; DWIN_Buffer[7] = Value ; for(i= 0 ;i < 10 ; i++) { Dwin_Send_Example(DWIN_Buffer[i]); } }
5.6 串口中断回调函数:
/*********************************************************************************************** * @brief g_uart0_callback (uart_callback_args_t * p_args) * @param 串口0接收到数据处理 * @retval 无 * @author 聪聪哥哥 * @version V1.1.0 * @date 3-4-2025 *************************************************************************************************/ void g_uart1_callback (uart_callback_args_t * p_args) { if(p_args->event == UART_EVENT_TX_COMPLETE) { uart1_send_complete_flag = true; } if(p_args->event == UART_EVENT_RX_CHAR) { temp = (unsigned char )p_args->data ; switch(BackState) { case 0: if(temp == 0x5A) BackState = 1; else {BackState = 0;} break; case 1: if(temp == 0xA5) BackState = 2; else {BackState = 0;} break; case 2: ReceiveLength = temp; if(ReceiveLength>32) BackState = 0; else { ReceiveLength = ReceiveLength - 1; BackState = 3; } break; case 3: ReceiveBuffer[ReceivePoint] = temp; ReceivePoint++; if(ReceivePoint > ReceiveLength) { backFlag = 1; BackState = 0; } else { BackState = 3; } break; default: break; } } }
七:调试心得
1:在调试瑞萨串口通讯的时候,也是遇到了问题。在发送固定字节的时候,发现串口数据发送不正常,一开始怀疑是自己FSP配置的问题,根据官方提供的PPT、代码发现,配置是没有问题,查到最后发现是在发送完成后,没有编写发生完成的标志位,在中断函数中添加,发送完成的标志位后,成功解决问题。
uart1_send_complete_flag = true;
2:后来想用printf函数发送数据,发现也是不行,但是官方提供例程版本是基于3.2.0版本,而我现在使用的版本是5.6.0的程序,我怀疑是版本不兼容导致的,后来才发现,是软件配置的问题。解决办法也是官方的网址上面,查到的,害的我排查了好久。