单片机项目中LED的重要性

很多初学者觉得自己学的东西很基础,担心今后实际工作用不到。有初学者问了这样的问题:单片机真正开发产品和学习的时候有什么差别,平时学的led、adc这些东西,在实际项目中会用到吗?
虽然技术更新迭代很快,但有很多基本的技术,仍然在实际项目中会用到,今天就拿led为例来说说吧。
led有哪些作用?
别小看led,它在实际生活中应用很广泛的。
首先就是以led为光源的项目,比如呼吸灯、广告灯、led显示屏等,这类控制led亮灭(闪烁),或者亮度渐变。
再次就是led背光灯,像液晶背光灯、按键背光灯等,这种也是需要控制led变化的。我之前做过有按键的项目,按键背光灯需要渐变、配合音效控制led不同频率闪烁,目的就是为了达到更好的体验效果。
再再次,led作为指示灯,电源指示灯、状态指示灯,这种就和接近初学者的学习时的led灯,但这种却在项目中很常见。
拿状态指示灯来说,一个项目的led状态指示灯可以直观明了的指示设备的运行状态,比如:运行、故障、待机、死机等常见状态。通过rgb,或者红黄绿不同颜色led组合,可以实现更多状态的指示。
下面针对led状态灯,说几点细节的内容。
led状态灯实现
这里结合代码为大家分享一些项目中常见的led状态灯的实现方法。
1、单色led运行状态指示灯
通过闪烁(一亮一灭)指示设备运行的状态的指示灯,一个关键作用:设备有没有死机。
很多产品中都会用到,你买一个开发板,提供的综合例程也基本都有。
裸机情况下(一般状态机),在某一个状态实现led闪烁:
int main(void) { //系统初始化 while(1) { //do something switch(state) { case 状态1: //do something break; case 状态2: //do something break; · · · case 状态灯: ed_toggle(); //led闪烁 break; } } }  
rtos情况下,新建一个状态灯线程,在线程里面直接控制即可:
void statuslight_task(void *pvparameters) { static ticktype_t xlastwaketime; //初始化 xlastwaketime = xtaskgettickcount(); for(;;) { //do something led_toggle(); //led闪烁 vtaskdelayuntil( xlastwaketime, 500); } }  
2、单色led渐变
led渐变在生活中其实也有一些场景在用,呼吸灯、键盘等,其实原来也很简单,就是控制led亮度。
控制方法有很多,电压、pwm都能达到控制led亮度的效果。当然,现在还有控制led渐变的专有芯片。
但是,对于单片机项目来说,单片机自身就能实现,如果单独用一个芯片,就显得有点多余。
使用dac输出模拟量可以实现,但如果多路就不现实,因此这种方法不常见。
常见的是pwm控制io高低电平(从而控制电压),这种对于单片机来说有两种方法:
定时器硬件pwm
控制gpio口高低电平
a、定时器硬件pwm
一个定时器输出pwm波形的同时,还需要一个定时器定时更新pwm输出占空比(修改亮度)。
b、控制gpio口高低电平
这个方法就比较简单,控制io口高低电平时间,只是这个时间需要结合整个项目业务逻辑(特别是裸机情况下),不能出现“卡机”情况。
当然,在rtos情况下,业务逻辑就比较简单,单独一个线程:
led_on(); vtaskdelay(timeson); led_off(); vtaskdelay(timesoff);  
这里timeson 和 timesoff是需要结合项目情况修改的变量(比如渐变时间)。
3、多色led,多种运行状态
一个设备在没有显示屏指示状态的时候,通过led指示状态也是一种方法,比如:红、黄、绿三色,分别常灭、常亮、闪烁三种状态。
这种相对第一种单色固定状态要复杂一点,但实现起来也不难,方法也有很多。
这里分享一些思路:创建一个线程,一个结构体,轮询各种led状态,根据应用修改其各种状态,以及闪烁时间等。
led状态结构体:
typedef struct { uint8_t mode; //模式 uint8_t status; //当前状态 uint16_t offtimes; //灭时间 uint16_t ontimes; //亮时间(ms) uint16_t counter; //计数(计时) void (*offfun)(void); //灭函数接口 void (*onfun)(void); //亮函数接口 }sl_typedef; /* 状态灯 */  
led状态主线程:
void statuslight_task(void *pvparameters) { static ticktype_t xlastwaketime; xlastwaketime = xtaskgettickcount(); for(;;) { sl_scan( sslg_structure); //红灯 sl_scan( ssly_structure); //黄灯 sl_scan( sslr_structure); //绿灯 vtaskdelayuntil( xlastwaketime, sl_task_period); } }  
这里结构体也是方便统一管理,其中sl_scan浏览(扫描)函数的参数通过传递结构体指针,是为了方便读取并修改其中变量。
当然,sl_scan浏览函数具体实现,就与你应用有关:
static void sl_scan(sl_typedef *sl_struct) { /* 常灭模式 */ if(sl_mode_off == sl_struct->mode) { sl_struct->status = sl_status_off; //状态置为灭 sl_struct->offfun(); //灭灯 } /* 常亮模式 */ else if(sl_mode_on == sl_struct->mode) { sl_struct->status = sl_status_on; //状态置为亮 sl_struct->onfun(); //亮灯 } /* 闪烁模式 */ else if(sl_mode_flicker == sl_struct->mode) { /* 在灭状态 */ if(sl_status_off == sl_struct->status) { sl_struct->counter++; if(sl_struct->counter >= sl_struct->offtimes) { sl_struct->counter = 0; sl_struct->onfun(); //亮灯 sl_struct->status = sl_status_on; //状态置为亮 } } /* 在亮状态 */ else if(sl_status_on == sl_struct->status) { sl_struct->counter++; if(sl_struct->counter >= sl_struct->ontimes) { sl_struct->counter = 0; sl_struct->offfun(); //灭灯 sl_struct->status = sl_status_off; //状态置为灭 } } else { sl_struct->status = sl_status_off; //状态置为灭 } } /* 未知模式 */ else { sl_struct->status = sl_status_off; //状态置为灭 sl_struct->offfun(); //灭灯 } }  
最后
以上的控制led的状态,其实是一个项目中很小的一个模块,还有更复杂的led实现和控制方法,相信做过这一块的同学就比较了解。
当然,led在项目中是微不足道的一个模块,但是,如果针对莫个人设计一块led的产品,那就意义非凡了。
上面这种,相信很多暖(zhi)男都做过,就是不知道,最终那个女孩子感动了没有?如果感动了,那这个led项目就是一生中非常重要的项目。


一文了解浪涌
吃个披萨就能理解云计算中IaaS、PaaS和SaaS
开关电容转换器简化了从1S到2S电池架构的迁移
中国联通与中国邮政签署战略协议,将在五大领域深化合作
开关电源如何降低纹波?
单片机项目中LED的重要性
苹果成功在香港注册了“Apple Card”及“Apple Cash”两项新商标
安防与智慧城市之间有着怎样的瓜葛呢?
常用汽车线束设计软件有哪些
MINITÜB 的UR机器人解决方案
维信诺固安G6 AMOLED生产线产能达3万片每月
什么蓝牙耳机品牌比较好、听歌音质好的蓝牙耳机
PCB电镀纯锡的缺陷
动力电池驱动当升科技实现加速发展
浅析FPC电路板的制造过程
闪电网络将给比特币交易带来哪些影响
配电箱的内部结构和相关保险丝的常见问题
苹果正式发邀请函,不止有iPhone8,苹果将有更多的新品,又要大肆揽钱了!
华为发布了面向交通行业的智简高速公路视频云网络方案
互感--连接器引起串扰的因素分析 如何改变返回电流路径