PWM寄存器配制问题
PWMA_RCR = rep; //重复计数寄存器,计数 rep 个脉冲后产生更新事件PWMA_CR1 |= 0x89;//使能ARR预装载,单脉冲模式,开始计时
//WritePWMA((char)&PWMA_CR1, 0x89);
//WritePWMA((char)&PWMA_RCR, rep);
直接赋值给寄存器PWM不工作,需要WritePWMA((char)&PWMA_CR1, 0x89);WritePWMA((char)&PWMA_RCR, rep);
<p>您好,感谢您分享这个链接。我已经查看了该帖子的内容。</p>
<h2>问题分析</h2>
<p>帖子中描述的现象是:<strong>直接对 PWMA 相关寄存器(如 <code>PWMA_RCR</code>、<code>PWMA_CR1</code>)进行赋值操作时,PWM 不工作;而通过 <code>WritePWMA()</code> 函数写入时则正常工作。</strong></p>
<h2>根本原因</h2>
<p>这是 STC 单片机中 <strong>高级 PWM(PWMA)寄存器位于扩展 RAM 区域(XFR)</strong> 所导致的典型问题。</p>
<p>在 STC 的 8 位单片机(如 STC8H、STC8G、STC8A8K64D4 等系列)中,高级 PWM 的寄存器(如 <code>PWMA_CR1</code>、<code>PWMA_RCR</code>、<code>PWMA_CCR1</code> 等)属于 <strong>扩展特殊功能寄存器(XFR)</strong>,地址范围在 <code>0xFE00</code><del><code>0xFEFF</code> 或 <code>0xFF00</code></del><code>0xFFFF</code> 区域。要访问这些寄存器,<strong>必须先使能扩展 RAM 访问权限</strong>。</p>
<h3>正确的做法</h3>
<p>在使用 <code>PWMA_CR1</code>、<code>PWMA_RCR</code> 等寄存器符号<strong>之前</strong>,必须先执行:</p>
<pre><code class="language-c">P_SW2 |= 0x80; // 使能访问 XFR(扩展特殊功能寄存器)
</code></pre>
<p>如果没有执行这一句,直接写 <code>PWMA_RCR = rep;</code> 这样的语句,编译器实际上操作的是 <strong>SFR 映射区中相同地址的普通寄存器</strong>,而不是高级 PWM 的 XFR 寄存器,因此 PWM 不会工作。</p>
<h3>为什么 <code>WritePWMA()</code> 可以工作?</h3>
<p><code>WritePWMA()</code> 函数内部通常已经封装了通过指针访问 XFR 区域的逻辑(例如使用 <code>volatile</code> 指针指向 XFR 地址并写入),或者函数内部已经包含了 <code>P_SW2 |= 0x80;</code> 的操作,因此能够正确写入。</p>
<h2>解决方案</h2>
<p>请在初始化 PWM 的代码开头添加:</p>
<pre><code class="language-c">P_SW2 |= 0x80; // 使能访问 XFR 扩展特殊功能寄存器
</code></pre>
<p>然后就可以直接使用 <code>PWMA_RCR = rep;</code>、<code>PWMA_CR1 |= 0x89;</code> 等直接赋值方式了。</p>
<h3>完整示例框架</h3>
<pre><code class="language-c">void PWMA_Init(void)
{
P_SW2 |= 0x80; // 使能访问 XFR
// 以下直接赋值即可正常工作
PWMA_CR1 = 0x00; // 先清零控制寄存器1
PWMA_CR2 = 0x00; // 先清零控制寄存器2
// ... 配置其他 PWM 寄存器 ...
PWMA_RCR = rep; // 重复计数寄存器
PWMA_CR1 |= 0x89; // 使能ARR预装载,单脉冲模式,开始计时
}
</code></pre>
<h2>总结</h2>
<table>
<thead>
<tr>
<th>问题</th>
<th>原因</th>
<th>解决</th>
</tr>
</thead>
<tbody>
<tr>
<td>直接赋值 <code>PWMA_RCR = rep;</code> 不工作</td>
<td>未使能 XFR 访问权限</td>
<td>在初始化开头加 <code>P_SW2 |= 0x80;</code></td>
</tr>
<tr>
<td><code>WritePWMA()</code> 函数可以工作</td>
<td>函数内部已处理 XFR 访问</td>
<td>也可继续使用该函数</td>
</tr>
</tbody>
</table>
<p>如果您能告诉我您具体使用的是哪个型号的 STC 单片机(如 STC8H8K64U、STC8G2K64S4 等),我可以帮您进一步确认 PWM 寄存器的具体配置细节。</p>
<hr />
<p><a href="https://www.stcaimcu.com/plugin.php?id=twpx_xunsearch&mod=forum&q=https%3A%2F%2Fwww.stcaimcu.com%2Fthread-24813-1-1.html&f=_all&m=yes&syn=yes&s=relevance&fid=0">🔍 搜索 "https://www.stcaimcu.com/thread-24813-1-1.html"</a></p>
<p>⏱️ 查找用时 3.0s | 总回答用时 12.8s</p>
EAXFR = 1; //使能访问 XFR
CKCON = 0x00;//设置外部数据总线速度为最快
WTST = 0x00;
P_SW2 |= 0x80; //SFR enable
已经加了这条语句了 但还是无效
页:
[1]