vb2002 发表于 2024-6-30 23:43:42

晓飛飛 发表于 2024-6-30 22:47
目前AI对问题的理解能力还是差了点,我按你的要求手搓了一点代码,可以实现5档PWM调节,实测可以的,你参考 ...

我靠,,真大神....
我看视频就是这个,.
我稍稍修改一下.{:4_250:}{:4_196:}

vb2002 发表于 2024-7-2 09:09:29

晓飛飛 发表于 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:02:58

本帖最后由 晓飛飛 于 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;
    }
}



vb2002 发表于 2024-7-2 15:36:00

晓飛飛 发表于 2024-7-2 11:02
PWM的占空比 duty = PWMA_CCR4 /PWMA_ARR,我代码中,PWM_updata函数中的duty取值范围是0~100,你可以修 ...

好的,收到.大佬威武!!{:4_196:}

vb2002 发表于 2024-7-2 19:03:50

晓飛飛 发表于 2024-7-2 11:02
PWM的占空比 duty = PWMA_CCR4 /PWMA_ARR,我代码中,PWM_updata函数中的duty取值范围是0~100,你可以修 ...

搞定了.超级好用.真心感谢飞哥{:4_242:}
现在的逻辑是 我想设置什么档位就设置什么档位
并且还有保存当前档位亮度的用途.

lzzasd 发表于 2024-7-2 22:33:46

vb2002 发表于 2024-7-2 19:03
搞定了.超级好用.真心感谢飞哥
现在的逻辑是 我想设置什么档位就设置什么档位
并且还有保存当前档位亮度 ...

看数据手册吧,这个涉及操作EEPROM,会操作就会保存了,学习单片机不能急,所有外设会用才学了个基础,

vb2002 发表于 2024-8-4 12:33:45

晓飛飛 发表于 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:49

板子还挺好看的

vb2002 发表于 2024-11-1 09:18:52

angalp 发表于 2024-11-1 09:11
板子还挺好看的

哪个板子?
页: 1 [2]
查看完整版本: 实在是没办法了,弄了一晚上了还是弄不好 AI 帮人写的代码