前言
之前我学习过b站江协科技的STM32教程(标准库),了解了一个单片机常用的模块还有初始化流程,并制作了自己的一个小项目。
后来了解到公司要使用瑞萨RL78/G13 的R5F100LEA芯片,所以为了提前适应工作需求,转战瑞萨芯片平台,淘宝上先买了一个R5F100LGA的开发板,里面赠送的课程(基于CS+ For CC)讲得很含糊,只是讲该怎么做,但是为什么要这么做没有深入讲解,让我这种有点基础的都不知其所以。
为了更好地学习CS+ For CC和瑞萨芯片,将自己所探索的内容呈现在此博文中,也是对自己自学历程的一个巩固与回顾。
CS+ For CC 编程过程,目前了解到基本上是 ①模块配置--->②代码自动生成--->③编辑自用模块--->④仿真器Debug调试--->⑤程序烧录运行 这么一个流程,因此我打算按照这个流程,对不同模块及可以实现的功能进行讲解。
第一课程讲解①②部分,也就是如何用Code Generator自动生成各模块文件及代码的过程。
从第二课开始,讲解各个模块的应用,也就是③、④和⑤的内容。
由于软件是刚上手,前面对于软件里面各种设置会讲得详细一些,后面就直接讲解各个模块。
下面开始正文。
第一课 使用Code Generator
一、各个模块设置
1、Clock Generator
1.1 Pin assignment 引脚功能配置
双击Code Generator,右面第一个窗口是配置引脚功能,类比之前学过的STM32相关知识,通过勾选PIOR0~PIOR4 bit,有2的5次方种引脚功能重定义,这里可以直接勾选,下面就会显示引脚不同的功能。

1.1.1 PIORx 位(Pin Function Register)
图里先让你选 PIOR0 ~ PIOR4 这 5 个全局开关。
| 位名 | 作用(一句话) | 一旦置 1 的后果 |
|---|---|---|
| PIOR0 | 把 P1x/P3x/P4x 部分脚 从 GPIO 永久切换成 Timer 输入/输出 | 这些脚再也回不到普通 IO,寄存器里连 PDR 都写不动 |
| PIOR1 | 把 UART/SPI/I²C 专用脚 锁死成 串口功能 | 想临时把 RxD 当 LED 脚?→ 门都没有 |
| PIOR2 | 把 INTP0~11 外部中断脚 锁死 | 只能中断,不能 GPIO |
| PIOR3 | 把 SDA/SCL 脚 锁成 I²C 开漏模式 | 回不到推挽输出 |
| PIOR4 | 把 PCLBUZ0/1 时钟输出脚 锁死 | 只能输出内部主时钟分频,不能当 GPIO |
为什么“一旦决定就不能改”?
因为这些位属于 Option-Byte(选项字节),只有烧录前能写一次,芯片跑起来后写 0 也无效,
所以 Code Generator 在你点 Generate Code 时就把它们固化进.opt文件,以后在代码里再改也不起作用,必须 重新建工程 + 重新烧录全片 才能换功能。
1.1.2 引脚功能列表
下面那张表就是 “引脚最终功能分配”,
每一行 = 一个物理脚 → 一个外设功能,同样 生成后不能动。
| 引脚 | 分配的功能 | 实际意思 |
|---|---|---|
| P17 | TI02/TO02 | Timer 单元 0 通道 2 输入/输出 |
| P31 | TI03/TO03 | Timer 单元 0 通道 3 |
| P05 | TI05/TO05 | Timer 单元 0 通道 5 |
| P76/P77 | INTP10/INTP11 | 外部中断 10/11 |
| P10~P15 | SCK00/SCL00/TxD0/RxD0… | 串口 0 + 串口 2 + I²C 20 |
| P60/P61 | SCLA0/SDAA0 | I²C 从机地址 0(开漏) |
| P140/P141 | PCLBUZ0/PCLBUZ1 | 主时钟分频输出(可接蜂鸣器) |
生成代码后你会看到:
c复制
PIOR0 = 1; // 文件 clk.c 里自动插入 PIOR1 = 1;同时 port.c 里根本不会给这些脚生成
PMx = 0;(方向寄存器),因为硬件已强制接管。
1.1.3 Reflect in Pin按钮
这个按钮用来生成引脚功能图,引脚功能图通过以下方式打开
-
在 Code Generator 窗口 右侧标签页 找到
“Pin Diagram”(引脚示意图)或
“Pin Map”(表格形式)→ 点击即可。 -
仍没有?菜单 View → Pin Diagram 勾选,或快捷键 Ctrl + D(部分版本)。
打开后你会看到:
-
芯片封装俯视图(DIP/QFN/LQFP 都有),
-
每个引脚小方块里实时显示 已分配的功能缩写(如 TI02、RxD0、SCL00),
-
绿色 = 已占用,灰色 = 空闲,红色 = 冲突。
1.1.4 Fix Settings 红字警告
这个按钮就是用来锁定引脚功能,一旦锁定,只能通过新建工程来修改引脚功能
“When it’s decided once, it isn’t possible to change it later.”
→ 不是吓唬你,是 硬件限制:
-
Option-Byte 只能整片擦除才能重写;
-
PIOR 位写 1 后无法清 0;
-
引脚功能硬熔丝,跑 application 时改不了。
所以 Code Generator 把这一步放在最前面,让你 先想清楚“哪些脚必须留给外设”,再往下走时钟、定时器、串口等细节配置。
1.2 Clock setting
由于学过STM32,所以知道配置芯片的第一步应该是配置系统时钟,点击Clock Generator下面的Colck setting,会发现有很多配置选项,如下图所示


1.2.1 Operation mode setting主运行模式设置
决定 CPU/Flash/外设最高允许频率 和 低压复位阈值。
| 图中选项 | 官方缩写 | 允许 VDD 范围 | 最高 CPU 频率 | 典型场景 |
|---|---|---|---|---|
| High speed main mode 3.6 V ≤ VDD ≤ 5.5 V | HSM(3.6) | 3.6-5.5 V | 32 MHz(Flash 0 等待) | 5 V 电机/继电器 |
| High speed main mode 2.7 V ≤ VDD ≤ 5.5 V | HSM(2.7) | 2.7-5.5 V | 24 MHz | 3.3 V 主电源 |
| High speed main mode 2.4 V ≤ VDD ≤ 5.5 V | HSM(2.4) | 2.4-5.5 V | 16 MHz | 锂电 2 串 |
| Low speed main mode 1.8 V ≤ VDD ≤ 5.5 V | LSM(1.8) | 1.8-5.5 V | 8 MHz | 纽扣电池 |
| Low voltage main mode 1.6 V ≤ VDD ≤ 5.5 V | LVM(1.6) | 1.6-5.5 V | 4 MHz | 超低功耗传感器 |
你勾哪一档,Code Generator 就自动:
把 LVI 低压检测阈值设成该档最低值(例如 2.7 V 档 → LVI 2.7 V);
把 Flash 读取等待周期设成对应值(32 MHz 时 0 等待,16 MHz 时 1 等待);
如果后续时钟树填了 高于该档允许的 CPU 频率,会弹红字禁止 Generate。
1.2.2 EVDD 设置(I/O 口供电档位)
EVDD 是 P0~P7 等 I/O 引脚的独立供电脚,和内部内核电压无关,只决定 引脚电平识别/驱动能力。
| 图中选项 | 允许 EVDD 范围 | 典型用途 |
|---|---|---|
| 4.0 V ≤ EVDD ≤ 5.5 V | 5 V 接口 | 驱动继电器、MOSFET、5 V 逻辑 |
| 2.7 V ≤ EVDD ≤ 5.5 V | 3.3 V 接口 | 接 3.3 V 传感器、Flash、蓝牙模块 |
| 2.4 V ≤ EVDD ≤ 5.5 V | 2.5 V 接口 | 低功耗 DDR、SD 卡 |
| 1.8 V ≤ EVDD ≤ 5.5 V | 1.8 V 接口 | 接 1.8 V 外设、低功耗 MEMS |
| 1.6 V ≤ EVDD ≤ 5.5 V | 1.6 V 接口 | 纽扣电池直接供电 |
1.2.3 主系统时钟fMAIN(芯片的心脏)
“Main system clock setting”
→ 决定 CPU 和外设 用哪路时钟。
| 选项 | 来源 | 典型用法 |
|---|---|---|
| ✅ High-speed OCO (fIH) | 内部高速 RC | 默认、省晶振、32 MHz 内 |
| High-speed system clock (fMX) | 外部晶振或时钟 | 要精准度或 >32 MHz 时选 |
你勾了 fIH,Code Generator 会生成:
CKC = 0x00;// 选 flH 当主时钟
1.2.4 High-speed OCO clock setting(片上高速时钟设置)
“High-speed OCO clock setting”
→ 当上面选了 fIH,这里才亮;决定 内部 RC 跑多少 MHz。
| 图中值 | 实际输出 | 寄存器 |
|---|---|---|
| 32 MHz | FHOCO 64 MHz ÷ 2 | HOCODIV = 1 |
✅ 可下拉改 16 / 8 / 4 MHz → 频率越低,动态功耗越低。
1.2.5 高速系统时钟(外部晶振)
“High-speed system clock setting”
→ 只有当你想 用外部晶振 才展开。
| 子项 | 含义 | 例子 |
|---|---|---|
| X1 oscillation (fX) | 在 X1-X2 脚接晶振 | 5 MHz 晶振 |
| External clock input (fEX) | 直接灌方波到 X1 | 有源晶振 |
| Frequency | 你填的晶振频率 | 5 MHz |
| Stable time | 等晶振稳定多久再切换 | 52428 个周期 ≈ 10 ms |
Code Generator 会生成:
OSTS = 0x07; // 选 2^18 周期稳定时间
CMC = 0x10; // 使能 X1 振荡
while(!OSTC_CKE); // 等待稳定
CKC = 0x02; // 切到 fMX 当主时钟
1.2.6 子系统时钟fSUB(给RTC/看门狗使用)
“Subsystem clock (fSUB) setting”
→ 32.768 kHz,只要低功耗定时或 RTC 就勾它。
| 子项 | 用途 |
|---|---|
| XT1 oscillation | 接 32.768 kHz 晶振 |
| External subclock input | 直接灌 32 kHz 方波 |
勾了 → 自动生成
RTCEN = 1;并配置 XT1 低驱模式。
1.2.7 低功耗相关
| 选项 | 作用 |
|---|---|
| Subsystem clock in STOP, HALT mode setting | 让 STOP 模式下 RTC/看门狗继续跑 |
| Internal low-speed oscillation clock (fIL) | 15 kHz 内部低速 RC,给看门狗或唤醒定时器 |
1.3 On-chip debug setting
On-chip debug operation setting选项,要选择Used,并且Emulator setting里面我用的是E2 Lite。

2、Port

2.1 Port选项
这里的Port就对应了STM32中的GPIO口,通过配置不同的Port,实现输入输出初始化。
例如,P41里面,有三个选项:Unused\In\Out,分别代表了不使用、输入模式和输出模式;
*如果选择In,那么后面的Pull-up(上拉输入模式)就可以勾选了。
*如果选择Out,就默认为推挽输出模式,至于开漏输出模式,等I2C那一课再进行配置和学习。
这里通过看开发板的原理图,知道LED灯是在P41、P42和P43上,所以可以通过控制这几个端口进行控制点灯操作。



3、Timer选项
这里选择想要使用的定时器,下拉菜单选择自己想要的功能,选择好后,后面Channel0就可编辑了

| 通道 | 可选功能(下拉菜单) | 人话解释 | 典型场景 | 是否需要引出脚 |
|---|---|---|---|---|
| 0 | Interval timer | 周期中断 / 唤醒 | 系统滴答、喂狗、低功耗采样 | ❌ 纯内部 |
| 1 | Interval timer Square wave output | 周期中断 or 50% 方波输出 | 1 kHz 时钟给外设 | ✅ 需要 TO01 引脚 |
| 2 | Divider function External event counter | 把输入时钟 分频后输出 or 数外部脉冲个数 | 频率合成器、转速计 | ✅ 需要 TI02/TO02 |
| 3 | Input pulse interval measurement High/Low width measurement | 捕获 两个上升沿之间时间 or 高/低电平宽度 | 红外解码、PWM 占空比测量 | ✅ 需要 TI03 |
| 4 | Delay count function PWM output (master) | 硬件 精确定时 n µs or 单路 PWM | 步进电机加减速、LED 调光 | ✅ 需要 TO04 |
| 5 | One-shot pulse (software trigger) One-shot pulse (external trigger) | 软件 / 外部触发 输出一个固定宽度脉冲 | 点火、快门、超声测距发射 | ✅ 需要 TO05 |
| 6 | Multiple PWM output (master) | 3 路互补/同步 PWM(与通道 7 从机配合) | BLDC 六步、开关电源 | ✅ 需要 TO60~TO62 |
| 7 | Unused | 释放为普通 GPIO | 当 IO 口用 |
Channel 0

| 选项 | 含义 | 生成代码后你能得到什么 |
|---|---|---|
| Interval timer setting | 把通道 0 当成 纯周期中断源 | INTTM00 每 500 ms 进一次 ISR |
| Interval value (16 bits) | 比较寄存器 CMP00 的初值 | 填 500 ms → 工具自动算分频 + 计数次数,生成CMP00 = 31249; |
| (Actual value: 500) | 提示 “我已经考虑分频后仍能做到 500 ms” | 如果填 1 ms,它会提示 0.999 ms 之类 |
| Generates INTTM00 when counting is started | 启动计数 立刻产生一次中断 | 用来做 “第一次马上执行” 的调度 |
| Interrupt setting → End of timer channel 0 count | 允许 计数溢出中断 | TMMK00 = 0; // 解除屏蔽 |
| Priority → Low | 设定 中断优先级 0~3 | 0=高 3 |
4、Watch Dog
看门狗是默认开启的,咱们现在入门,先不学习,所以勾选Unused

二、代码生成Generate Code
1、生成文件的含义
点击Generate Code,自动生成代码。

以下是Kimi自动生成的解释:
1.1 r_cg_macrodriver.h ⭐ 必须先看
-
地位 = STM32 的
stm32f1xx.h+system_stm32f1xx.h -
里面集中了 所有寄存器位定义、union-bit 结构体、全局宏(
TRUE/FALSE、__set_interrupt_level()等)。 -
任何
.c文件只要#include "r_cg_macrodriver.h"就能直接P0_bit.no0 = 1;
1.2 r_cg_cgc.h / .c ⭐ 时钟“大管家”
-
CGC = Clock Generator Controller
-
生成 系统时钟切换、Flash 等待周期、上电时钟源 等代码;
-
main.c 第一句
R_CGC_Create()就是它提供的,别删除。
1.3 r_cg_port.h / .c ⭐ GPIO“HAL”
-
等价于 STM32 的
gpio.c/.h -
根据你在 Pin Assignment 里勾的 方向、推挽/开漏、上拉,生成:
cR_PORT_Create(); // 一次性配置 P0_bit.no3 = 1; // 位操作宏也在这里 -
用户常调用:
R_PORT_Create();必须最先执行。
1.4 r_cg_timer.h / .c ⭐ 定时器驱动
-
对应 STM32 的
tim.c/.h -
包含 Interval Timer、PWM、输入捕获、单脉冲 等通道初始化 + 运行时 API:
cR_TAU0_Create(); // 初始化 R_TAU0_Channel0_Start(); // 启动 R_TAU0_Channel4_Set_Duty(duty); -
中断向量表 也已帮你填好,直接写 ISR 体即可。
1.5 r_cg_userdefine.h ✅ 用户专属“黑板”
-
唯一允许你随意改动的生成文件
-
里面只有一堆空宏和注释,用来放:
-
全局宏开关
-
板载 LED、按键引脚别名
-
你自己的
extern声明
-
-
重新 Generate 时不会被覆盖,放心写。
1.6 r_main.c ✅ 你的“新 main.c”
-
等价于 STM32 的
main.c -
模板已给出:
c复制
R_Systeminit(); // 调用所有 r_cg_xxx_Create() while (1) { /* Start user code → 在这里填任务 */ } -
只改用户区间,其余别动,重新 Generate 会自动合并。
1.7 其它 r_cg_xxx.c/.h(未截图但常见)
| 文件 | 作用 |
|---|---|
r_cg_serial.c/.h | UART/SPI/I²C 初始化 + 发送/接收 API |
r_cg_adc.c/.h | ADC 扫描、单次/连续、结果读取 |
r_cg_intc.c | 外部中断 INTP0~INTP11 向量表 + 空 ISR |
r_cg_wdt.c | 看门狗启动与喂狗接口 |
1.8 🧭 快速上手路线图
-
先读
r_cg_macrodriver.h→ 知道怎么位操作; -
main.c 里只写业务 → 别改生成区;
-
要调外设 → 先看对应
r_cg_xxx.h提供的 API(函数名都很直白); -
宏/别名放
r_cg_userdefine.h→ 重新 Generate 不会丢; -
遇到“玄学错误” → Rebuild Project,别 Clean 单个文件。
记住:这些文件 = 瑞萨帮你写好的“标准库”,你只管填用户区间,就能像 STM32 一样快速开发。
注:上面生成文件是根据Code Generator开启模块生成的,比如开启了Timer的某个通道,那么左边栏会多出 r_cg_timer.c、r_cg_timer.h和r_cg_timer_user.c文件;如果生成完后,再用Code Generator编辑端口,Unused Timer的所有通道,再次生成代码,那么相应的文件就会消失。
上面是AI生成的内容,下面咱们自己首先看看生成的main函数里面都有什么
2、函数文件内容详细介绍
2.1 r_main.c

2.1.1 Includes
这里面包含了所需要用到的头文件,Code Generator自动生成的include不要动,如果想include自己做的.h文件,那么需要在下面两行中间进行填写,否则下次自动生成代码后,会覆盖掉![]()
2.1.2 General Variables and Functions 全局变量和函数
如果想插入自己的全局变量和函数,那么需要在下面两行中间进行填写,否则下次自动生成代码后,会覆盖掉

注意到,这里定义了一个R_Main_UserInit()函数,跳转函数定义,发现就在main文件最下面:

2.1.3 EI()函数
里面有个EI()函数,右键跳转到函数定义,发现找不到定义。
以下是Kimi的解释(总之相当于使能中断,最好放在所有功能初始化最后面)
*/****************************************************************************/*
EI(); 并不是 C 函数,而是 RL78 编译器提供的“内置汇编宏”(intrinsic macro)。
打开 <intrinsics.h>(或 r_cg_macrodriver.h 里已间接包含)即可看到原型:
c
#define EI() __asm("EI")
2.1.3.1 作用
EI 是 RL78 指令助记符,含义一句话:
置位 PSW.I 标志位,全局允许可屏蔽中断(IRQ0~IRQ31、INTP0~INTP11、TAU0、UART0…)。
等价于 ARM 的 __enable_irq();
没有参数,没有返回值,执行后立即生效。
2.1.3.2 为什么必须放在 R_Main_UserInit() 末尾
Code Generator 生成的流程:
c
R_Systeminit(); // 关中断状态下初始化时钟、端口、定时器、UART
R_Main_UserInit(); // 给用户二次初始化,**仍关中断**
while (1) { … } // 主循环
若你在用户初始化里 开定时器、UART 中断,但 不打开全局中断,
则 中断标志会置位,但 CPU 不响应 → 看起来“程序不跑”。
因此 官方模板在 R_Main_UserInit() 最后放 EI();,
保证用户所有外设初始化完成后再开总中断,避免 初始化期间误入 ISR。
2.1.3.3 使用注意
| 要点 | 说明 |
|---|---|
| 别随意提前 | 如果初始化序列里 有对时序敏感的操作(如 I²C 发送),EI() 可移到初始化全部结束后再手动调用。 |
与 DI() 配对 | DI() 同样是内置宏 __asm("DI"),关全局中断,用于临界段。 |
| 中断优先级 | EI() 只是 总开关,各外设中断还需 单独使能(XXMK = 0)。 |
✅ 一句话记忆
EI(); = RL78 版 __enable_irq(),使能中断
一条汇编宏,作用是打开 CPU 总中断开关;
放在 R_Main_UserInit() 末尾就是 “用户初始化完再开中断”,防止初始化期间被打断。
*/****************************************************************************************/*
2.2 r_systeminit.c
里面有两个函数,void R_Systeminit(void)与hdwinit(void)


2.2.1 R_Systeminit(void)
| 步骤 | 语句 | 硬件动作 | 设计原因 | 能否改顺序/值 |
|---|---|---|---|---|
| 1 | PIOR = 0x00U; | 把 PIOR0~4 全部清 0 → 所有引脚 暂时处于 GPIO 模式(未锁定) | 上电 PIOR 随机,先清掉再配置可防止 Code Generator 后面写 Option-Byte 时冲突 | 不要改顺序;值必须 0x00(后面 Code Generator 会根据你勾的再置位) |
| 2 | R_CGC_Get_ResetSource(); | 只读操作 → 读取 RSTSR 寄存器 并把结果保存在全局变量 g_cgc_reset_source | 让程序 后续判断是 POR/BOR/看门狗/软件复位,以便 差异化初始化(例如狗复位时不擦数据) | 可以删掉,但 推荐保留(调试时能打印复位源) |
| 3 | R_CGC_Create(); | 时钟树初始化 → 设置 主时钟源、Flash 等待周期、CPU 频率、内部电压稳压时间 | 所有外设都依赖时钟,必须最先配置;顺序不能后移 | 顺序 固定;寄存器值由 Code Generator 根据你选的时钟参数自动生成 |
| 4 | R_PORT_Create(); | GPIO 初始化 → 写 PM/POM/PU/PIOR 等,把引脚 锁成你勾的功能(推挽/开漏/上拉/复用) | 时钟稳定后才能 安全切换引脚模式;必须在所有外设初始化前完成 | 顺序 固定;不要手工改值,重新 Generate 即可 |
| 5 | R_TAU0_Create(); | 定时器单元 0 初始化 → 写 TMR/TPR/TDR 寄存器,停止计数、装初值、清标志 | 后面 用户代码随时可能启动定时器,所以 先初始化再开中断 | 如果你 没勾 TAU0,Code Generator 会 自动删掉这句 |
| 6 | IAWCTL = 0x00U; | 非法访问检测控制寄存器清 0 → 关闭硬件对非法地址/指令的复位 | 调试阶段 先关掉,避免 踩飞指针导致芯片复位;量产可打开 | 可以 后期改为 0xFF 使能全检测,顺序必须在最后(防止前面配置时误触发) |
✅ 一句话总结顺序
先清脚 → 读复位源 → 给时钟 → 锁引脚 → 装定时器 → 关硬件看门狗(非法访问)
整套流程 由 Code Generator 固化,用户不要改顺序,只改值(通过图形界面重新 Generate 即可)。
备注:
(1)跳转R_PORT_Create()函数,可发现里面都是一些寄存器位与位或操作,比较底层,这个就像STM32的标准库函数。
(2)R_Systeminit(void)里面的初始化函数,是根据Code Generator开启模块进行编辑的,比如开启了Timer的某个通道,那么,R_Systeminit(void)里面就会多出一个R_TAU0_Create();用于对定时器的初始化。
(3)同样的,(2)中,如果生成完代码后,再用Code Generator Unused已生成的模块,那么相应的初始化函数会在R_Systeminit(void)里面消失。
2.2.2 hdwinit(void)
hdwinit = Hardware Init
🌟重点:里面包含了R_Systeminit(),并且这个函数是被main函数隐形调用的,不能修改函数名称。
DI()这个函数与EI()相反,Disable irq,停止使能中断。
2.3 r_cg_cgc.c
2.3.1 R_CGC_Create(void)
这个文件全程是 renesas_code generator_colck generate controller(时钟生成控制器)
瑞萨的子文件喜欢以这种方式命名
此c文件里面只有一个void R_CGC_Create(void)函数,用来生成时钟相关指令,如果想修改,建议还是直接用code generator里面设置好后自动生成,比较方便,要不然还要查阅里面的函数和寄存器,比较麻烦。
2.4 r_cg_cgc_user.c
2.4.1 R_CGC_Get_ResetSource(void)
这个文件里面只有一个void R_CGC_Get_ResetSource(void)函数,用来获取复位源,找到是什么原因导致的RL78芯片复位。
这里的“复位”指的是 让 RL78 芯片立刻回到初始状态并重新开始执行程序 的任何一种硬件或软件触发事件;不是“软件重启 main()”,而是 真正拉低/拉高内部复位逻辑,使 PC 指针回到 0x0000 并重新初始化大部分寄存器。
在 RL78 里 RESF 寄存器 一共记录 6 类复位源,下面用 一句话 + 实际场景 说明每种“复位”到底指什么:
| RESF 位 | 复位源名称 | 一句话解释 | 常见触发场景 |
|---|---|---|---|
| bit0 | POR (Power-On Reset) | 真正掉电后再上电 | 插 USB、上电瞬间、供电从 0 V 爬升 |
| bit1 | LVD (Low-Voltage Detect) | 电压掉到设定阈值以下 | 电池快没电、负载突增、电源线过长 |
| bit2 | WDT (Watchdog Timer) | 程序跑飞/卡死,没喂狗 | while(1) 里死循环、中断没返回 |
| bit3 | AWDT (Auxiliary WDT) | 独立看门狗或窗口狗超时 | 同上,但时钟源不同(低速) |
| bit4 | Software Reset | 软件写特殊寄存器自复位 | 用户代码里 SWITCH 寄存器写 0xAC |
| bit5 | RESIN (External Reset Pin) | 外部 RESET 脚被拉低 | 按下复位按键、调试器点击 Reset、ISP 工具拉低 |
只要出现以上 任何一种,硬件都会:
让 PC = 0x0000,
把原因写进 RESF 寄存器(只保留到第一次读),
重新执行启动文件 →
R_SystemInit()→main()。
因此 R_CGC_Get_ResetSource() 保存的 “复位” 就是 这些硬件事件的快照,不是软件层面的 NVIC_SystemReset() 概念。
2.5 r_cg_port.c(GPIO口)
2.5.1 R_PORT_Create
这个是根据code generator前,根据手动配置端口结果生成的代码,相当于STM32里面的GPIO_Init(),初始化端口,配置输出输入模式等
2.6 r_cg_port_user.c(MyGPIO.c)
这个文件里面没有代码,但是为了方便用户在初始化port口后修改端口状态,提前给用户创建好的一个文件,如果想在main中调用函数修改port口状态,可以将相关函数封装在这个文件里面。
2.7 r_cg_timer.c(定时器相关)
2.7.1 R_TAU0_Create
这个函数用来初始化定时器,经过上面的分析,瑞萨文件里面 _Creat 函数就相当于 _Init 初始化函数,用来配置内部寄存器,用于模块的初始化设置。具体设置参数,可以通过Code Generator 编辑器里面的Timer进行相关参数的编辑,然后自动生成代码。
2.7.2 R_TAU0_Channel0_Start
这个函数用于定时器的开启。
之前我在Code Generator里面设置了Channel 0 所以这里面生成了Channel 0 的Strat函数。
2.7.3 R_TAU0_Channel0_Stop
这个函数用于定时器的停止。
2.8 r_cg_timer_user.c文件
(用户往中断函数里面填写需要执行的代码)
2.8.1 #pragma interrupt INTTM00 r_tau0_channel0_interrupt

作用:把中断向量号 INTTM00 绑定到 C 函数 r_tau0_channel0_interrupt,
也就是
当 TAU0 通道 0 的计数器溢出时,硬件自动跳转到
r_tau0_channel0_interrupt()执行。
| 关键词 | 解释 |
|---|---|
pragma interrupt | 瑞萨编译器特有指令,声明“下面这个函数是中断服务例程” |
INTTM00 | 中断向量表里的固定符号,对应 TAU0 通道 0 溢出事件 |
r_tau0_channel0_interrupt | 你自己(或生成器)写的 C 函数名,函数体里放用户代码 |
使用流程
-
Code Generator 已经帮你 使能中断、填好中断向量表;
-
你只需在 保留区 写业务:
void r_tau0_channel0_interrupt(void)
{
/* 用户代码:1 ms 滴答、翻转 LED、喂狗 … */
}
-
编译器遇到
*在向量表里把pragma interrupt会自动:INTTM00入口填成 函数地址;
*给函数加上__interrupt属性,返回用RETI而非普通RET。
一句话记忆
#pragma interrupt INTTM00 r_tau0_channel0_interrupt
= “TAU0 通道 0 一溢出,就进这个 C 函数” —— 相当于 STM32 的
void TIM2_IRQHandler(void) { ... }
只是绑定方式用 pragma 而非向量表文件。
2.8.2 __interrupt static void r_tau0_channel0_interrupt(void)

这个函数相当于
void TIM2_IRQHandler(void) { ... }
可以在下面填写进入中断后需要执行的代码指令。
至此,入门用到的Code Generator设置及代码生成文件的介绍就结束了,下一课程进行具体功能的实现。
964

被折叠的 条评论
为什么被折叠?



