找回密码
 立即注册
查看: 97|回复: 5

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

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-04-17 01:59:50
已绑定手机

6

主题

18

回帖

98

积分

注册会员

积分
98
发表于 2025-4-6 13:10:04 | 显示全部楼层 |阅读模式

// 频率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频率

// 数据类型
#define  uint32   unsigned long                 // 定义32位无符号整数类型
#define  uint16   unsigned int                  // 定义16位无符号整数类型
#define  uint8    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规格书配置的  但是为什么实际用示波器测试却测不到波形 全是低电平



回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-4-6 13:12:00 | 显示全部楼层
  1. c
  2.     PWMAENO = 0x03;                // 使能PWM输出通道1和2
  3.     PWMACCER1 = 0x00;              // 关闭PWM捕获比较使能寄存器1
  4.     PWMACCER2 = 0x00;              // 关闭PWM捕获比较使能寄存器2
  5.     // 设置PWM周期和占空比
  6.     ARR = (uint16)(TIMERXO / PWMFREQ) - 1;  // 计算自动重装载寄存器值
  7.     CCR = (uint16)(ARR / 2);                 // 计算捕获比较寄存器值,占空比50%
  8.     PWMAARRH = (uint8)(ARR >> 8);           // 设置ARR高字节
  9.     PWMAARRL = (uint8)(ARR & 0xFF);         // 设置ARR低字节
  10.     PWMACCR1H = (uint8)(CCR >> 8);          // 设置CCR1高字节
  11.     PWMACCR1L = (uint8)(CCR & 0xFF);        // 设置CCR1低字节
  12.     PWMACCR2H = (uint8)(CCR >> 8);          // 设置CCR2高字节
  13.     PWMACCR2L = (uint8)(CCR & 0xFF);        // 设置CCR2低字节
  14.     // 设置死区时间
  15.     uint16 deadTime = (uint16)(ARR  0.03);  // 计算死区时间,3%
  16.     PWMADTR = deadTime;                     // 设置死区时间寄存器
  17.     // 配置PWM模式
  18.     PWMACCMR1 = 0x68;                      // 设置PWM模式1,使能预装载
  19.     PWMACCMR2 = 0x68;                      // 设置PWM模式1,使能预装载
  20.     PWMACCER1 = 0x33;                      // 使能PWM输出通道1和2,并设置极性
  21.     PWMACCER2 = 0x33;                      // 使能PWM输出通道1和2,并设置极性
  22.     PWMACR1 = 0x01;                        // 使能计数器
  23.     PWMABKR = 0x80;                        // 使能主输出
  24. }
  25. // 主函数
  26. void main()
  27. {
  28.     PWMInit();                             // 初始化PWM
  29.     while (1)
  30.     {
  31.         // 主循环
  32.     }
  33. }
复制代码

代码解析

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)(ARR  0.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输出控制。

[本文内容由国芯人工智能辅助生成,仅供参考]
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:458
  • 最近打卡:2025-05-01 07:48:22
已绑定手机
已实名认证

110

主题

2219

回帖

5452

积分

版主

积分
5452
发表于 2025-4-7 09:38:30 | 显示全部楼层
你好,STC8系列需要设置IO引脚模式为输出模式才可以输出
除了P30/P31外,其他引脚上电默认都是高阻输入的。
截图202504070938264613.jpg


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

截图202504070941062749.jpg
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2025-4-7 09:52:09 | 显示全部楼层
我用你的配置代码测了一下,可以正常输出互补对称PWM信号。
烧录附件例子的hex文件到你板子试试,还没有测到信号的话,排查硬件,看看是否有虚焊或者短路,此外P10,P11外围电路断开试试。
截图202504070951308272.jpg

高级PWM1驱动P1程序.zip

14.17 KB, 下载次数: 4

回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-04-17 01:59:50
已绑定手机

6

主题

18

回帖

98

积分

注册会员

积分
98
发表于 2025-4-7 09:54:35 | 显示全部楼层
感谢 我这边修改一下代码 ,我确实缺少了清零和初始化引脚的部分

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

我先修改一下看一下波形
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:10
  • 最近打卡:2025-04-17 01:59:50
已绑定手机

6

主题

18

回帖

98

积分

注册会员

积分
98
发表于 2025-4-7 10:20:01 | 显示全部楼层
王*** 发表于 2025-4-7 09:38
你好,STC8系列需要设置IO引脚模式为输出模式才可以输出
除了P30/P31外,其他引脚上电默认都是高阻输入的。 ...

C:\Users\Administrator\Desktop

没问题了
2a6f925ac9e07e7132267b08208bf6f.png
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 02:41 , Processed in 0.152997 second(s), 89 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表