您好,感谢您分享这个链接。我已经查看了该帖子的内容。
问题分析
帖子中描述的现象是:直接对 PWMA 相关寄存器(如 PWMA_RCR、PWMA_CR1)进行赋值操作时,PWM 不工作;而通过 WritePWMA() 函数写入时则正常工作。
根本原因
这是 STC 单片机中 高级 PWM(PWMA)寄存器位于扩展 RAM 区域(XFR) 所导致的典型问题。
在 STC 的 8 位单片机(如 STC8H、STC8G、STC8A8K64D4 等系列)中,高级 PWM 的寄存器(如 PWMA_CR1、PWMA_RCR、PWMA_CCR1 等)属于 扩展特殊功能寄存器(XFR),地址范围在 0xFE000xFEFF 或 0xFF000xFFFF 区域。要访问这些寄存器,必须先使能扩展 RAM 访问权限。
正确的做法
在使用 PWMA_CR1、PWMA_RCR 等寄存器符号之前,必须先执行:
P_SW2 |= 0x80; // 使能访问 XFR(扩展特殊功能寄存器)
如果没有执行这一句,直接写 PWMA_RCR = rep; 这样的语句,编译器实际上操作的是 SFR 映射区中相同地址的普通寄存器,而不是高级 PWM 的 XFR 寄存器,因此 PWM 不会工作。
为什么 WritePWMA() 可以工作?
WritePWMA() 函数内部通常已经封装了通过指针访问 XFR 区域的逻辑(例如使用 volatile 指针指向 XFR 地址并写入),或者函数内部已经包含了 P_SW2 |= 0x80; 的操作,因此能够正确写入。
解决方案
请在初始化 PWM 的代码开头添加:
P_SW2 |= 0x80; // 使能访问 XFR 扩展特殊功能寄存器
然后就可以直接使用 PWMA_RCR = rep;、PWMA_CR1 |= 0x89; 等直接赋值方式了。
完整示例框架
void PWMA_Init(void)
{
P_SW2 |= 0x80; // 使能访问 XFR
// 以下直接赋值即可正常工作
PWMA_CR1 = 0x00; // 先清零控制寄存器1
PWMA_CR2 = 0x00; // 先清零控制寄存器2
// ... 配置其他 PWM 寄存器 ...
PWMA_RCR = rep; // 重复计数寄存器
PWMA_CR1 |= 0x89; // 使能ARR预装载,单脉冲模式,开始计时
}
总结
| 问题 |
原因 |
解决 |
直接赋值 PWMA_RCR = rep; 不工作 |
未使能 XFR 访问权限 |
在初始化开头加 P_SW2 |= 0x80; |
WritePWMA() 函数可以工作 |
函数内部已处理 XFR 访问 |
也可继续使用该函数 |
如果您能告诉我您具体使用的是哪个型号的 STC 单片机(如 STC8H8K64U、STC8G2K64S4 等),我可以帮您进一步确认 PWM 寄存器的具体配置细节。
🔍 搜索 "https://www.stcaimcu.com/thread-24813-1-1.html"
⏱️ 查找用时 3.0s | 总回答用时 12.8s