感谢论坛和厂家,有机会学习瑞萨的MCU开发。
开发板型号是FPB-RA4E1
RA4E1 快速原型板配备了 R7FA4E10D2CFM 微控制器,是一块专门用于各种应用原型开发的评估板。 板载 SEGGER J-Link™ 仿真器电路,无需额外工具即可以烧写/调试程序。 此外,标配 Arduino Uno 和 Pmod™ 接口,并可通过通孔连接微控制器的所有引脚,具有很高的可扩展性。
样例代码可用于演示 RA4E1 MCU 的功能以及连接 RA4E1 快速原型板和各种无线模块或传感器模块。
使用时,请根据各国家/地区的无线电法规使用 蓝牙™、LoRa® 和 Wi-Fi。
- 配备 RA4E1 32 位微控制器(64 引脚,ROM:512KB,RAM:128KB)
- 板载 SEGGER J-Link™ 仿真器电路,无需额外工具即可对程序进行烧写/调试
- 可以通过通孔连接微控制器的所有引脚
- 标配 Arduino Uno 和 Pmod™ 接口
- 支持各种 RA4E1 软件和工具
开发板主要特性:
开发板官网链接如下:
https://www.renesas.cn/cn/zh/products/microcontrollers-microprocessors/ra-cortex-m-mcus/rtk7fpa4e1s00001be-ra4e1-fast-prototyping-board-fpb-ra4e1
提供了详细的开发资料和视频教程。
主控芯片是RA4E1,瑞萨电子 RA4E1 32 位微控制器 (MCU) 产品群使用支持 TrustZone 的高性能 Arm® Cortex®-M33 内核。 RA4E1 采用高效的 40nm 工艺,是 RA 产品家族微控制器的入门级产品,通过开放且灵活的生态系统(灵活配置软件包 (FSP))提供支持。 RA4E1 适用于入门级物联网应用的需求,这些应用通常需要优化的功能和集成的连接性、降低总体系统成本和平衡的功耗与性能。RA4E1提供 100 MHz 的Cortex-M33 内核和尽可能低的运行功耗(从闪存运行 CoreMark® 算法时功耗低至 81µA/MHz)的组合。
下面使用 RASC 软件新建一个工程, 直接借助 RASC 来自动生成一个 Keil 工程。
首先打开 RASC 软件,接着在菜单栏依次点击“File”→“New”→“FSP Project”,开始新建一个工程,然后会弹出如下的默认界面:
接下来点击“Next”进入下一步,到工程选项界面,如下图所示。 与使用 e2s 新建工程时的一样,我们需要在这里选择 FSP 库版本、板子型号、设备(MCU)型号、编程语言、编译器等。 这里的不同之处主要在于需要额外选择 IDE 类型(Keil、IAR等),并且不需要选择调试器, 因为调试器是在 IDE 里面进行选择和配置的:
选择IDE工具是KEIL:
更改完成后的配置如下图所示。然后点击“Next”下一步:
这里默认选择 “Flat (Non-TrustZone) Project” 即可。点击“下一步”:
默认选择 “No RTOS” 即可,然后点“下一步”,最后进入主页了,图形化的配置方式,十分强大,不用去翻数据手册找寄存器了:
接下来配置串口,根据原理图板卡的串口GPIO是:P109和P110
SCI(Serial Communications Interface),意为串行通信接口, 是相对与并行通信的概念,是串行通信技术的一种总称,包括了UART,SPI等串行通信技术。
SCI 模块包含如下功能:
UART
8位时钟同步接口
简易IIC(只能用作主机)
简易SPI
智能卡接口(符合ISO/IEC 7816-3国际标准)
曼彻斯特接口
增强的串行接口
P109和P110管脚功能配置为串口:
串口属性配置:注意通道和管脚的配置
串口中断回调函数
在前面的 FSP 配置步骤的时候,设置了串口中断回调函数的名字为: debug_uart9_callback。 设置这么一个函数的原因是:每当串口发送或者接收完成一个字符时,都会默认触发串口的中断, 而在串口中断中会调用函数 debug_uart9_callback,在函数里我们需要根据不同的中断情况进行相应的处理。
因此,需要同时在我们的代码里面定义并实现这么函数 debug_uart9_callback。 我们把这个函数放到文件“bsp_debug_uart.c”中,该函数代码如下所示。
其中,需要定义一个额外的标志变量 uart_send_complete_flag 来表示串口发送数据已完成。 变量 uart_send_complete_flag 必须加上volatile,否则可能被编译器优化。
- /* 发送完成标志 */
- volatile bool uart_send_complete_flag = false;
- /* 串口中断回调 */
- void debug_uart9_callback (uart_callback_args_t * p_args)
- {
- switch (p_args->event)
- {
- case UART_EVENT_RX_CHAR:
- {
- /* 把串口接收到的数据发送回去 */
- R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&(p_args->data), 1);
- break;
- }
- case UART_EVENT_TX_COMPLETE:
- {
- uart_send_complete_flag = true;
- break;
- }
- default:
- break;
- }
- }
虽然可以直接使用 R_SCI_UART_Write 函数来将字符串输出到串口, 但是这个函数在很多情况下没有 printf 函数那样方便。所以需要添加一段代码来将 printf 输出重定向到串口(UART9)。
将以下的代码添加到源文件“bsp_debug_uart.c”里面。 由于不同C库的 printf 函数的底层实现不同,这里使用条件编译选择我们需要重写的函数。
- /* 重定向 printf 输出 */
- #if defined __GNUC__ && !defined __clang__
- int _write(int fd, char *pBuffer, int size); //防止编译警告
- int _write(int fd, char *pBuffer, int size)
- {
- (void)fd;
- R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)pBuffer, (uint32_t)size);
- while(uart_send_complete_flag == false);
- uart_send_complete_flag = false;
- return size;
- }
- #else
- int fputc(int ch, FILE *f)
- {
- (void)f;
- R_SCI_UART_Write(&g_uart9_ctrl, (uint8_t *)&ch, 1);
- while(uart_send_complete_flag == false);
- uart_send_complete_flag = false;
- return ch;
- }
- #endif
C语言程序的入口函数 main 函数调用了 hal_entry 函数。 在 hal_entry 函数里面编写应用代码。
- void hal_entry(void)
- {
- /* TODO: add your own code here */
- Debug_UART9_Init(); // SCI9 UART 调试串口初始化
- printf("mbb.eet-china.com,RA4E1 Test\r\n");
- while(1)
- {
- R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_SECONDS);
- }
- #if BSP_TZ_SECURE_BUILD
- /* Enter non-secure code */
- R_BSP_NonSecureEnter();
- #endif
- }