感谢论坛和厂家,有机会学习瑞萨的MCU开发。
开发板型号是FPB-RA4E1
![微信图片_20230901201132.jpg 微信图片_20230901201132.jpg](data/attachment/forum/202309/01/201427pdwla2wa88wuadu3.jpg)
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 软件和工具
![微信图片_20230901201120.jpg 微信图片_20230901201120.jpg](data/attachment/forum/202309/01/201426bx3icbxzeigxg954.jpg)
开发板主要特性:
![屏幕截图 2023-09-01 201630.png 屏幕截图 2023-09-01 201630.png](data/attachment/forum/202309/01/201646blb9dkzqkz675am6.png)
开发板官网链接如下:
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)的组合。
![ra4e1-block-diagram_0.png ra4e1-block-diagram_0.png](data/attachment/forum/202309/01/201425s261q0r5m170ze70.png)
下面使用 RASC 软件新建一个工程, 直接借助 RASC 来自动生成一个 Keil 工程。
首先打开 RASC 软件,接着在菜单栏依次点击“File”→“New”→“FSP Project”,开始新建一个工程,然后会弹出如下的默认界面:
![屏幕截图 2023-09-01 201748.png 屏幕截图 2023-09-01 201748.png](data/attachment/forum/202309/01/201949ael7il8o87o7ibb2.png)
接下来点击“Next”进入下一步,到工程选项界面,如下图所示。 与使用 e2s 新建工程时的一样,我们需要在这里选择 FSP 库版本、板子型号、设备(MCU)型号、编程语言、编译器等。 这里的不同之处主要在于需要额外选择 IDE 类型(Keil、IAR等),并且不需要选择调试器, 因为调试器是在 IDE 里面进行选择和配置的:
![屏幕截图 2023-09-01 201838.png 屏幕截图 2023-09-01 201838.png](data/attachment/forum/202309/01/201949hsos45zz51ilr5ri.png)
选择IDE工具是KEIL:
![屏幕截图 2023-09-01 201855.png 屏幕截图 2023-09-01 201855.png](data/attachment/forum/202309/01/201950dskiyyd9mylqy6si.png)
更改完成后的配置如下图所示。然后点击“Next”下一步:
![屏幕截图 2023-09-01 201909.png 屏幕截图 2023-09-01 201909.png](data/attachment/forum/202309/01/201951vp99fpypfzx9pizi.png)
这里默认选择 “Flat (Non-TrustZone) Project” 即可。点击“下一步”:
![屏幕截图 2023-09-01 201921.png 屏幕截图 2023-09-01 201921.png](data/attachment/forum/202309/01/201951ap9ndib8d87eme9e.png)
默认选择 “No RTOS” 即可,然后点“下一步”,最后进入主页了,图形化的配置方式,十分强大,不用去翻数据手册找寄存器了:
![屏幕截图 2023-09-01 202028.png 屏幕截图 2023-09-01 202028.png](data/attachment/forum/202309/01/202040n1zvmaorbrav8aeb.png)
接下来配置串口,根据原理图板卡的串口GPIO是:P109和P110
![屏幕截图 2023-09-01 203239.png 屏幕截图 2023-09-01 203239.png](data/attachment/forum/202309/01/203630h8di9ppy9pa4fdeo.png)
SCI(Serial Communications Interface),意为串行通信接口, 是相对与并行通信的概念,是串行通信技术的一种总称,包括了UART,SPI等串行通信技术。
SCI 模块包含如下功能:
UART
8位时钟同步接口
简易IIC(只能用作主机)
简易SPI
智能卡接口(符合ISO/IEC 7816-3国际标准)
曼彻斯特接口
增强的串行接口
P109和P110管脚功能配置为串口:
![屏幕截图 2023-09-01 203902.png 屏幕截图 2023-09-01 203902.png](data/attachment/forum/202309/01/204058moov7jq1lmjiogma.png)
串口属性配置:注意通道和管脚的配置
![屏幕截图 2023-09-01 204039.png 屏幕截图 2023-09-01 204039.png](data/attachment/forum/202309/01/204058c7ge9ewrur227o4w.png)
串口中断回调函数
在前面的 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
}
复制代码