找回密码
 立即注册
查看: 35|回复: 0

LED调光-STC8H1K08A-驱动12V灯板

[复制链接]
  • 打卡等级:以坛为家III
  • 打卡总天数:788
  • 最近打卡:2026-03-07 08:59:31

17

主题

163

回帖

512

积分

高级会员

积分
512
发表于 4 天前 | 显示全部楼层 |阅读模式
灯板灯珠是3V,4串3并,电源24V2A(很亮)。电路是JLC开源的,附件附带原作者的固件(无源码),可以直接使用。后又根据电路写了一个四档高光的代码并带有档位断电记忆功能,无温度开启风扇功能,有需要的可以自行修改代码加上。

SCH_Schematic1_2025-10-17_1.jpg


实物照片.png

  1. //stc8g1k08a   EEPROM 空间为 4K(0000h~0FFFh)
  2. #include "reg51.h"
  3. #include "intrins.h"
  4. sfr     CCON    =   0xd8;
  5. sbit    CF      =   CCON^7;
  6. sbit    CR      =   CCON^6;
  7. sbit    CCF2    =   CCON^2;
  8. sbit    CCF1    =   CCON^1;
  9. sbit    CCF0    =   CCON^0;
  10. sfr     CMOD    =   0xd9;
  11. sfr     CL      =   0xe9;
  12. sfr     CH      =   0xf9;
  13. sfr     CCAPM0  =   0xda;
  14. sfr     CCAP0L  =   0xea;
  15. sfr     CCAP0H  =   0xfa;
  16. sfr     PCA_PWM0 =  0xf2;
  17. sfr     CCAPM1  =   0xdb;
  18. sfr     CCAP1L  =   0xeb;
  19. sfr     CCAP1H  =   0xfb;
  20. sfr     PCA_PWM1 =  0xf3;
  21. sfr     CCAPM2  =   0xdc;
  22. sfr     CCAP2L  =   0xec;
  23. sfr     CCAP2H  =   0xfc;
  24. sfr     PCA_PWM2 =  0xf4;
  25. sfr         P5          =           0xC8;
  26. sfr     P0M1    =   0x93;
  27. sfr     P0M0    =   0x94;
  28. sfr     P1M1    =   0x91;
  29. sfr     P1M0    =   0x92;
  30. sfr     P2M1    =   0x95;
  31. sfr     P2M0    =   0x96;
  32. sfr     P3M1    =   0xb1;
  33. sfr     P3M0    =   0xb2;
  34. sfr     P4M1    =   0xb3;
  35. sfr     P4M0    =   0xb4;
  36. sfr     P5M1    =   0xc9;
  37. sfr     P5M0    =   0xca;
  38. sfr     IAP_DATA    =   0xC2;
  39. sfr     IAP_ADDRH   =   0xC3;
  40. sfr     IAP_ADDRL   =   0xC4;
  41. sfr     IAP_CMD     =   0xC5;
  42. sfr     IAP_TRIG    =   0xC6;
  43. sfr     IAP_CONTR   =   0xC7;
  44. sfr     IAP_TPS     =   0xF5;
  45. //ADC sfr
  46. sfr     ADC_CONTR   =   0xbc;
  47. sfr     ADC_RES     =   0xbd;
  48. sfr     ADC_RESL    =   0xbe;
  49. sfr     ADCCFG      =   0xde;
  50. sfr     P_SW2   =   0xba;
  51. #define ADCTIM  (*(unsigned char volatile xdata *)0xfea8)
  52. #define ADC_POWER 0x80
  53. #define ADC_START 0x40
  54. char IapRead(int addr);//EEPROM读
  55. void IapProgram(int addr, char dat);////EEPROM写
  56. void IapErase(int addr);//EEPROM扇区擦除
  57. #define uchar unsigned char
  58. #define uint unsigned int
  59. //定义按键引脚
  60. sbit KEY_INC = P3^0;    //增加占空比按键
  61. sbit KEY_DEC = P3^1;    //减小占空比按键
  62. sbit PWM_IO =P5^4;
  63. //定义PWM占空比档位(6个档位)
  64. uchar pwm_level = 0;    //初始档位为0(0%占空比)
  65. //占空比配置数组(8位PWM)
  66. uint pwm_duty[6] = {
  67.     0xff,   // 0% 占空比 (8位PWM最大值)
  68.     0xe9,   // 10% 占空比
  69.     0xe0,   // 20% 占空比
  70.     0xd0,   // 30% 占空比
  71.    
  72.     0x80    // 50% 占空比
  73. };
  74. //延时函数
  75. void delay_ms(uint ms)
  76. {
  77.     unsigned char data i, j;
  78.         unsigned int abcd;
  79.     for (abcd = ms; abcd > 0; abcd--)
  80.         {
  81.                 _nop_();
  82.                 _nop_();
  83.                 _nop_();
  84.                 i = 11;
  85.                 j = 190;
  86.                 do
  87.                 {
  88.                         while (--j);
  89.                 } while (--i);
  90.         }
  91. }
  92. //按键扫描函数
  93. void key_scan()
  94. {
  95.     //检测增加按键
  96.     if (KEY_INC == 0)
  97.     {
  98.         delay_ms(50);  //去抖动
  99.         if (KEY_INC == 0)
  100.         {
  101.             //单按操作:增加一个档位
  102.             if (pwm_level < 4)  //最大档位为4
  103.             {
  104.                 pwm_level++;
  105.                 //更新PWM占空比
  106.                 CCAP2L = pwm_duty[pwm_level] & 0xff;
  107.                 CCAP2H = pwm_duty[pwm_level] & 0xff;
  108.             }
  109.             
  110.             //检测是否为长按
  111.             delay_ms(1000);  //长按检测时间
  112.             while (KEY_INC == 0)  //如果按键仍然按下,进入长按模式
  113.             {
  114.                 if (pwm_level < 4)  //最大档位为4
  115.                 {
  116.                     pwm_level++;
  117.                     //更新PWM占空比
  118.                     CCAP2L = pwm_duty[pwm_level] & 0xff;
  119.                     CCAP2H = pwm_duty[pwm_level] & 0xff;
  120.                     delay_ms(500);  //调节间隔500ms
  121.                 }
  122.                 else
  123.                 {
  124.                     //已达到最大档位,停止增加
  125.                     delay_ms(500);  //保持间隔时间
  126.                 }
  127.             }
  128.             
  129.             //松开按键后保存当前占空比
  130.             IapErase(0x0000);  //先擦除扇区
  131.             IapProgram(0x0000, pwm_level);
  132.         }
  133.     }
  134.    
  135.     //检测减小按键
  136.     if (KEY_DEC == 0)
  137.     {
  138.         delay_ms(50);  //去抖动
  139.         if (KEY_DEC == 0)
  140.         {
  141.             //单按操作:减小一个档位
  142.             if (pwm_level > 0)  //最小档位为1(10%,不能为0)
  143.             {
  144.                 pwm_level--;
  145.                 //更新PWM占空比
  146.                 CCAP2L = pwm_duty[pwm_level] & 0xff;
  147.                 CCAP2H = pwm_duty[pwm_level] & 0xff;
  148.             }
  149.             
  150.             //检测是否为长按
  151.             delay_ms(1000);  //长按检测时间
  152.             while (KEY_DEC == 0)  //如果按键仍然按下,进入长按模式
  153.             {
  154.                 if (pwm_level > 1)  //最小档位为1(10%,不能为0)
  155.                 {
  156.                     pwm_level--;
  157.                     //更新PWM占空比
  158.                     CCAP2L = pwm_duty[pwm_level] & 0xff;
  159.                     CCAP2H = pwm_duty[pwm_level] & 0xff;
  160.                     delay_ms(500);  //调节间隔500ms
  161.                 }
  162.                 else
  163.                 {
  164.                     //已达到最小档位,停止减小
  165.                     delay_ms(500);  //保持间隔时间
  166.                 }
  167.             }
  168.             
  169.             //松开按键后保存当前占空比
  170.             IapErase(0x0000);  //先擦除扇区
  171.             IapProgram(0x0000, pwm_level);
  172.         }
  173.     }
  174. }
  175. //unsigned int  ADCSCAN(void)
  176. //{
  177. //              ADC_CONTR |= 0x43;                      //启动AD转换 P3.3
  178. //        _nop_();
  179. //        _nop_();
  180. //        while (!(ADC_CONTR & 0x20));            //查询ADC完成标志
  181. //        ADC_CONTR &= ~0x20;                     //清完成标志
  182. //        ADC_RES;                           //读取ADC结果
  183. //}
  184. unsigned int  GetADCResult(BYTE ch)
  185. {           
  186.     unsigned int AdcTmp;
  187. unsigned char         ADC_RES,ADC_RESL;
  188.           AdcTmp=0;
  189.         ADC_RES=0;
  190.         ADC_RESL=0;
  191.     ADC_CONTR = ADC_POWER| ch | ADC_START;
  192.          Delay(500);  
  193.           while(~(ADC_CONTR|0xdf));//等待ADC转换完成
  194. //                UartSend(ADC_RES);
  195. //                UartSend(ADC_RESL);
  196.     ADC_CONTR &= 0xdf;         //清完成标志
  197. //        AdcTmp=(ADC_RES)<<2;
  198. //        AdcTmp|=ADC_RESL;
  199.         AdcTmp = ((u16)ADC_RES << 2) + (ADC_RESL & 0x03);
  200.     return AdcTmp;                 //返回ADC结果
  201.         
  202. }
  203. void main()
  204. {
  205.     PWM_IO = 0;
  206.         //配置端口模式
  207.     P0M0 = 0x00;
  208.     P0M1 = 0x00;
  209.     P1M0 = 0x00;
  210.     P1M1 = 0x00;
  211.     P2M0 = 0x00;
  212.     P2M1 = 0x00;
  213.     P3M0 = 0x00;
  214.     P3M1 = 0x08;//p33 高阻 ADC输入
  215.     P4M0 = 0x00;
  216.     P4M1 = 0x00;
  217. //    P5M0 = 0x00;
  218. //    P5M1 = 0x00;
  219.    
  220.     //配置P54引脚为推挽输出
  221.     P5M1 &= ~(1 << 4);
  222.     P5M0 |= (1 << 4);
  223.     //从EEPROM读取占空比档位
  224.     pwm_level = IapRead(0x0000);
  225.     //检查读取值是否在有效范围内
  226.     if (pwm_level > 5)
  227.     {
  228.         pwm_level = 0;  //如果值无效,设置为默认值0(0%占空比)
  229.         //保存默认值到EEPROM
  230.         IapErase(0x0000);  //先擦除扇区
  231.         IapProgram(0x0000, pwm_level);
  232.     }
  233.     //初始化PCA模块2
  234.     CCON = 0x00;
  235.     CMOD = 0x08;                                //PCA时钟为系统时钟
  236.     CL = 0x00;
  237.     CH = 0x00;
  238.    
  239.     //配置PCA模块2为8位PWM模式(更稳定可靠)
  240.     CCAPM2 = 0x42;                              //PCA模块2为PWM工作模式
  241.     PCA_PWM2 = 0x00;                            //PCA模块2输出8位PWM
  242.    
  243.     //设置初始占空比
  244.     CCAP2L = pwm_duty[pwm_level] & 0xff;
  245.     CCAP2H = pwm_duty[pwm_level] & 0xff;
  246.    
  247.     CR = 1;                                     //启动PCA计时器
  248.                
  249.                 //ADC INIT
  250.     P_SW2 |= 0x80;                              //使能访问XFR
  251.     ADCTIM = 0x3f;                              //设置ADC内部时序
  252.     P_SW2 &= 0x7f;
  253.     ADCCFG = 0x0f;                              //设置ADC时钟为系统时钟/2/16
  254.     //ADC_CONTR = 0x80;                           //使能ADC模块
  255.     while (1)
  256.     {
  257.         key_scan();  //扫描按键
  258.     }
  259. }
  260. void IapIdle()
  261. {
  262.     IAP_CONTR = 0;                              //关闭IAP功能
  263.     IAP_CMD = 0;                                //清除命令寄存器
  264.     IAP_TRIG = 0;                               //清除触发寄存器
  265.     IAP_ADDRH = 0x80;                           //将地址设置到非IAP区域
  266.     IAP_ADDRL = 0;
  267. }
  268. char IapRead(int addr)
  269. {
  270.     char dat;
  271.     IAP_CONTR = 0x80;                           //使能IAP
  272.     IAP_TPS = 12;                               //设置等待参数12MHz
  273.     IAP_CMD = 1;                                //设置IAP读命令
  274.     IAP_ADDRL = addr;                           //设置IAP低地址
  275.     IAP_ADDRH = addr >> 8;                      //设置IAP高地址
  276.     IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
  277.     IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
  278.     _nop_();
  279.     dat = IAP_DATA;                             //读IAP数据
  280.     IapIdle();                                  //关闭IAP功能
  281.     return dat;
  282. }
  283. void IapProgram(int addr, char dat)
  284. {
  285.     IAP_CONTR = 0x80;                           //使能IAP
  286.     IAP_TPS = 12;                               //设置等待参数12MHz
  287.     IAP_CMD = 2;                                //设置IAP写命令
  288.     IAP_ADDRL = addr;                           //设置IAP低地址
  289.     IAP_ADDRH = addr >> 8;                      //设置IAP高地址
  290.     IAP_DATA = dat;                             //写IAP数据
  291.     IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
  292.     IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
  293.     _nop_();
  294.     IapIdle();                                  //关闭IAP功能
  295. }
  296. void IapErase(int addr)
  297. {
  298.     IAP_CONTR = 0x80;                           //使能IAP
  299.     IAP_TPS = 12;                               //设置等待参数12MHz
  300.     IAP_CMD = 3;                                //设置IAP擦除命令
  301.     IAP_ADDRL = addr;                           //设置IAP低地址
  302.     IAP_ADDRH = addr >> 8;                      //设置IAP高地址
  303.     IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
  304.     IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
  305.     _nop_();                                    //
  306.     IapIdle();                                  //关闭IAP功能
  307. }
复制代码



重写代码: 自编代码.rar (33.1 KB, 下载次数: 0)
原作者固件: LedDrive.rar (1.82 KB, 下载次数: 0)
嘉利创专业版工程: ProDoc_Board1.rar (157.64 KB, 下载次数: 0)
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-7 16:59 , Processed in 0.103503 second(s), 45 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表