请教一下这个PWM呼吸灯的程序哪里有问题
unsigned char pwm_count = 0; // PWM 计数器unsigned int pwm_duty = 0; // PWM 占空比,取值范围扩大到 0~200
unsigned char pwm_direction = 1; // PWM 增减方向,1 表示增加,0 表示减少
unsigned int brightness_delay = 0; // 控制亮度变化的延时计数器
void Timer1_Isr(void) interrupt 3 // 50us 中断
{
if (++pwm_count >= 200) pwm_count = 0; // 使 PWM 周期为 200,即 50us * 200 = 10ms 的周期
// PWM 控制:根据 pwm_duty 调整 LED 的亮暗
if (pwm_count < pwm_duty) P25 = 0;
else P25 = 1;
// 控制亮度变化频率,每隔10ms调整一次占空比
if (++brightness_delay >= 10) {// 每10次中断(即10ms)调整一次亮度
brightness_delay = 0;
// 每次调节占空比,以实现1秒从暗到亮的变化
if (pwm_direction) {
pwm_duty++; // 增加亮度
if (pwm_duty >= 200) pwm_direction = 0;// 达到最高亮度后,开始变暗
} else {
pwm_duty--; // 减少亮度
if (pwm_duty == 0) pwm_direction = 1; // 达到最低亮度后,开始变亮
}
}
}
大概看了一眼,没看出什么问题,现在运行有问题吗? 晓飛飛 发表于 2024-10-30 19:37
大概看了一眼,没看出什么问题,现在运行有问题吗?
根本看不出来灯的亮度变化 Crystalline 发表于 2024-10-30 20:10
根本看不出来灯的亮度变化
#include "stc8h.h"
unsigned char pwm_count = 0; // PWM 计数器
unsigned int pwm_duty = 0; // PWM 占空比,取值范围扩大到 0~200
unsigned char pwm_direction = 1; // PWM 增减方向,1 表示增加,0 表示减少
unsigned int brightness_delay = 0; // 控制亮度变化的延时计数器
void Timer1_Isr(void) interrupt 3
{
if (++pwm_count >= 200) pwm_count = 0; // 使 PWM 周期为 200,即 50us * 200 = 10ms 的周期
// PWM 控制:根据 pwm_duty 调整 LED 的亮暗
if (pwm_count < pwm_duty) P27 = 0;
else P27 = 1;
// 控制亮度变化频率,每隔10ms调整一次占空比
if (++brightness_delay >= 10) {// 每10次中断(即10ms)调整一次亮度
brightness_delay = 0;
// 每次调节占空比,以实现1秒从暗到亮的变化
if (pwm_direction) {
pwm_duty++; // 增加亮度
if (pwm_duty >= 200) pwm_direction = 0;// 达到最高亮度后,开始变暗
} else {
pwm_duty--; // 减少亮度
if (pwm_duty == 0) pwm_direction = 1; // 达到最低亮度后,开始变亮
}
}
}
void Timer1_Init(void) //50微秒@11.0592MHz
{
AUXR |= 0x40; //定时器时钟1T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0xD7; //设置定时初始值
TH1 = 0xFD; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
}
void main()
{
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
Timer1_Init();
EA = 1;
while (1);
}
280
晓飛飛 发表于 2024-10-30 20:19
280
{:5_341:} 晓飛飛 发表于 2024-10-30 20:19
280
总中断忘开了 PWM还是硬件的简单好用靠谱啊,赶紧试试吧。
/*
本例程基于STC8H8K64U-QFN32核心板编写
使用PWM4_2对应的P2.6和P2.7驱动板载LED指示灯
*/
#include "stc8h.h"
#define MAIN_Fosc 24000000L
void delay_ms (unsigned int ms)
{
unsigned int i;
if(ms > 0)
{ do
{
i = MAIN_Fosc / 10000;
while (--i);//10T per loop
}
while (--ms);
}
}
void PWM_init(void)
{
PWMA_CCER2 = 0x00; //写CCMRx前必须先清零CCERx关闭通道
PWMA_CCMR4 = 0x60; //设置CC1为PWMA输出模式
PWMA_PS = 0x40;
//PWMA_CCER1 = 0x01; //使能CC1通道正极
//PWMA_CCER1 = 0x05; //使能CC1通道双极
PWMA_CCER2 = 0x50; //使能CC4通道双极
//PWMA_CCR1 = (MAIN_Fosc / fq / 2) - 1; //设置占空比时间1~65535
PWMA_CCR4 = 2000;
PWMA_ARR = 12000; //设置周期时间 1~65535
//PWMA_ENO = 0x01; //使能PWM1P端口输出
//PWMA_ENO = 0x03; //使能PWM1P+N端口输出
PWMA_ENO = 0xC0; //使能PWM4P+N端口输出
PWMA_PSCR = 0; //PWM时钟预分频寄存器 0~65535
PWMA_BKR = 0x80; //使能主输出
PWMA_CR1 = 0x01; //开始计时
}
void PWM_updata(unsigned char duty)
{
if(duty > 0) //
{
PWMA_CCR4 = duty * 120;
PWMA_BKR = 0x80; //使能主输出
PWMA_CR1 = 0x01; //开始计时
}
else
{
PWMA_BKR = 0x00; //关主输出
PWMA_CR1 = 0x00; //停止计时
}
}
void main()
{
unsigned char i;
EAXSFR(); //
P0M0 = 0x00; P0M1 = 0x00;
P1M0 = 0x00; P1M1 = 0x00;
P2M0 = 0x00; P2M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
P4M0 = 0x00; P4M1 = 0x00;
P5M0 = 0x00; P5M1 = 0x00;
P6M0 = 0x00; P6M1 = 0x00;
P7M0 = 0x00; P7M1 = 0x00;
PWM_init();
while(1)
{
for(i = 1;i<99;i++)
{
PWM_updata(i);
delay_ms(5);
}
for(i = 1;i<99;i++)
{
PWM_updata(100-i);
delay_ms(5);
}
}
}
281
晓飛飛 发表于 2024-10-30 20:28
PWM还是硬件的简单好用靠谱啊,赶紧试试吧。
281
好的好的 晓飛飛 发表于 2024-10-30 20:28
PWM还是硬件的简单好用靠谱啊,赶紧试试吧。
281
我只用过stm32的PWM输出{:5_314:} 本帖最后由 zwf33335 于 2024-11-5 18:02 编辑
哪位大佬有PWM4P(P2.6)输出的PWM调速程序,我是新手做不出来,先谢谢各位大佬STC8H1K28单片机,
页:
[1]
2