电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
文章
STM32 PWM驱动RGB全彩LED
分 享
扫描二维码分享
STM32 PWM驱动RGB全彩LED
全彩LED
PWM
呼吸灯
嵌入式从0到1
关注
发布时间: 2020-07-28
丨
阅读: 3667
手里有下面几种四脚全彩LED,分为共阴或者共阳两种。 ![](https://cf04.ickimg.com/bbsimages/202008/c7467be7cda2c654b7236ce7c94506e7.png) 我们今天以共阳极全彩RGB LED为例进行讲解。 这种全彩RGB LED其实内部包括三个发光二极管,颜色分别为**R**ed(红色)、**G**reen(绿色)和**B**lue(蓝色)。 本文使用的共阳全彩LED的驱动原理图如下所示: ![](https://cf04.ickimg.com/bbsimages/202008/649c689d5f9f2f82b5c59afaed21fa10.png) ### 多彩LED实现方式一 本例应用中,R86为0R,R85、R87和R88选用的1K的电阻。R85、R87和R88的电阻作用为限流。 ![](https://cf04.ickimg.com/bbsimages/202008/92779b1117b4b880a38c025d2015541f.png) 当LED_R引脚置低时,红灯亮; 当LED_G引脚置低时,绿灯亮; 当LED_B引脚置低时,蓝灯亮。 当RGB三色灯,亮灭不同组合时,全彩LED的颜色为组合后的颜色,具体如下: | R | G | B | 颜色 | | :---: | :---: | :---: | :---: | | 亮 | 灭 | 灭 | 红 | | 灭 | 亮 | 灭 | 绿 | | 灭 | 灭 | 亮 | 蓝 | | 亮 | 亮 | 灭 | 黄 | | 灭 | 亮 | 亮 | 青色 | | 亮 | 灭 | 亮 | 紫色 | | 亮 | 亮 | 亮 | 白色 | 这种情况,我们只需要控制RGB三个引脚的高低电平即可,所以初始化STM32的GPIO引脚为输出模式即可: ```C //LED IO初始化 void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_SetBits(GPIOB,GPIO_Pin_6); //初始化为高电平,即灭 GPIO_SetBits(GPIOB,GPIO_Pin_7); GPIO_SetBits(GPIOB,GPIO_Pin_8); } ``` 初始化完毕之后,只需要调用GPIO_ReSetBits和GPIO_SetBits这两个函数,即可实现对LED亮灭的控制。 ### 多彩LED实现方式二 上面使用的是三色灯通过排列组合的方式,通过亮灭不同组合,进而显示不同的颜色。 但是这样显示的颜色种类毕竟是有限的。 如果我们可以控制RGB不同颜色的比例,根据RGB的对照表,我们就可以显示RGB全彩任意颜色了。 ![](https://cf04.ickimg.com/bbsimages/202008/bdd4ea4146c71464815f6d4b90b82df1.png) 要想控制各个颜色的比例,我们可以使用PWM输出的方式控制高低电平的占空比即可。 设计原理图的时候,我特意选择了三个带有PWM输出功能的GPIO:PB6、PB7和PB8,我们查看芯片手册,能够看到这三个引脚带有TIMx_CHy这样的标识,即说明该引脚具有PWM输出功能。 ![](https://cf04.ickimg.com/bbsimages/202008/0dc6c4226929ea5a8b7a8535ac989405.png) 我们首先初始化这三个引脚: ```C void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //注意此处跟上面有区别 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } void Led_PWM_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); LED_Init(); TIM_DeInit(TIM4); /@@* Time Base configuration */ TIM_TimeBaseStructure.TIM_Period = arr; TIM_TimeBaseStructure.TIM_Prescaler = psc; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM4, &TIM_OCInitStructure); TIM_OC2Init(TIM4, &TIM_OCInitStructure); TIM_OC3Init(TIM4, &TIM_OCInitStructure); TIM_CtrlPWMOutputs(TIM4, ENABLE); TIM_OC1PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_OC2PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_OC3PreloadConfig(TIM4, TIM_OCPreload_Enable); TIM_ARRPreloadConfig(TIM4, ENABLE); TIM_Cmd(TIM4, ENABLE); } ``` 注意上面,GPIO的模式设置为: ```C GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; ``` main函数中调用上面初始化函数: ```C Led_PWM_Init(254, 0); //254 PWM 频率=72000KHz/(254+1)=282.5Khz ;1:不分频 ``` 这样,我们相当于将各个GPIO的输出,分成了255份,正好对应RGB值,每通道的值为0~255。 所以封装RGB颜色设置的函数为: ```C void RGBLed(u8 R,u8 G,u8 B) { TIM_SetCompare1(TIM4,R); //CH1 R TIM_SetCompare2(TIM4,G); //CH2 G TIM_SetCompare3(TIM4,B); //CH3 B } ``` 要设置不同颜色,我们只需要根据RGB颜色对照表设置对应的值即可。 比如,我们要设置成橙色: ![](https://cf04.ickimg.com/bbsimages/202008/e5b6b9e2413bbf73a34829e7d3ddd8f6.png) 我们只需要像如下进行函数调用即可: ```C RGBLed(255,165,0); ``` ### 注意 STM32的IO口灌入电流和输出驱动电流最大是多少? I/O口正常提供灌入和输出电流为+/-8mA,可以达到+/-20mA(不过这时IO口的电平值会有变化,但要保证所有进入芯片VDD的不能超过150mA,同样所有从VSS流出的电流也不能超过150mA。 ![](https://cf04.ickimg.com/bbsimages/202008/dd68453627d124b68c66e65f1ed5ad0b.png) ![](https://cf04.ickimg.com/bbsimages/202008/ea01c57092037372cdcda85b08b61c20.png) 所以使用GPIO直接驱动LED时,要注意驱动电流的大小(我们本例中仅有三个LED,这样使用还是可以的)。 本例驱动一个全彩RGB LED需要三个GPIO引脚,驱动的LED不多,而且电流不大,可以用GPIO直接驱动。 如果需要驱动更多的LED,最好使用三极管当作开关控制LED灯,使用三极管调节亮度比较方便,不用担心CPU的负载能力。 ### 结果演示 我们通过色相环,发送RGB的数据,单片机收到JSON字符串,对其解析,然后得到RGB的值,进而改变LED的颜色。 ---- 文章首发于公众号:【**嵌入式从0到1**】 公众号内容面向大学生,电子爱好者,每个月会做一个毕业设计难度的DIY内容,下学期大四的朋友可以关注一下,到时做毕设就不用找人啦,欢迎学弟学妹来关注哈。 有要学习单片机,嵌入式,物联网知识的可以关注一下,我们一起学习一起进步。 加号主微信号:chengxuyuanxiaoha(程序员小哈),可以拉你进技术交流群,当然也可以私聊号主免费咨询。
原创作品,未经权利人授权禁止转载。详情见
转载须知
。
举报文章
点赞
(
0
)
嵌入式从0到1
关注
评论
(0)
登录后可评论,请
登录
或
注册
相关文章推荐
MK-米客方德推出工业级存储卡
Beetle ESP32 C3 蓝牙数据收发
Beetle ESP32 C3 wifi联网获取实时天气信息
开箱测评Beetle ESP32-C3 (RISC-V芯片)模块
正点原子数控电源DP100测评
DP100试用评测-----开箱+初体验
Beetle ESP32 C3环境搭建
【花雕体验】16 使用Beetle ESP32 C3控制8X32位WS2812硬屏之二
X
你的打赏是对原创作者最大的认可
请选择打赏IC币的数量,一经提交无法退回 !
100IC币
500IC币
1000IC币
自定义
IC币
确定
X
提交成功 ! 谢谢您的支持
返回
我要举报该内容理由
×
广告及垃圾信息
抄袭或未经授权
其它举报理由
请输入您举报的理由(50字以内)
取消
提交