目前AI对问题的理解能力还是差了点,我按你的要求手搓了一点代码,可以实现5档PWM调节,实测可以的,你参考 ...
我靠,,真大神....
我看视频就是这个,.
我稍稍修改一下.{:4_250:}{:4_196:} 晓飛飛 发表于 2024-6-30 22:47
目前AI对问题的理解能力还是差了点,我按你的要求手搓了一点代码,可以实现5档PWM调节,实测可以的,你参考 ...
根据您的代码我改好了,花了2天时间{:4_167:}
超级好用,但是现在有个问题.
就是我不能定义自己的数值,因为手电亮度比较大.
占空比数据不知道从哪里改了.
这是我改的代码,把Time4改成Time0了
然后把PWM引脚等数据稍微改了一下.
#include "stc8h.h"
#include "intrins.h"
#define MAIN_Fosc 11059200L
#define NUM_PWM_LEVELS 5 // 自定义占空比等级的数量
unsigned char 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);
}
}
}
}
}
本帖最后由 晓飛飛 于 2024-7-2 11:12 编辑
vb2002 发表于 2024-7-2 09:09
根据您的代码我改好了,花了2天时间
超级好用,但是现在有个问题.
就是我不能定义自己的数值,因为手电亮度 ...
PWM的占空比 duty = PWMA_CCR4 /PWMA_ARR,我代码中,PWM_updata函数中的duty取值范围是0~100,你可以修改duty的变量类型为unsigned int,赋值给PWMA_CCR4不必再乘120,
然后通过PWM_updata(pwm_levels)调用PWM更新
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,你可以修 ...
好的,收到.大佬威武!!{:4_196:} 晓飛飛 发表于 2024-7-2 11:02
PWM的占空比 duty = PWMA_CCR4 /PWMA_ARR,我代码中,PWM_updata函数中的duty取值范围是0~100,你可以修 ...
搞定了.超级好用.真心感谢飞哥{:4_242:}
现在的逻辑是 我想设置什么档位就设置什么档位
并且还有保存当前档位亮度的用途.
vb2002 发表于 2024-7-2 19:03
搞定了.超级好用.真心感谢飞哥
现在的逻辑是 我想设置什么档位就设置什么档位
并且还有保存当前档位亮度 ...
看数据手册吧,这个涉及操作EEPROM,会操作就会保存了,学习单片机不能急,所有外设会用才学了个基础, 晓飛飛 发表于 2024-7-2 11:02
PWM的占空比 duty = PWMA_CCR4 /PWMA_ARR,我代码中,PWM_updata函数中的duty取值范围是0~100,你可以修 ...
飞哥,这个是机械开关的换挡,并且可以均衡磨损eeprom
但是在switch那里有点乱.
我加了个定时器,(想弄成开机后成3秒内关了再开,换挡,.... 开机3秒后,,关机再开,就回到关机之前的档位).
可以帮帮我吗?
板子还挺好看的 angalp 发表于 2024-11-1 09:11
板子还挺好看的
哪个板子?
页:
1
[2]