AI8H PWM输出的问题 求助!
AI8H8K64U-TSSOP20使用PWM的方式P1.6端口点亮LED,没有驱动点亮,用IO低电平输出的方式能点亮请看完整代码
#define MAIN_Fosc 24000000L // 主时钟:24MHz(文档6.1.3章节,内部IRC)
#include "STC8H.h"
// -------------------------- 文档对应参数定义 --------------------------
// PWM频率1KHz(人眼无闪烁),公式:频率=MAIN_Fosc/[(PSCR+1)*(ARR+1)](文档22.5.7章节)
#define PWMA_PSCR_VAL 0x0000 // 预分频=0(不分频,PWM时钟=24MHz)
#define PWMA_ARR_VAL (MAIN_Fosc/(PWMA_PSCR_VAL+1)/1000 - 1) // ARR=23999(周期1ms)
#define BREATH_STEP 20 // 占空比渐变步长(平滑呼吸)
#define BREATH_DELAY 10 // 渐变间隔(ms,控制呼吸速度)
// -------------------------- 全局变量 --------------------------
unsigned int g_ccr4_val = 0; // PWMA_CCR4值(0~23999,对应低电平占空比0%~100%)
bit g_duty_inc = 1; // 占空比递增/递减标志(1=递增:LED变亮)
// -------------------------- 函数声明 --------------------------
void PWMA_Init(void); // 初始化PWMA_CCR4(P1.6 PWM输出)
void Delay_ms(unsigned int ms); // 毫秒延时(文档6.1.3章节时钟校准)
void Breath_Loop(void); // 呼吸灯占空比渐变逻辑
// -------------------------- 主函数 --------------------------
void main(void)
{
PWMA_Init(); // 初始化PWMA_CCR4(P1.6),启动PWM输出
while(1)
{
Breath_Loop(); // 循环执行呼吸逻辑
}
}
// -------------------------- PWMA初始化(P1.6=PWMA_CCR4,文档22.7章节) --------------------------
void PWMA_Init(void)
{
// 1. 使能扩展SFR访问(文档8.2.8章节:必须先使能才能访问PWMA寄存器)
P_SW2 |= 0x80;
// 2. 配置PWM时钟与周期(文档22.7.20/22.7.22章节)
PWMA_PSCR = PWMA_PSCR_VAL; // 预分频=0
PWMA_ARR = PWMA_ARR_VAL; // 自动重装载值=23999(1KHz周期)
// 3. 配置PWMA_CCR4为PWM模式1(低电平占空比随CCR4增大而增加,文档22.7.13章节)
// CCMR2控制CCR4通道,高8位=0x60(PWM模式1),低8位无意义
PWMA_CCMR2 = 0x6000;
// 4. 配置P1.6为PWM4P输出(默认映射,文档2.5.4章节)
// PWMA_IOAUX=0x00:CCR4默认映射P1.6,无需额外切换
PWMA_IOAUX = 0x00;
// 5. 使能CCR4输出+设置极性(文档22.7.16章节)
// CC4E=1(使能输出),CC4P=0(低电平有效,符合LED低电平点亮)
PWMA_CCER1 = 0x0080;
// 6. 使能P1.6 PWM输出(文档22.7.2章节:输出允许寄存器)
// ENO4P=1(使能PWM4P输出,对应P1.6)
PWMA_ENO = 0x04;
// 7. 初始占空比(0%低电平→LED灭,文档22.7.27章节)
PWMA_CCR4 = g_ccr4_val;
// 8. 主输出使能+启动PWMA计数器(文档22.7.33/22.7.4章节)
PWMA_BKR = 0x80; // MOE=1(主输出使能,PWMA所有通道输出总开关)
PWMA_CR1 = 0x81; // CEN=1(启动计数器),ARPE=1(允许ARR缓冲)
// 9. 关闭扩展SFR访问(文档8.2.8章节:配置完成后恢复)
P_SW2 &= ~0x80;
}
// -------------------------- 毫秒延时函数(基于24MHz时钟,文档6.1.3章节精度) --------------------------
void Delay_ms(unsigned int ms)
{
unsigned int i, j;
for(i = ms; i > 0; i--)
{
// 24MHz时钟下,j=2400≈1ms(文档6.1.3章节:1机器周期=1/24MHz≈41.67ns)
for(j = 2400; j > 0; j--);
}
}
// -------------------------- 呼吸灯逻辑(低电平占空比渐变,文档22.5.7章节) --------------------------
void Breath_Loop(void)
{
// 使能扩展SFR访问(修改CCR4需重新使能)
P_SW2 |= 0x80;
// 占空比渐变:0%→100%(亮)→0%(灭)循环
if(g_duty_inc)
{
g_ccr4_val += BREATH_STEP;
if(g_ccr4_val >= PWMA_ARR_VAL) // 达到最大占空比(100%低电平→LED最亮)
{
g_ccr4_val = PWMA_ARR_VAL;
g_duty_inc = 0; // 切换为递减
}
}
else
{
g_ccr4_val -= BREATH_STEP;
if(g_ccr4_val <= 0) // 达到最小占空比(0%低电平→LED灭)
{
g_ccr4_val = 0;
g_duty_inc = 1; // 切换为递增
}
}
// 更新CCR4值,改变PWM占空比(文档22.7.27章节)
PWMA_CCR4 = g_ccr4_val;
// 恢复扩展SFR访问状态
P_SW2 &= ~0x80;
// 延时平滑渐变(控制呼吸速度)
Delay_ms(BREATH_DELAY);
}
您好,关于您在使用 STC8H8K64U-TSSOP20 芯片进行 PWM 输出控制 LED 的问题,您提到使用 IO口低电平输出 可以点亮LED,但通过 PWM方式控制P16端口 无法点亮,下面我将从硬件配置、寄存器设置、引脚复用功能、PWM模式选择等多个角度为您分析可能的原因,并提供相应的修改建议。
一、问题简述
目标:使用STC8H8K64U的P16引脚输出PWM波控制LED亮度(呼吸灯效果)。
现象:
使用普通IO口低电平输出,LED可以点亮。
使用PWM输出,LED不亮。
代码片段:您提供了PWM初始化部分的代码,但未提供完整的PWM中断处理、占空比更新和主循环逻辑。
二、初步分析
1. 引脚功能复用配置是否正确?
在STC8H系列中,P16默认是ADC6输入通道,不是PWM输出通道。必须通过 端口复用寄存器 P1M1/P1M0 设置其为 第二功能(即PWM输出)。
示例配置:
c
P1M1 = 0x00; // 设置P1口为推挽输出
P1M0 = 0xFF;
// 设置P16为PWM输出(第二功能)
P1M1 &= ~0x40; // P1M1.6 = 0
P1M0 |=0x40; // P1M0.6 = 1 → 第二功能(PWM)
若未配置P16为PWM功能,该引脚将始终作为普通IO或ADC使用,导致PWM输出无效。
2. PWM模块初始化是否正确?
您提供的代码片段中定义了PWM的ARR和PSCR参数,但未提供完整的PWM初始化函数。以下是标准的 PWMA初始化流程:
示例代码:
c
void PWMAInit(void)
{
PWMAPSCR = PWMAPSCRVAL; // 设置预分频值
PWMAARR= PWMAARRVAL; // 设置自动重载寄存器(周期)
PWMACCR4 = 0; // 初始占空比为0
PWMACR1= 0x80; // 启动PWM时钟
PWMACR2= 0x00; // 边沿对齐模式
PWMABKR= 0x80; // 主输出使能
PWMAOER= 0x10; // 使能PWMA通道4输出
PWMACR1 |= 0x01; // 启动PWM
}
注意:PWMA通道4对应的引脚为P16,需确保PWMAOER寄存器位设置正确。
3. PWM输出极性是否正确?
PWM输出的极性决定了输出是高电平有效还是低电平有效。如果LED是阳极接VCC、阴极接地的方式,PWM输出应为低电平有效。
设置低电平有效的寄存器如下:
c
PWMACMR4 = 0x60; // PWM模式1,低电平有效
如果设置为高电平有效,LED可能无法正确点亮。
4. PWM中断或主循环是否更新了占空比?
在呼吸灯实现中,需要在主循环或定时器中断中动态修改PWMACCR4的值:
示例:
```c
void main(void)
{
PWMAInit();
while (1)
{
if (gdutyinc)
{
gccr4val += BREATHSTEP;
if (gccr4val >= PWMAARRVAL)
{
gdutyinc = 0;
}
}
else
{
gccr4val -= BREATHSTEP;
if (gccr4val = PWMAARRVAL)
{
gdutyinc = 0;
}
}
else
{
gccr4val -= BREATHSTEP;
if (gccr4val
[本文内容由国芯人工智能辅助生成,仅供参考] 基本就是没有初始化管脚的IO模式,
默认上电高阻抗.所以无法输出PWM波形
可参考8H实验箱例程包里面的PWM例子:23-高级PWM1-PWM2-PWM3-PWM4,驱动P6口呼吸灯实验程序
只要修改例子里面的PWM选择通道即可。
例程包下载地址:https://www.stcai.com/syx
页:
[1]