)
第八届立创电赛基于瑞萨RA2E1的智能小夜灯硬件设计与FSP开发实战新手入门篇最近有不少朋友问我第一次接触瑞萨的RA系列MCU该怎么上手正好借着参加第八届立创电赛的机会我用瑞萨RA2E1这颗芯片做了一个“智能小夜灯”的项目。从画板子、焊元件到用瑞萨的FSP库写代码整个过程踩了不少坑也积累了一些经验。这篇文章我就以一个嵌入式新手的视角带你走一遍这个项目的开发流程希望能帮你少走弯路。咱们这个项目说白了就是一个能自动调光、带触摸开关的小夜灯。核心是瑞萨的R7FA2E1A72DFL这颗MCU外加WS2812彩灯、加速度传感器用来感应动作、触摸按键等外设。我会重点讲两部分硬件设计上要注意什么以及软件上如何用FSP这个“瑞萨版HAL库”来驱动它们。特别是对于从ST意法半导体转过来的朋友我会多做一些对比帮你更快理解。1. 项目规划与硬件选型思路拿到一个芯片第一步不是急着画图而是先想清楚我要用它做什么需要哪些功能训练营给的例程功能很全是个电子时钟但我们做小夜灯用不上那么多。我的思路是在例程基础上做减法只保留核心功能。核心需求分析主控芯没得选比赛指定要用RA2E1系列的R7FA2E1A72DFL。电源电例程里有电池和充电管理太复杂。小夜灯通常插电使用我直接删掉电池部分用Type-C口供电简单可靠。灯光光例程用数码管显示我们换成更炫酷的WS2812彩灯再加一个普通的白光LED。总共用了11颗灯珠比数码管的32颗少更省电。传感器测例程用温湿度传感器我们换成加速度传感器。为啥因为小夜灯需要感知环境动作比如人挥手自动亮起或调整亮度加速度计比温湿度更合适。我还预留了一个亮度传感器的位置为以后升级自动调光做准备。交互手例程有4个物理按键1个触摸键。我们只保留最酷的触摸按键物理按键全删掉让面板更简洁。其他蜂鸣器太吵删掉复位键、串口电路、SWD下载口这些调试必需的保留但做在板子背面不占用正面空间。这样一规划项目就清晰了一个由RA2E1主控通过触摸控制用加速度计感知动作驱动WS2812和白光LED的智能小夜灯。接下来我们就进入硬件设计环节。2. 核心电路设计详解与踩坑记录画原理图和PCB是最体现工程师功底的地方这里有很多细节需要注意尤其是对于瑞萨这颗不太常见的芯片。2.1 主控MCU外围电路设计a) 时钟与RTC实时时钟芯片内置了一个低速内部时钟LOCO约32.768KHz但手册标称误差有±15%精度比较差。如果小夜灯需要靠RTC实现定时开关这个误差就太大了。所以我强烈建议外接一个32.768KHz的晶振给RTC用。电路上就在XCIN和XCOUT引脚接上晶振和负载电容即可。另外这颗芯片没有单独的VBAT引脚专门给RTC供电的引脚。这意味着如果完全断电RTC就会停止。我们的设计是常供电的所以问题不大。但如果你的项目想用电池保持RTC就需要整个系统都由电池供电并在软件上做好低功耗管理。b) 触摸按键CTSU电路这是本项目的一个亮点。瑞萨的CTSU外设支持自电容和互电容检测但官方开发板都没用互电容咱们也保守点用自电容。触摸设计的核心是“电容”。你的手指按上去相当于增加了一个电容Ctouch。芯片就是通过检测这个电容的变化来判断触摸的。但PCB上的走线、铺铜都会产生寄生电容CpCp太大会降低灵敏度。PCB布局布线要点血泪经验触摸电极做成圆形或圆角方形避免尖角。大小建议12mm左右贴合手指。走线从触摸电极到MCU引脚的走线要尽量短、尽量直。避免90度直角走线不是因为信号反射而是会增加一点点寄生电容。线宽6mil0.152mm就够线间距大于1.27mm。铺铜触摸走线周围可以铺网格铜来抗干扰但必须与走线保持1mm以上的间距。电极背面最好不要铺实心铜如果铺也要用网格铜并保持5mm以上间距。隔离触摸走线要像对待模拟信号一样远离其他数字信号线特别是LED驱动线这种有大电流变化的线。如果必须交叉请90度垂直交叉。电容记得在TSCAP引脚接一个推荐值的电容到地这个电容对触摸检测的基准很重要。c) 调试与通信接口SWD这是最常用的调试下载接口SWDIO和SWDCLK两个脚必须引出来。串口 (SCI)用于打印调试信息。RA2E1的串口功能在SCI外设里。我引出了一路方便和电脑通信。I2C (SCI)我预留给了未来的亮度传感器。RA2E1也有独立的I2C外设但用SCI里的I2C功能也够用软件上还少研究一个外设。2.2 电源与LED驱动电路电源Type-C输入5V通过一个LDO低压差线性稳压器降到3.3V给整个系统供电。虽然MCU的IO口可以耐受5V但其他传感器可能不行所以统一用3.3V比较稳妥。LED驱动这里我踩了一个坑。为了省事我用PMOS管做高端开关控制LED电源MCU的IO直接驱动PMOS的栅极。最初以为IO口耐压5V没问题但后来发现只有P400,P401,P407这三个引脚明确支持5V耐受其他引脚最高只能到VCC0.3V也就是约3.6V。坑点提示当你用IO口直接控制一个电压比VCC高的信号时比如用3.3V MCU控制5V的PMOS栅极电流可能会通过IO口内部的保护二极管倒灌到VCC虽然不一定立刻损坏但有风险。稳妥的做法是使用电平转换芯片。使用NOMS做低端开关控制LED到地的通路。在IO口串联一个较大的限流电阻比如几K欧姆来减小倒灌电流。我最后用了方法3临时解决。WS2812驱动这是一个单线归零码协议的数字RGB灯。需要用精确的定时器GPT来产生0码和1码对应的高电平脉冲。我们后面在软件部分详细讲。2.3 PCB设计心得画PCB时我被训练营里的大佬们“教育”了一番。总结一下要点走线拐角优先用圆弧其次用45度角尽量避免90度直角。对于触摸等敏感信号线直角带来的微小寄生电容确实有影响。布局发热大的器件如LED和敏感的模拟器件如加速度计要分开。我的加速度计不幸放在了LED背面这是不对的热量会影响传感器精度。丝印清晰明了把引脚功能、接口名称都标清楚后期调试焊接会省很多事。我的第一版PCB就因为工厂工艺问题出现了“断桥”线路断开。所以打样回来一定要仔细检查下图是焊接好主要部分的效果3. 软件开发环境搭建与FSP初探硬件搞定了接下来是软件。瑞萨的软件生态和ST不太一样需要适应一下。3.1 开发工具链选择瑞萨主推的是e2studio基于Eclipse FSPRASC这套组合拳。e2studio集成开发环境(IDE)类似STM32CubeIDE。我用不惯Eclipse所以没选它。FSP (Flexible Software Package)这就是瑞萨的HAL库提供了芯片所有外设的驱动函数。RASC (Renesas Advanced Software Configurator)图形化配置工具类似STM32CubeMX。你在这里勾勾选选它就能帮你生成初始化代码这个非常关键我个人的选择是用RASC生成代码然后用Keil MDK进行编译和调试。因为我对Keil更熟悉而且它的编译器优化效果有时更好。RA2E1只有64KB Flash能省一点是一点。好消息是RASC支持生成Keil工程。我用J-Link、WCH-LinkEDAPLink模式、PWLink测试下载和调试都没问题。但用ST-Link可能会报错建议还是用J-Link或DAPLink。3.2 创建第一个点灯工程打开RASC新建一个工程选择你的芯片型号R7FA2E1A72DFL。配置时钟在“Clocks”标签页。RA2E1没有PLL锁相环所以主频最高只能到48MHz通过HOCO时钟。我选择HOCO 48MHz作为主时钟源。瑞萨命名相当于STM32的频率用途说明HOCOHSI48MHz高速内部时钟主频来源MOCO无8MHz中速内部时钟LOCOLSI~32.768KHz低速内部时钟精度低MOSCHSE1-20MHz外部高速晶振SOSCLSE32.768KHz外部低速晶振接RTC配置引脚在“Pins”标签页。找到你想用来点灯的GPIO比如P100点击它在“Pin Configuration”下面选择“I/O Port”模式并设置初始输出电平为低。配置GPT定时器用于PWM在“Stacks”标签页点击“New Stack” - “Timers” - “Timer, General PWM (r_gpt)”来添加一个GPT定时器实例。然后在它的属性里设置周期、占空比并把输出引脚关联到你刚才的LED引脚上。生成工程点击“Generate Project Content”选择“Toolchain”为“MDK (Keil)”。RASC会在你指定的目录生成一个Keil工程文件(.uvprojx)。3.3 理解FSP的代码结构用Keil打开生成的工程你会发现目录结构是这样的你的工程目录/ ├── ra/ // FSP库的核心文件不要修改 ├── ra_cfg/ // FSP的配置文件头文件 ├── ra_gen/ // RASC生成的代码引脚配置、时钟配置、外设初始化代码 └── src/ // 用户代码目录我们在这里写主程序重要规则ra/和ra_gen/文件夹下的代码千万不要直接修改因为下次用RASC重新生成工程时它们会被覆盖。所有你自己的代码都写在src/目录下。打开src/目录下的hal_entry.c文件找到hal_entry()函数这就是我们程序的入口相当于main函数但main在别处调用了它。让我们写一个最简单的LED闪烁程序void hal_entry(void) { /* TODO: add your own code here */ // 注意RASC已经帮我们初始化了GPIO这里可以直接用了 // BSP_IO_PORT_01_PIN_00 对应 P100 引脚这个宏在 bsp_pin_cfg.h 里定义 while(1) { // 点亮LED (假设LED低电平点亮) R_BSP_PinWrite(BSP_IO_PORT_01_PIN_00, BSP_IO_LEVEL_LOW); // 延迟500毫秒 R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); // 熄灭LED R_BSP_PinWrite(BSP_IO_PORT_01_PIN_00, BSP_IO_LEVEL_HIGH); R_BSP_SoftwareDelay(500, BSP_DELAY_UNITS_MILLISECONDS); } }编译、下载你的LED就应该开始闪烁了R_BSP_SoftwareDelay是一个软件阻塞延时函数用于简单演示。实际项目中我们会用GPT定时器来做精确延时或PWM调光。4. 关键外设驱动实战点灯只是开始让我们看看如何驱动更复杂的外设。4.1 使用GPT驱动WS2812WS2812需要精确的时序0码的高电平约0.4us低电平0.85us1码的高电平约0.8us低电平0.45us。整个复位信号需要大于50us的低电平。用GPT定时器可以很好地产生这种波形。我们需要将GPT配置为PWM模式并且动态改变占空比来生成0码和1码。在RASC中配置GPT添加一个GPT堆栈例如g_timer0。模式选择“PWM”。周期设置为1.25us对应800kHz频率这是WS2812的数据速率。占空比我们将在代码中动态修改。代码思路初始化GPT。编写一个函数将24位RGB颜色值每个颜色8位转换为WS2812的数据流每个位用GPT的占空比表示。在函数中根据每一位是0还是1设置GPT的占空比分别为0.4us / 1.25us ≈ 32%或0.8us / 1.25us ≈ 64%并保持一个周期。发送完所有数据后拉低数据线超过50us完成复位。这里代码较长核心是操作GPT的周期比较寄存器GTCCR来改变占空比。你需要仔细阅读RA2E1用户手册中关于GPT的章节了解如何启停定时器、更新比较值。4.2 配置ADC检测电流电压我们想监测小夜灯的功耗就需要用ADC测量供电电流和电压。在RASC中配置ADC添加一个ADC堆栈例如g_adc0。选择扫描模式Scan Mode添加你要测量的通道比如通道0和通道7。设置采样时间和转换精度。如果你需要连续监测可以启用DTC数据传输控制器类似简易DMA来自动搬运ADC结果到内存数组。一个坑点RA2E1的ADC结果寄存器ADDR是每个通道独立的ADDR0,ADDR1...。如果你用DTC并且只使能了通道0和通道7你的DTC目标数组仍然需要定义为包含所有通道0到7的大小即uint16_t adc_buffer[8]DTC会从ADDR0的地址开始顺序搬运。中间未使用的通道对应的数组元素会是0。4.3 实现触摸按键CTSUCTSU的配置相对复杂RASC只能配置基础参数精细的灵敏度调整需要借助瑞萨的“QE for Touch”工具但这个工具似乎只集成在e2studio里。手动调参的基本步骤RASC中使能CTSU外设。在代码中初始化后需要校准触摸基准值无触摸时的计数值。设置一个阈值Delta当检测到的计数值变化超过这个阈值时判定为触摸。为了抗干扰通常还会加入“去抖动”算法比如连续几次检测都超过阈值才认为是有效触摸。调试时最好把触摸的原始计数值通过串口打印出来或者用类似J-Scope的工具图形化显示这样能直观地看到触摸时数值的变化便于确定合适的阈值。4.4 使用RTC并输出1PPS信号RTC用于提供时间信息。我使用了外部32.768KHz晶振以获得更高精度。在RASC中配置RTC添加RTC堆栈。时钟源选择“Sub-Clock”外部低速晶振。使能“Set source clock in open”这样R_RTC_Open函数里会自动配置时钟源。我想用RTC的RTCOUT引脚输出一个1秒一次的脉冲1PPS来驱动一个LED用于直观显示RTC在工作。但发现FSP库居然没有提供这个功能的API没办法只能直接操作寄存器了// 手动使能RTCOUT输出1Hz方波 R_RTC-RCR2_b.START 0x00; // 先停止RTC计数 // 等待寄存器写入完成FSP提供的宏 FSP_HARDWARE_REGISTER_WAIT(R_RTC-RCR2_b.START, 0x00); R_RTC-RCR2_b.RTCOE 0x01; // 使能RTCOUT输出 FSP_HARDWARE_REGISTER_WAIT(R_RTC-RCR2_b.RTCOE, 0x01); R_RTC-RCR2_b.START 0x01; // 重新启动RTC计数 FSP_HARDWARE_REGISTER_WAIT(R_RTC-RCR2_b.START, 0x01);注意直接操作寄存器有风险需要确保你完全理解寄存器位域的含义。FSP_HARDWARE_REGISTER_WAIT是一个等待寄存器同步的宏很有用。另一个问题如何防止每次上电RTC都被重置RA2E1没有备份寄存器。通常的解决办法是在Flash里存一个标志位。但Flash擦写次数有限约10万次。对于常供电的小夜灯一个更简单的办法是在SRAM中定义一个__no_init变量。只要不断电这个变量就不会被初始化可以用来判断是否是第一次上电。5. 项目总结与心得通过这个智能小夜灯项目我算是把瑞萨RA2E1和FSP开发流程摸了一遍。总的来说RA2E1作为M23内核的MCU开发模式和常见的Cortex-M0/M3很像对于有STM32基础的朋友来说硬件层面切换成本不高。主要的挑战和心得在于软件层面开发环境RASCFSPKeil/IAR的组合是可行的避免了使用e2studio。RASC图形化配置大大降低了初始化难度但生成的Keil工程有些选项如下载算法需要手动补充。FSP库功能强大但风格独特需要花时间阅读代码和手册来理解其“堆栈(Stack)”和“实例(Instance)”的概念。官方文档和例程是学习的最佳资料。资料更新瑞萨在Arm生态上发力不久资料和工具更新很快。建议多去官网查看最新版的数据手册、用户手册和FSP库有时新版本会修复旧版的问题。社区支持相比ST瑞萨的中文社区资源可能少一些。遇到问题时可以多在官方论坛、训练营群里提问或者像我一样对照着ST的经验去理解和尝试。这个项目目前实现了基础功能RTC、1PPS信号输出、LED控制、ADC检测、触摸按键和串口调试。更复杂的WS2812动态效果、加速度计手势识别等就需要你在此基础上继续探索了。嵌入式开发就是这样从点灯开始一步步添加功能踩坑、填坑最终做出自己想要的产品。希望这篇长文能为你上手瑞萨RA2E1打开一扇门。