130
1521
1865
金牌会员
晓*** 发表于 2024-6-30 22:47 目前AI对问题的理解能力还是差了点,我按你的要求手搓了一点代码,可以实现5档PWM调节,实测可以的,你参考 ...
使用道具 举报 送花
#include "stc8h.h" #include "intrins.h" #define MAIN_Fosc 11059200L #define NUM_PWM_LEVELS 5 // 自定义占空比等级的数量 unsigned char pwm_levels[NUM_PWM_LEVELS] = {5, 200, 500, 5000, 12000}; // 占空比等级列表,可以根据需要调整 unsigned char PWM_SAVE; sbit key = P3^2; bit key_flag; unsigned char PWM_MODE; unsigned char time_out; void PWM_init(void) { PWMA_CCER2 = 0x00; //写CCMRx前必须先清零CCERx关闭通道 PWMA_CCMR4 = 0x60; //设置CC1为PWMA输出模式 PWMA_PS = 0xc0; PWMA_CCER2 = 0x50; //使能CC4通道双极 PWMA_CCR4 = 0; PWMA_ARR = 12000; //设置周期时间 1~65535 PWMA_ENO = 0xC0; //使能PWM4P+N端口输出 PWMA_PSCR = 0; //PWM时钟预分频寄存器 0~65535 PWMA_BKR = 0x80; //使能主输出 PWMA_CR1 = 0x01; //开始计时 } void PWM_updata(unsigned char duty) //duty取值0~100,duty = 0时,关闭输出,PWM端口释放为普通IO { if(duty > 0) // { PWMA_CCR4 = duty * 120; PWMA_ENO = 0xC0; PWMA_BKR = 0x80; //使能主输出 PWMA_CR1 = 0x01; //开始计时 } else { PWMA_BKR = 0x00; //关主输出 PWMA_CR1 = 0x00; //停止计时 PWMA_ENO &= ~0xC0; //关闭PWM端口 P33 = 1;P34 = 1; } } void Timer0_Isr(void) interrupt 1 { static unsigned char key_sta; switch(key_sta) //按键检测状态机 { case 0: if (key == 0) key_sta++; //如果有按键 跳下一个模式 break; case 1: if (key == 0) key_sta++; //如果持续按键 跳下一个模式 else key_sta = 0; break; case 2: if (key == 1) key_sta++; //如果按键释放 跳下一个模式 break; case 3: key_flag = 1; key_sta = 0; break; default: key_sta = 0; break; } if (time_out < 20) time_out++; //50ms x 60 = 3000ms = 3秒,这里是超时计数器 } void Timer0_Init(void) //50毫秒@11.0592MHz { AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x00; //设置定时初始值 TH0 = 0x4C; //设置定时初始值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 IE = 0x02; //定时器0开启中断 } void main() { int current_level = 0; // 当前选中的占空比等级 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(); Timer0_Init(); EA = 1; while(1) { if(key_flag) //如果有按键事件 { key_flag = 0; //清按键标记 if (time_out < 20) //按键还没超时 { PWM_MODE++; if(PWM_MODE > 5) PWM_MODE = 1; PWM_updata(PWM_MODE*20); time_out = 0; } else //按键超时了 { if(PWM_MODE) //有输出状态时关闭输出 { PWM_SAVE = PWM_MODE; //保存当前状态 //可以移植代码保存到EEPROM PWM_MODE = 0; PWM_updata(0); } else //关闭状态时恢复之前的PWM { if(PWM_SAVE == 0) PWM_SAVE = 1; //首次按键启动最低亮度 PWM_MODE = PWM_SAVE; //恢复之前的PWM //可以移植代码从EEPROM读取 time_out = 0; PWM_updata(PWM_MODE*20); } } } } } 复制代码
34
2096
2206
荣誉版主
vb2*** 发表于 2024-7-2 09:09 根据您的代码我改好了,花了2天时间 超级好用,但是现在有个问题. 就是我不能定义自己的数值,因为手电亮度 ...
void PWM_updata(unsigned int duty) //duty取值0~100,duty = 0时,关闭输出,PWM端口释放为普通IO { if(duty > 0) // { PWMA_CCR4 = duty; PWMA_ENO = 0xC0; PWMA_BKR = 0x80; //使能主输出 PWMA_CR1 = 0x01; //开始计时 } else { PWMA_BKR = 0x00; //关主输出 PWMA_CR1 = 0x00; //停止计时 PWMA_ENO &= ~0xC0; //关闭PWM端口 P33 = 1;P34 = 1; } } 复制代码
晓*** 发表于 2024-7-2 11:02 PWM的占空比 duty = PWMA_CCR4 / PWMA_ARR,我代码中,PWM_updata函数中的duty取值范围是0~100,你可以修 ...
12
125
1685
vb2*** 发表于 2024-7-2 19:03 搞定了.超级好用.真心感谢飞哥 现在的逻辑是 我想设置什么档位就设置什么档位 并且还有保存当前档位亮度 ...
24
345
1637
angalp 发表于 2024-11-1 09:11 板子还挺好看的
本版积分规则 发表回复 回帖后跳转到最后一页
|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )
GMT+8, 2025-5-3 15:16 , Processed in 0.147795 second(s), 106 queries .
Powered by Discuz! X3.5
© 2001-2025 Discuz! Team.