PWM 实现调光

一、项目效果

预期(没有相关经验)

达到的目的(是实际能做到的)

通过 PWM 驱动扩展板上的冷光 LED 和暖光 LED,
并通过红外遥控器调节占空比来实现调节色温和调节亮度的功能。
这里也可以使用普通的,调节普通的led灯珠的亮度

  1. 使用 CH+/-键设置灯光的色温
  2. 使用+/-键设置灯光亮度
  3. 使用 EQ 键控制灯光开启或者关闭
    (是基于成功做出,遥控器的实验)
  4. 通过串口打印此时的亮度和色温百分比

二、原理说明

调光原理

学习物联网最经典的案例就是实现一款智能灯,
用户可以对其进行色温、亮度、颜色(下一章讲解)的控制,
色温就是指灯光的颜色是偏白(冷光源) 还是偏黄(暖光源) ,
单位是K(开尔文),色温值越高光源颜色就越白反之色温越低,光源颜色就越黄。
通常使用冷光灯和暖光灯配合的方式,通过调节各自的亮度来实现色温的任意调节。

调节灯光亮度的原理就是通过 PWM 的占空比来设置灯光亮暗,
调节灯光色温则是在当前亮度值(占空比)基础上再次进行比例的分配


这便是调光原理

硬件连接

开发板上使用的冷光灯色温为 6000K,暖光灯为 3000K,
上图这种情况下对应的色温值为 3900K,另外为了保证色温恒定在固定值,通常亮度不能设置为 0,
而是有一个保底的最小值,比如 10%。
还需要注意的是,为了大家方便理解今后不使用 K 作为色温单位,
而是像亮度那样使用百分比值,范围 0-100,值越大,灯光越白

开发板上的两颗高亮 LED 分别是暖光 LED 和冷光 LED

其中使用这两个引脚(PA15和PB5)的注意点
PA15上电后,该引脚默认是 JTAG 的 JTDI, 因此需要将其引脚重映射为 TIM2 的通道 1,
PB3 上电默认功能是 JTAG 的 JTDO,所以也需要 PB3 重映射为 TIM2 的通道 1,
这两个引脚的功能映射图

配置定时器 2 的通道 1/2 作为 PWM 输出的步骤

  1. 重映射 TIM2 的 1/2 通道到 PA15 和 PB3 引脚,并初始化为复用输出
  2. 初始化定时器,主要是设置定时器周期和重装载寄存器
  3. 分别初始化定时器 2 的输出比较通道 1/2

总结

难点就在于将亮度和色温值最终转换为占空比的计算公式上。

程序说明

灯光初始化函数

/*** 功能:初始灯光* 参数:*          brightness:初始化亮度 10-100*          colortemp:初始化色温 0-100         * 返回值:None*/
void initLight(u8 brightness,u8 colortemp)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO,ENABLE);GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);    //禁止JTAG保留SWDGPIO_PinRemapConfig(GPIO_PartialRemap1_TIM2, ENABLE);         //设置JTAG为定时器2部分映射,只使用SWD模式/*设置冷光灯*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure); /*设置暖光灯*/GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure); setLight(brightness,colortemp);
}

结合代码来理解这句话
灯光初始化函数实现了复用功能重映射,
并初始化冷光灯和暖光灯的控制引脚为复用输出。

设置灯光函数

/*** 功能:设置灯光亮度和色温* 参数:*          brightness:亮度 10-100*          colortemp:色温 0-100         * 返回值:None*/
void setLight(u8 brightness,u8 colortemp)
{/*** 无论是亮度还是色温,最终都体现在LED的亮度上* LED最终的亮度计算公式为:满占空比(重装载值) * 亮度百分比 * 色温百分比* 并且要保证冷光和暖光的色温比值之和为100%* */TIM_SetCompare1(TIM2,getPeriod(TIM2)*brightness/100*colortemp/100);         //设置冷光 对应PA15 TIM2_CH1TIM_SetCompare2(TIM2,getPeriod(TIM2)*brightness/100*(100-colortemp)/100);   //设置暖光 对应PB3  TIM2_CH2
}

为了方便理解, 没有把占空比计算公式进行合并。
我们通过 TIM_setCompare1()和 TIM_setCompare2()函数
对定时器 2 的捕获/比较寄存器 1/2 赋值来改变 PWM 占空比,
传入函数的第二个参数就是亮度-色温的计算公式,
在公式中先获取了重装载寄存器中的值(满占空比对应的计数值),
然后乘上亮度的百分比得到我们想要的亮度,最后在此基础上又将亮度值乘上色温百分比,
这里要注意,冷/暖光的色温比值之和是 100%,
这就保证了无论亮度值是多少,最终呈现出来的色温是不受影响的。

PWM 初始化函数

初始化定时器2输出比较通道1来生成PWM 对应冷光

/*** 功能:初始化定时器2输出比较通道1来生成PWM 对应冷光* 参数:*      duty:设置PWM输出的占空比* 返回值:None*/
void initTIM2OC1(u16 duty)
{TIM_OCInitTypeDef  TIM_OCInitStructure;                           //定义输出比较初始化结构体            TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;           //设置PWM1模式TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能TIM_OCInitStructure.TIM_Pulse = duty;                       //设置捕获比较寄存器的值TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //设置有效电平为高电平TIM_OC1Init(TIM2, &TIM_OCInitStructure);                    //生效初始化设置TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);              //使能输出比较预装载,即更改完输入捕获寄存器的值要等到更新事件发生才生效,该行加不加无所谓
}

初始化定时器2输出比较通道2来生成PWM 对应暖光

/*** 功能:初始化定时器2输出比较通道2来生成PWM 对应暖光* 参数:*      duty:设置PWM输出的占空比* 返回值:None*/
void initTIM2OC2(u16 duty)
{TIM_OCInitTypeDef  TIM_OCInitStructure;                           //定义输出比较初始化结构体            TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;           //设置PWM1模式TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出使能TIM_OCInitStructure.TIM_Pulse = duty;                       //设置捕获比较寄存器的值TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;     //设置有效电平为高电平TIM_OC2Init(TIM2, &TIM_OCInitStructure);                    //生效初始化设置TIM_OC2PreloadConfig(TIM2, TIM_OCPreload_Enable);              //使能输出比较预装载,即更改完输入捕获寄存器的值要等到更新事件发生才生效,该行加不加无所谓
}

主函数

int main(void)
{u8 light_power = 1;       //默认开机s8 brightness = 100; //亮度s8 colortemp = 50;     //色温/*初始化各外设*/ initSysTick();                          initLED();initUART();initNVIC(NVIC_PriorityGroup_2);/*初始化NEC*/ initNEC();/*定时器4时钟周期10us,中断周期200ms,使能更新中断和捕获通道3中断*/initTIMx(TIM4,719,19999,TIM_IT_Update|TIM_IT_CC3,ENABLE);/*设置下降沿触发捕获*/initTIM4IC3(TIM_ICPolarity_Falling);  /*设置定时器2时钟为10us,1KHz*/initTIMx(TIM2,719,99,TIM_IT_Update,DISABLE);initTIM2OC1(50);initTIM2OC2(50);/*亮度10%,色温50%*/initLight(100,50);    while(1){if(NEC_DataStructure.CmdCode_H == 0x45)        //CH-键按下{NEC_DataStructure.CmdCode_H = 0;          //清除键值colortemp -= 10;if(colortemp<0)                      {colortemp = 0;}setLight(brightness,colortemp);}else if(NEC_DataStructure.CmdCode_H == 0x47) //CH+键按下{NEC_DataStructure.CmdCode_H = 0;          //清除键值colortemp += 10;if(colortemp>100)        {colortemp = 100;}   setLight(brightness,colortemp);}else if(NEC_DataStructure.CmdCode_H == 0x07) //-键按下                                        {NEC_DataStructure.CmdCode_H = 0;       //清除键值brightness -= 10;if(brightness<10)                       {brightness = 10;                       //保底值}setLight(brightness,colortemp);}else if(NEC_DataStructure.CmdCode_H == 0x15) //+键按下{NEC_DataStructure.CmdCode_H = 0;          //清除键值brightness += 10;if(brightness>100)                         {brightness = 100;                       }setLight(brightness,colortemp);         }else if(NEC_DataStructure.CmdCode_H == 0x09) //EQ键按下{NEC_DataStructure.CmdCode_H = 0;         //清除键值light_power = !light_power;                  //开关机状态取反if(light_power == 0){setLight(0,0);                          //关灯}else {setLight(brightness,colortemp);       //开灯}                  }else {}printf("brightness is :%d%%\n",brightness);printf("color temperature is :%d%%\n",colortemp);toggleLED();Delay_ms(100);        }
}

代码很长,主要实现的是
定时器 2 设置的时钟周期为 10us,则 1KHz(1ms)需要计数 100 个。
然后初始化 PWM 并设置灯光开机默认最大亮度,色温 50%。
在用户逻辑循环中不断的判断此时红外键值,并根据键值做出相应的灯光控制动作。

最终效果

PWM 实现调光——测试pwn的功能相关推荐

  1. 【零知ESP8266教程】快速入门10-使用PWM进行调光

    前面的分享热身完毕,接下来,我们要进入更专业电子技术的深入哦! PWM科普:PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所 ...

  2. 乐鑫esp8266学习rtos3.0笔记第9篇:整理分享那些我在项目中常用的esp8266 rtos3.0版本的常见驱动,Button按键长短按、PWM平滑调光等。(附带demo)

    本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途.如有不对之处,请留言,本人及时更改. 1. Esp8266之 搭建开发环境,开始一个"hello ...

  3. 支持PWM 高辉调光的多功能LED恒流驱动器Hi7011

    共阳输出65536:1 高辉调光1‰深度调光@20K超低压差1.5V恒流  宽输入电压:5-100V  平均电流工作模式  高效率:最高可达 95%  输出电流可调范围 60mA~1.5A  ...

  4. PWM的调光基本原理

    什么是PWM? PWM信号是PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,是一种模拟控制方式,根据相应载荷的变化来调制晶体管基极或MOS管栅极的偏置,来实现晶体管或M ...

  5. 基于ESP32的智能台灯-PWM网页调光-实时时间-OLED显示-语音闹钟-WEB远程操控

    具体的项目,我免费分享在我的项目里,供大家参考学习: chenyuhan1997/ESP32-SMART-WIFI-PWM-LED-ALARM-CLOCK: Desk lamp with PWM ad ...

  6. 【大功率摄影灯/舞台灯RGB调光驱动方案】DC-DC降压恒流LED双路调光芯片FP7126,共阳极高辉无频闪调光,调光深度可达万分之一

    方案名称 [大功率摄影灯/舞台灯RGB调光驱动方案]DC-DC降压恒流LED双路调光芯片FP7126,共阳极高辉无频闪调光,调光深度可达万分之一 描述 FP7126 是平均电流模式控制的 LED 驱动 ...

  7. 远翔DC-DC降压恒流LED双路调光IC RGB共阳极无频闪调光调色芯片FP7126-FP7127-FP7128 舞台灯磁吸轨道灯智能家居调光电源应用方案

    方案名称 [舞台灯RGB调光驱动方案]DC-DC降压恒流LED双路调光芯片FP7126,共阳极高辉无频闪调光,调光深度可达万分之一 描述 FP7126 是平均电流模式控制的 LED 驱动 IC,具有稳 ...

  8. FP7122降压恒流内置MOS耐压100V共正极阳极PWM调光方案原理图

    FP7122 产品特性说明 恒流输出:IC内部有快速回授机制,输出电流不受电感量.输入电压与输出 LED 电压影响. 恒定电流纹波控制:FP7122会自动调整频率,使LED上的电流纹波固定在±25%. ...

  9. PWM调光方法在LED亮度调节中的应用

    LED 是一种固态电光源, 是一种半导体照明器件,其电学特性具有很强的离散性.它具有体积小.机械强度大.功耗低.寿命长, 便于调节控制及无污染等特征,有极大发展前景的新型光源产品.LED 调光方法的实 ...

最新文章

  1. 编程马拉松大赛试题及代码(C++实现)
  2. 3_ARM内核和架构都是什么意思,它们到底是什么关系?
  3. Kubernetes kubectl proxy命令的妙用
  4. 画了个Android
  5. 导出sql文件_(一)SQL基本知识
  6. Magento 获取当前货币和货币符How to get current currency in Magento
  7. textarea怎么占满整个td_保健品为什么偏偏盯上老人?作为子女,应怎么面对老人狂买保健品...
  8. MySQL带参数的存储过程小例子
  9. Waymo在美国推出自动驾驶汽车共享服务
  10. 打工的人面对老板是没有溢价权的
  11. win10 64位系统 excel2016 vba odbc方式 访问 oracle远程数据库 免安装oracle客户端
  12. WINDOWS游戏编程学习笔记(一):Hello Game!
  13. 怎么用python黑别人电脑_超级黑科技代码!用Python打造电脑人脸屏幕解锁神器附带接头暗号!...
  14. Program received signal SIGFPE,Arithmetic exception.
  15. 探寻HTTPS中S的含义
  16. Vue子组件绑定事件无效
  17. Bugzilla使用手册
  18. 【Hello Linux】Linux入门
  19. poj1419Graph Coloring(一般图最大独立集或着最大团)
  20. 关于3Dmax出现错误奔溃和中毒解决问题方法

热门文章

  1. 【Linux】创建新用户 sudo配置,添加信任
  2. Java 矩阵主对角线所有数字之和
  3. 基于python的微信公众号开发教程_基于python的微信公众号开发教程
  4. 计算机文档排版考试,Word和WPS通用的文档排版技巧
  5. SQL server学习日志(二)创建表!手把手教你创建表,修改表,了解数据类型!超详细!
  6. 如何手机访问电脑服务器上的网页?
  7. PS 滤镜——(扭曲)球面化 Spherize
  8. android 监控app 读写,Android端 APP性能监控实践
  9. decelerate(decelerates)
  10. android编程xml动画,Android中xml设置Animation动画效果详解