C351 程序基本结构
主程序从 main 开始执行,无参数和返回值。main 通常包含无限循环 while(1) 作为后台任务。示例:
c
void main(void) {
// 初始化代码
while (1) {
// 主循环逻辑
}
}
与 C51 的差异:语法结构一致,无变化。
中断处理函数
标准中断函数
使用 interrupt 关键字声明中断号,无参数和返回值。编译器自动处理现场保存(入栈/出栈)。
c
void ISR_Name(void) interrupt 1 {
// 中断逻辑
}
快速中断
通过 fast_interrupt 关键字实现,用户可手动指定需保存的寄存器以提升响应速度。
与 C51 差异
- C351 不支持
using指定寄存器组(固定使用组 0)。 - 中断号扩展至 63(实际支持 255)。
- 新增快速中断机制。
函数重入模型
默认可重入
所有函数默认支持重入(无需 reentrant 关键字),适合多任务场景。
实现机制
- 使用 16 位虚拟寄存器(BP/VP)管理 XRAM 栈。
- 原生 8 位 SP 仅用于调用返回和中断现场保存。
与 C51 差异
- C51 需显式声明
reentrant,且开销较大。 - C51 默认使用
idata栈,C351 统一使用 XRAM 栈。
变量存储模型
存储规则
- 动态变量(局部变量、参数)位于 XRAM 栈,从高地址向低地址生长。
- 静态变量(全局变量、
static局部变量)从低地址向高地址生长。
优势
- 支持大型动态缓冲区(如局部数组),退出函数后自动释放。
- 最小 XRAM 需求为 256 字节。
与 C51 差异
- C51 变量需手动指定存储区域(
data/xdata等),C351 统一使用 XRAM。
函数参数传递
混合传递规则
- 前两个参数通过寄存器传递(高效)。
- 其余参数通过 XRAM 栈传递。
与 C51 差异
- C51 参数传递依赖编译器和存储模式,规则不统一。
- C351 采用固定"两寄存器+栈"模型。
SFR 与端口定义
扩展 SFR 支持
-
支持地址 <0x80 的 SFR 定义(访问速度与寄存器相同)。
-
扩展 XSFR(XRAM 中的外设寄存器),语法简化:
cxsfr T11L = 0xFE7B; // 替代 C51 的宏定义
优化限制
- 禁止对 SFR/XSFR 的读写操作进行重排序或缓存。
与 C51 差异
- C51 的 SFR 范围限于 0x80--0xFF,且优化行为可能引发问题。
数据类型与运算限制
新增 binary 类型
用于位操作和位域定义,支持 8/16/32 位寄存器语义。
表达式规范
-
禁止复杂表达式(如
(i++) + (i++))。 -
每行仅允许一个二元运算,需拆分多步:
c// 错误示例:return (ADC_RES << 2) | (ADC_RESL & 3); uint16_t x1 = ADC_RES << 2; uint16_t x2 = ADC_RESL & 3; return x1 | x2; -
禁止依赖 PSW/CY 等标志位的跨语句关联。
与 C51 差异
- C51 允许复杂表达式和隐式标志依赖,C351 强制显式拆分。
库函数与重入性
库函数支持
- 禁用
malloc/free(无堆管理)。 - 推荐
sprintf+ 自定义串口输出替代printf(避免不可重入和 XRAM 占用)。
与 C51 差异
- C51 支持堆函数,
printf不可重入且需手动实现getchar。 - C351 提供扩展库(如
STDLIBE、FMTIO)。
启动流程与迁移建议
固定启动过程
- 初始化 XRAM、虚拟寄存器后调用
main,禁止修改启动文件。
迁移注意事项
- 拆分复合表达式为单步操作。
- 消除对 PSW/CY 的隐式依赖。
- 替换
?:为if-else。 - 使用
sprintf+ 串口输出替代printf。
验证方法
编译后对照生成的 A351 汇编代码,确保每条 C 语句对应一段独立汇编指令。