灯板灯珠是3V,4串3并,电源24V2A(很亮)。电路是JLC开源的,附件附带原作者的固件(无源码),可以直接使用。后又根据电路写了一个四档高光的代码并带有档位断电记忆功能,无温度开启风扇功能,有需要的可以自行修改代码加上。
- //stc8g1k08a EEPROM 空间为 4K(0000h~0FFFh)
-
- #include "reg51.h"
- #include "intrins.h"
-
- sfr CCON = 0xd8;
- sbit CF = CCON^7;
- sbit CR = CCON^6;
- sbit CCF2 = CCON^2;
- sbit CCF1 = CCON^1;
- sbit CCF0 = CCON^0;
- sfr CMOD = 0xd9;
- sfr CL = 0xe9;
- sfr CH = 0xf9;
- sfr CCAPM0 = 0xda;
- sfr CCAP0L = 0xea;
- sfr CCAP0H = 0xfa;
- sfr PCA_PWM0 = 0xf2;
- sfr CCAPM1 = 0xdb;
- sfr CCAP1L = 0xeb;
- sfr CCAP1H = 0xfb;
- sfr PCA_PWM1 = 0xf3;
- sfr CCAPM2 = 0xdc;
- sfr CCAP2L = 0xec;
- sfr CCAP2H = 0xfc;
- sfr PCA_PWM2 = 0xf4;
- sfr P5 = 0xC8;
- sfr P0M1 = 0x93;
- sfr P0M0 = 0x94;
- sfr P1M1 = 0x91;
- sfr P1M0 = 0x92;
- sfr P2M1 = 0x95;
- sfr P2M0 = 0x96;
- sfr P3M1 = 0xb1;
- sfr P3M0 = 0xb2;
- sfr P4M1 = 0xb3;
- sfr P4M0 = 0xb4;
- sfr P5M1 = 0xc9;
- sfr P5M0 = 0xca;
-
- sfr IAP_DATA = 0xC2;
- sfr IAP_ADDRH = 0xC3;
- sfr IAP_ADDRL = 0xC4;
- sfr IAP_CMD = 0xC5;
- sfr IAP_TRIG = 0xC6;
- sfr IAP_CONTR = 0xC7;
- sfr IAP_TPS = 0xF5;
-
-
- //ADC sfr
- sfr ADC_CONTR = 0xbc;
- sfr ADC_RES = 0xbd;
- sfr ADC_RESL = 0xbe;
- sfr ADCCFG = 0xde;
-
- sfr P_SW2 = 0xba;
- #define ADCTIM (*(unsigned char volatile xdata *)0xfea8)
- #define ADC_POWER 0x80
- #define ADC_START 0x40
- char IapRead(int addr);//EEPROM读
- void IapProgram(int addr, char dat);////EEPROM写
- void IapErase(int addr);//EEPROM扇区擦除
-
- #define uchar unsigned char
- #define uint unsigned int
-
- //定义按键引脚
- sbit KEY_INC = P3^0; //增加占空比按键
- sbit KEY_DEC = P3^1; //减小占空比按键
- sbit PWM_IO =P5^4;
-
- //定义PWM占空比档位(6个档位)
- uchar pwm_level = 0; //初始档位为0(0%占空比)
-
- //占空比配置数组(8位PWM)
- uint pwm_duty[6] = {
- 0xff, // 0% 占空比 (8位PWM最大值)
- 0xe9, // 10% 占空比
- 0xe0, // 20% 占空比
- 0xd0, // 30% 占空比
-
- 0x80 // 50% 占空比
- };
-
- //延时函数
- void delay_ms(uint ms)
- {
- unsigned char data i, j;
- unsigned int abcd;
- for (abcd = ms; abcd > 0; abcd--)
- {
- _nop_();
- _nop_();
- _nop_();
- i = 11;
- j = 190;
- do
- {
- while (--j);
- } while (--i);
- }
- }
-
- //按键扫描函数
- void key_scan()
- {
- //检测增加按键
- if (KEY_INC == 0)
- {
- delay_ms(50); //去抖动
- if (KEY_INC == 0)
- {
- //单按操作:增加一个档位
- if (pwm_level < 4) //最大档位为4
- {
- pwm_level++;
- //更新PWM占空比
- CCAP2L = pwm_duty[pwm_level] & 0xff;
- CCAP2H = pwm_duty[pwm_level] & 0xff;
- }
-
- //检测是否为长按
- delay_ms(1000); //长按检测时间
- while (KEY_INC == 0) //如果按键仍然按下,进入长按模式
- {
- if (pwm_level < 4) //最大档位为4
- {
- pwm_level++;
- //更新PWM占空比
- CCAP2L = pwm_duty[pwm_level] & 0xff;
- CCAP2H = pwm_duty[pwm_level] & 0xff;
- delay_ms(500); //调节间隔500ms
- }
- else
- {
- //已达到最大档位,停止增加
- delay_ms(500); //保持间隔时间
- }
- }
-
- //松开按键后保存当前占空比
- IapErase(0x0000); //先擦除扇区
- IapProgram(0x0000, pwm_level);
- }
- }
-
- //检测减小按键
- if (KEY_DEC == 0)
- {
- delay_ms(50); //去抖动
- if (KEY_DEC == 0)
- {
- //单按操作:减小一个档位
- if (pwm_level > 0) //最小档位为1(10%,不能为0)
- {
- pwm_level--;
- //更新PWM占空比
- CCAP2L = pwm_duty[pwm_level] & 0xff;
- CCAP2H = pwm_duty[pwm_level] & 0xff;
- }
-
- //检测是否为长按
- delay_ms(1000); //长按检测时间
- while (KEY_DEC == 0) //如果按键仍然按下,进入长按模式
- {
- if (pwm_level > 1) //最小档位为1(10%,不能为0)
- {
- pwm_level--;
- //更新PWM占空比
- CCAP2L = pwm_duty[pwm_level] & 0xff;
- CCAP2H = pwm_duty[pwm_level] & 0xff;
- delay_ms(500); //调节间隔500ms
- }
- else
- {
- //已达到最小档位,停止减小
- delay_ms(500); //保持间隔时间
- }
- }
-
- //松开按键后保存当前占空比
- IapErase(0x0000); //先擦除扇区
- IapProgram(0x0000, pwm_level);
- }
- }
- }
- //unsigned int ADCSCAN(void)
- //{
- // ADC_CONTR |= 0x43; //启动AD转换 P3.3
- // _nop_();
- // _nop_();
- // while (!(ADC_CONTR & 0x20)); //查询ADC完成标志
- // ADC_CONTR &= ~0x20; //清完成标志
- // ADC_RES; //读取ADC结果
-
- //}
- unsigned int GetADCResult(BYTE ch)
- {
- unsigned int AdcTmp;
- unsigned char ADC_RES,ADC_RESL;
- AdcTmp=0;
- ADC_RES=0;
- ADC_RESL=0;
- ADC_CONTR = ADC_POWER| ch | ADC_START;
- Delay(500);
- while(~(ADC_CONTR|0xdf));//等待ADC转换完成
- // UartSend(ADC_RES);
- // UartSend(ADC_RESL);
- ADC_CONTR &= 0xdf; //清完成标志
- // AdcTmp=(ADC_RES)<<2;
- // AdcTmp|=ADC_RESL;
- AdcTmp = ((u16)ADC_RES << 2) + (ADC_RESL & 0x03);
- return AdcTmp; //返回ADC结果
-
- }
- void main()
- {
- PWM_IO = 0;
- //配置端口模式
- P0M0 = 0x00;
- P0M1 = 0x00;
- P1M0 = 0x00;
- P1M1 = 0x00;
- P2M0 = 0x00;
- P2M1 = 0x00;
- P3M0 = 0x00;
- P3M1 = 0x08;//p33 高阻 ADC输入
- P4M0 = 0x00;
- P4M1 = 0x00;
- // P5M0 = 0x00;
- // P5M1 = 0x00;
-
-
- //配置P54引脚为推挽输出
- P5M1 &= ~(1 << 4);
- P5M0 |= (1 << 4);
-
- //从EEPROM读取占空比档位
- pwm_level = IapRead(0x0000);
- //检查读取值是否在有效范围内
- if (pwm_level > 5)
- {
- pwm_level = 0; //如果值无效,设置为默认值0(0%占空比)
- //保存默认值到EEPROM
- IapErase(0x0000); //先擦除扇区
- IapProgram(0x0000, pwm_level);
- }
-
- //初始化PCA模块2
- CCON = 0x00;
- CMOD = 0x08; //PCA时钟为系统时钟
- CL = 0x00;
- CH = 0x00;
-
- //配置PCA模块2为8位PWM模式(更稳定可靠)
- CCAPM2 = 0x42; //PCA模块2为PWM工作模式
- PCA_PWM2 = 0x00; //PCA模块2输出8位PWM
-
- //设置初始占空比
- CCAP2L = pwm_duty[pwm_level] & 0xff;
- CCAP2H = pwm_duty[pwm_level] & 0xff;
-
- CR = 1; //启动PCA计时器
-
- //ADC INIT
- P_SW2 |= 0x80; //使能访问XFR
- ADCTIM = 0x3f; //设置ADC内部时序
- P_SW2 &= 0x7f;
- ADCCFG = 0x0f; //设置ADC时钟为系统时钟/2/16
- //ADC_CONTR = 0x80; //使能ADC模块
-
-
- while (1)
- {
- key_scan(); //扫描按键
- }
- }
-
- void IapIdle()
- {
- IAP_CONTR = 0; //关闭IAP功能
- IAP_CMD = 0; //清除命令寄存器
- IAP_TRIG = 0; //清除触发寄存器
- IAP_ADDRH = 0x80; //将地址设置到非IAP区域
- IAP_ADDRL = 0;
- }
-
- char IapRead(int addr)
- {
- char dat;
-
- IAP_CONTR = 0x80; //使能IAP
- IAP_TPS = 12; //设置等待参数12MHz
- IAP_CMD = 1; //设置IAP读命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_();
- dat = IAP_DATA; //读IAP数据
- IapIdle(); //关闭IAP功能
-
- return dat;
- }
-
- void IapProgram(int addr, char dat)
- {
- IAP_CONTR = 0x80; //使能IAP
- IAP_TPS = 12; //设置等待参数12MHz
- IAP_CMD = 2; //设置IAP写命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_DATA = dat; //写IAP数据
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_();
- IapIdle(); //关闭IAP功能
- }
-
- void IapErase(int addr)
- {
- IAP_CONTR = 0x80; //使能IAP
- IAP_TPS = 12; //设置等待参数12MHz
- IAP_CMD = 3; //设置IAP擦除命令
- IAP_ADDRL = addr; //设置IAP低地址
- IAP_ADDRH = addr >> 8; //设置IAP高地址
- IAP_TRIG = 0x5a; //写触发命令(0x5a)
- IAP_TRIG = 0xa5; //写触发命令(0xa5)
- _nop_(); //
- IapIdle(); //关闭IAP功能
- }
复制代码
重写代码:
自编代码.rar
(33.1 KB, 下载次数: 0)
原作者固件:
LedDrive.rar
(1.82 KB, 下载次数: 0)
嘉利创专业版工程:
ProDoc_Board1.rar
(157.64 KB, 下载次数: 0)
|