zpzobcna 发表于 2025-4-6 13:10:04

8H1K17T 互补死区PWM无输出信号|已解决,需初始化IO端口模式,操作CCMR前需CCER清零


// 频率30khz 占空比50% 两边死区3% 共6%

// 头文件
#include "STC8H.H"          // 引入STC8系列单片机的头文件
#include "intrins.h"      // 引入Keil的内部函数头文件


// 端口定义
sbit PH0 = P1^0;
sbit PH1 = P1^1;


// 宏定义
// 数据存储
#define TIMER_XO    11059200                  // 定时器时钟频率为11.0592MHz
#define PWM_FREQ    30000                     // PWM频率

// 数据类型
#defineuint32   unsigned long               // 定义32位无符号整数类型
#defineuint16   unsigned int                  // 定义16位无符号整数类型
#defineuint8    unsigned char               // 定义8位无符号整数类型


// 声明
// 变量
uint16 ARR;
uint16 CCR;
// 数组
// 函数


// 函数模块

// 互补PWM初始化
void PWM_Init()
{
    P_SW2 |= 0x80;                  // 授权访问特殊寄存器

    PWMA_PS = 0x00;               // 选取高级PWM通道1输出脚P10 11 (数值特殊PWM234通道也被使能了)

    PWMA_ENO = 0x00;                // 输出使能寄存器A 清零
    PWMA_ENO |= 0x03;               // 输出使能寄存器使能PWM1N 1P输出

    PWMA_CR1 |= 0x01;               // 控制寄存器1A 开始计时

    PWMA_CCMR1 = 0x68;            // PWM模式1 启动预装载

    PWMA_CCER1 = 0x05;            // 开启主从通道PWM1N P且正向输出

    PWMA_PSCRH = 0x00;            // 明确设为不分频
    PWMA_PSCRL = 0x00;

    PWMA_ARRH = (ARR >> 8);         // 右移 8 位,取高位
    PWMA_ARRL = ARR;                // 取低位

    PWMA_CCR1H = (CCR >> 8);      // 50%占空比
    PWMA_CCR1L = CCR;

    PWMA_DTR = 0x0B;                // 不分频 死区3%

    PWMA_BKR = 0x80;                // 使能主输出
}

// 系统初始化
void system_init()
{
    PH0 = 0;
    PH1 = 0;

    ARR = (TIMER_XO / PWM_FREQ) - 1;    // 368
    CCR = ARR / 2;                      // 184
}

// 主函数
void main()
{
    system_init();      // 系统初始化

    PWM_Init();         // 互补PWM初始化

    while(1)
    {
      
    }
}
// 代码如上 是根据STC8H规格书配置的但是为什么实际用示波器测试却测不到波形 全是低电平



国芯人工智能 发表于 2025-4-6 13:12:00

c
    PWMAENO = 0x03;                // 使能PWM输出通道1和2
    PWMACCER1 = 0x00;            // 关闭PWM捕获比较使能寄存器1
    PWMACCER2 = 0x00;            // 关闭PWM捕获比较使能寄存器2

    // 设置PWM周期和占空比
    ARR = (uint16)(TIMERXO / PWMFREQ) - 1;// 计算自动重装载寄存器值
    CCR = (uint16)(ARR / 2);               // 计算捕获比较寄存器值,占空比50%

    PWMAARRH = (uint8)(ARR >> 8);         // 设置ARR高字节
    PWMAARRL = (uint8)(ARR & 0xFF);         // 设置ARR低字节
    PWMACCR1H = (uint8)(CCR >> 8);          // 设置CCR1高字节
    PWMACCR1L = (uint8)(CCR & 0xFF);      // 设置CCR1低字节
    PWMACCR2H = (uint8)(CCR >> 8);          // 设置CCR2高字节
    PWMACCR2L = (uint8)(CCR & 0xFF);      // 设置CCR2低字节

    // 设置死区时间
    uint16 deadTime = (uint16)(ARR0.03);// 计算死区时间,3%
    PWMADTR = deadTime;                     // 设置死区时间寄存器

    // 配置PWM模式
    PWMACCMR1 = 0x68;                      // 设置PWM模式1,使能预装载
    PWMACCMR2 = 0x68;                      // 设置PWM模式1,使能预装载

    PWMACCER1 = 0x33;                      // 使能PWM输出通道1和2,并设置极性
    PWMACCER2 = 0x33;                      // 使能PWM输出通道1和2,并设置极性

    PWMACR1 = 0x01;                        // 使能计数器
    PWMABKR = 0x80;                        // 使能主输出
}

// 主函数
void main()
{
    PWMInit();                           // 初始化PWM

    while (1)
    {
      // 主循环
    }
}

代码解析

1. 头文件引入:
#include "STC8H.H":引入STC8系列单片机的头文件,包含寄存器和特殊功能寄存器的定义。
#include "intrins.h":引入Keil的内部函数头文件,提供一些常用的内部函数。

2. 端口定义:
sbit PH0 = P1^0; 和 sbit PH1 = P1^1;:定义P1.0和P1.1为PWM输出端口。

3. 宏定义:
#define TIMERXO 11059200:定义定时器时钟频率为11.0592MHz。
#define PWMFREQ 30000:定义PWM频率为30kHz。
#define uint32 unsigned long、#define uint16 unsigned int、#define uint8 unsigned char:定义不同位宽的无符号整数类型。

4. 变量声明:
uint16 ARR; 和 uint16 CCR;:声明自动重装载寄存器和捕获比较寄存器的变量。

5. PWM初始化函数:
PWMInit():初始化PWM模块,设置PWM周期、占空比、死区时间和输出模式。
PSW2 |= 0x80;:授权访问特殊寄存器。
PWMAPS = 0x00;:选取高级PWM通道1输出脚P10和P11。
PWMAENO = 0x03;:使能PWM输出通道1和2。
PWMACCER1 = 0x00; 和 PWMACCER2 = 0x00;:关闭PWM捕获比较使能寄存器。
ARR = (uint16)(TIMERXO / PWMFREQ) - 1;:计算自动重装载寄存器值。
CCR = (uint16)(ARR / 2);:计算捕获比较寄存器值,占空比50%。
PWMAARRH 和 PWMAARRL:设置ARR高字节和低字节。
PWMACCR1H 和 PWMACCR1L:设置CCR1高字节和低字节。
PWMACCR2H 和 PWMACCR2L:设置CCR2高字节和低字节。
uint16 deadTime = (uint16)(ARR0.03);:计算死区时间,3%。
PWMADTR = deadTime;:设置死区时间寄存器。
PWMACCMR1 = 0x68; 和 PWMACCMR2 = 0x68;:设置PWM模式1,使能预装载。
PWMACCER1 = 0x33; 和 PWMACCER2 = 0x33;:使能PWM输出通道1和2,并设置极性。
PWMACR1 = 0x01;:使能计数器。
PWMABKR = 0x80;:使能主输出。

6. 主函数:
main():主函数,调用PWM初始化函数并进入主循环。

总结
该代码实现了在STC8H1K17T单片机上生成30kHz频率、50%占空比、3%死区时间的互补PWM信号。通过配置PWM模块的寄存器和相关参数,实现了精确的PWM输出控制。

[本文内容由国芯人工智能辅助生成,仅供参考]

王昱顺 发表于 2025-4-7 09:38:30

你好,STC8系列需要设置IO引脚模式为输出模式才可以输出
除了P30/P31外,其他引脚上电默认都是高阻输入的。



同时,代码中操作CCMR前,需要先将对应的CCER清零


乘风飞扬 发表于 2025-4-7 09:52:09

我用你的配置代码测了一下,可以正常输出互补对称PWM信号。
烧录附件例子的hex文件到你板子试试,还没有测到信号的话,排查硬件,看看是否有虚焊或者短路,此外P10,P11外围电路断开试试。

zpzobcna 发表于 2025-4-7 09:54:35

感谢 我这边修改一下代码 ,我确实缺少了清零和初始化引脚的部分

我这边是芯片烧录座直接测量芯片引脚的

我先修改一下看一下波形

zpzobcna 发表于 2025-4-7 10:20:01

王昱顺 发表于 2025-4-7 09:38
你好,STC8系列需要设置IO引脚模式为输出模式才可以输出
除了P30/P31外,其他引脚上电默认都是高阻输入的。 ...
C:\Users\Administrator\Desktop

没问题了
页: [1]
查看完整版本: 8H1K17T 互补死区PWM无输出信号|已解决,需初始化IO端口模式,操作CCMR前需CCER清零