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规格书配置的但是为什么实际用示波器测试却测不到波形 全是低电平
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输出控制。
[本文内容由国芯人工智能辅助生成,仅供参考] 你好,STC8系列需要设置IO引脚模式为输出模式才可以输出
除了P30/P31外,其他引脚上电默认都是高阻输入的。
同时,代码中操作CCMR前,需要先将对应的CCER清零
我用你的配置代码测了一下,可以正常输出互补对称PWM信号。
烧录附件例子的hex文件到你板子试试,还没有测到信号的话,排查硬件,看看是否有虚焊或者短路,此外P10,P11外围电路断开试试。
感谢 我这边修改一下代码 ,我确实缺少了清零和初始化引脚的部分
我这边是芯片烧录座直接测量芯片引脚的
我先修改一下看一下波形
王昱顺 发表于 2025-4-7 09:38
你好,STC8系列需要设置IO引脚模式为输出模式才可以输出
除了P30/P31外,其他引脚上电默认都是高阻输入的。 ...
C:\Users\Administrator\Desktop
没问题了
页:
[1]