阿林 发表于 2026-7-4 09:41:28

AI8H2K32U P0.2脚PWM7_3无法输出PWM

AI8H2K32U P0.2脚PWM7_3的PWM用官方提供库程序还是自己写程序,都没有PWM输出


/***************串口初始化函数 *****************/
void        PWM_config(void)
{
        PWMx_InitDefine                PWMx_InitStructure;
       
        //PWMx_InitStructure.PWM_Mode    =        CCMRn_PWM_MODE1;        //模式,                CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
        //PWMx_InitStructure.PWM_Duty    = PWMB_Duty.PWM5_Duty;        //PWM占空比时间, 0~Period
        //PWMx_InitStructure.PWM_EnoSelect   = ENO5P;                                //输出通道选择,        ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
        //PWM_Configuration(PWM5, &PWMx_InitStructure);                        //初始化PWM,PWMA,PWMB

        //PWMx_InitStructure.PWM_Mode    =        CCMRn_PWM_MODE1;        //模式,                CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
        //PWMx_InitStructure.PWM_Duty    = PWMB_Duty.PWM6_Duty;        //PWM占空比时间, 0~Period
        //PWMx_InitStructure.PWM_EnoSelect   = ENO6P;                                //输出通道选择,        ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
        //PWM_Configuration(PWM6, &PWMx_InitStructure);                        //初始化PWM,PWMA,PWMB

        PWMx_InitStructure.PWM_Mode    =        CCMRn_PWM_MODE1;        //模式,                CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
        PWMx_InitStructure.PWM_Duty    = PWMB_Duty.PWM7_Duty;        //PWM占空比时间, 0~Period
        PWMx_InitStructure.PWM_EnoSelect   = ENO7P;                                //输出通道选择,        ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
        PWM_Configuration(PWM7, &PWMx_InitStructure);                        //初始化PWM,PWMA,PWMB

        //PWMx_InitStructure.PWM_Mode    =        CCMRn_PWM_MODE1;        //模式,                CCMRn_FREEZE,CCMRn_MATCH_VALID,CCMRn_MATCH_INVALID,CCMRn_ROLLOVER,CCMRn_FORCE_INVALID,CCMRn_FORCE_VALID,CCMRn_PWM_MODE1,CCMRn_PWM_MODE2
        //PWMx_InitStructure.PWM_Duty    = PWMB_Duty.PWM8_Duty;        //PWM占空比时间, 0~Period
        //PWMx_InitStructure.PWM_EnoSelect   = ENO8P;                                //输出通道选择,        ENO1P,ENO1N,ENO2P,ENO2N,ENO3P,ENO3N,ENO4P,ENO4N / ENO5P,ENO6P,ENO7P,ENO8P
        //PWM_Configuration(PWM8, &PWMx_InitStructure);                        //初始化PWM,PWMA,PWMB

        PWMx_InitStructure.PWM_Period   = 2047;                                        //周期时间,   0~65535
        PWMx_InitStructure.PWM_DeadTime = 0;                                        //死区发生器设置, 0~255
        PWMx_InitStructure.PWM_MainOutEnable= ENABLE;                        //主输出使能, ENABLE,DISABLE
        PWMx_InitStructure.PWM_CEN_Enable   = ENABLE;                        //使能计数器, ENABLE,DISABLE
        PWM_Configuration(PWMB, &PWMx_InitStructure);                        //初始化PWM通用寄存器,PWMA,PWMB

        NVIC_PWM_Init(PWMB,DISABLE,Priority_0);

        //PWM5_SW(PWM5_SW_P20);                                        //PWM5_SW_P20,PWM5_SW_P17,PWM5_SW_P00,PWM5_SW_P74
        //PWM6_SW(PWM6_SW_P21);                                        //PWM6_SW_P21,PWM6_SW_P54,PWM6_SW_P01,PWM6_SW_P75
        PWM7_SW(PWM7_SW_P02);                                        //PWM7_SW_P22,PWM7_SW_P33,PWM7_SW_P02,PWM7_SW_P76
        //PWM8_SW(PWM8_SW_P23);                                        //PWM8_SW_P23,PWM8_SW_P34,PWM8_SW_P03,PWM8_SW_P77
}


/******************** 主函数**************************/
void main(void)
{
        EAXSFR();                /* 扩展寄存器访问使能 */
        //PWMB_Duty.PWM5_Duty = 128;
        //PWMB_Duty.PWM6_Duty = 256;
        PWMB_Duty.PWM7_Duty = 512;
        //PWMB_Duty.PWM8_Duty = 1024;
       
        GPIO_config();
        Timer_config();
        PWM_config();
        EA = 1;

        while (1);
}

各位大佬,问题在哪里,急等

狂热主宰 发表于 2026-7-4 10:22:59

配置PWMB_PS寄存器
信号输出到对应Pxx

狂热主宰 发表于 2026-7-4 10:27:37

多数I/O 口上电后
默认的状态为高阻输入

神农鼎 发表于 2026-7-7 16:26:14


神农鼎 发表于 2026-7-7 16:26:35

<p>好的,手册信息已经查到了。现在我来给出完整的解决方案。</p>
<hr />
<h2>完整解决方案</h2>
<p>根据手册 <strong>&quot;16位高级PWM定时器,支持正交编码器&quot;</strong> 章节和 <strong>&quot;I/O口&quot;</strong> 章节,你的问题出在 <strong>两个关键配置遗漏</strong>:</p>
<h3>问题1:PWM7 输出引脚未切换到 P0.2</h3>
<p>手册中 <strong>&quot;高级PWM功能脚切换&quot;</strong> 部分明确说明:</p>
<table>
<thead>
<tr>
<th align="center">C7PS</th>
<th align="center">PWM7 输出脚</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">00</td>
<td align="center">P2.2</td>
</tr>
<tr>
<td align="center">01</td>
<td align="center">P3.3</td>
</tr>
<tr>
<td align="center"><strong>10</strong></td>
<td align="center"><strong>P0.2</strong></td>
</tr>
<tr>
<td align="center">11</td>
<td align="center">P7.6</td>
</tr>
</tbody>
</table>
<p><strong>默认值 C7PS = 00,即 PWM7 默认输出在 P2.2,而不是 P0.2!</strong> 你需要将 PWMB_PS 寄存器的 C7PS 设置为 <code>10</code>,才能将 PWM7 映射到 P0.2。</p>
<h3>问题2:P0.2 口未设置为推挽输出</h3>
<p>上电后 I/O 口默认是 <strong>高阻输入模式</strong>(PxM1=1, PxM0=0),PWM 信号无法输出。需要将 P0.2 设置为 **推挽输出**。</p>
<hr />
<h2>修正后的代码示例</h2>
<pre><code class="language-c">/***************功能说明 ***************
AI8H2K32U 使用 PWMB 的 PWM7 通道
从 P0.2 输出 PWM 信号
测试工作频率为 11.0592MHz
******************************************/

#include &quot;ai8h.h&quot;
#include &quot;intrins.h&quot;

// PWMB_PS 寄存器地址(XFR 区域)
#define PWMB_PS   (*(unsigned char volatile xdata *)0xFEFE)

void PWM_config(void)
{
    PWMx_InitDefine PWMx_InitStructure;

    // ===== 步骤1:使能访问 XFR 寄存器 =====
    P_SW2 |= 0x80;

    // ===== 步骤2:将 PWM7 输出切换到 P0.2 =====
    // C7PS = 10,对应 P0.2
    // 注意:PWMB_PS 是 XFR 寄存器,需要先使能 P_SW2.7
    PWMB_PS &amp;= ~0xC0;   // 先清除 C7PS 位(bit7:6)
    PWMB_PS |= 0x80;    // 设置 C7PS = 10,选择 P0.2

    // ===== 步骤3:将 P0.2 设置为推挽输出 =====
    // P0M1.2 = 0, P0M0.2 = 1=&gt; 推挽输出
    P0M1 &amp;= ~0x04;   // P0.2 对应 bit2,清零
    P0M0 |= 0x04;    // P0.2 对应 bit2,置1

    // ===== 步骤4:配置 PWM7 参数 =====
    PWMx_InitStructure.PWM_Mode      = CCMRn_PWM_MODE1;   // PWM模式1
    PWMx_InitStructure.PWM_Duty      = PWMB_Duty.PWM7_Duty; // 占空比
    PWMx_InitStructure.PWM_EnoSelect = ENO7P;            // 输出通道选择
    PWM_Configuration(PWM7, &amp;PWMx_InitStructure);
}
</code></pre>
<h3>关键点总结</h3>
<table>
<thead>
<tr>
<th>配置项</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>PWMB_PS 寄存器</strong></td>
<td>必须设置 <code>C7PS = 10</code>,将 PWM7 切换到 P0.2</td>
</tr>
<tr>
<td><strong>P0M1/P0M0</strong></td>
<td>P0.2 必须设为<strong>推挽输出</strong>(P0M1.2=0, P0M0.2=1)</td>
</tr>
<tr>
<td>**P_SW2</td>
<td>= 0x80**</td>
</tr>
<tr>
<td><strong>ENO7P</strong></td>
<td>使能 PWM7 正相输出通道</td>
</tr>
</tbody>
</table>
<h3>排查清单</h3>
<p>如果按上述配置后仍然没有输出,请检查:</p>
<ol>
<li>✅ <strong>PWMB 的时钟是否已使能?</strong> 需要配置 PWMB 的时钟源和分频。</li>
<li>✅ <strong>PWM 周期和占空比是否合理?</strong> 确认 <code>PWMB_Duty.PWM7_Duty</code> 的值在 0 ~ Period 之间。</li>
<li>✅ <strong>PWM 总使能是否已打开?</strong> 检查 <code>PWMB_ENO</code> 和 <code>PWMB_CR1</code> 寄存器。</li>
<li>✅ <strong>用示波器/逻辑分析仪测量 P0.2 引脚</strong>,不要用万用表(PWM 是快速脉冲信号,万用表测不准)。</li>
</ol>
<p>如果你能贴出完整的 PWM 初始化代码(包括时钟、周期、占空比设置),我可以帮你进一步排查。</p>
<hr />
<p><a href="https://www.stcaimcu.com/plugin.php?id=twpx_xunsearch&amp;mod=forum&amp;q=https%3A%2F%2Fwww.stcaimcu.com%2Fthread-24761-1-1.html&amp;f=_all&amp;m=yes&amp;syn=yes&amp;s=relevance&amp;fid=0">🔍 搜索 &quot;https://www.stcaimcu.com/thread-24761-1-1.html&quot;</a></p>
<p>⏱️ 查找用时 10.4s | 总回答用时 20.8s</p>
页: [1]
查看完整版本: AI8H2K32U P0.2脚PWM7_3无法输出PWM