有初学者问了这样的问题:单片机真正开发产品和学习的时候有什么差别,平时学的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在项目中是微不足道的一个模块,但要做到兼容项目,又方便移植、又可删减增加功能,其实也不是想象的那么简单。
结合STM32、Arduino理解红外遥控编解码通信原理
小米6白色版今日十点首卖,网友直呼:蓝瘦香菇买不到
扫描仪的主要性能指标
今年卖的最好的高端手机 居然有华为荣耀magic,小米note2
霍尔开关的工作原理 霍尔开关的优点 霍尔开关在气缸上的应用
单片机“花式点灯”实现方法
Intel新一代处理器Skylake:全新的GT4e核显
一份2018年Python开源项目Top100清单!
政策东风和技术突破加持,SENSOR CHINA助力提升中国传感与物联全球创新力
荣耀正式发布了46mm和42mm两种版本的荣耀MagicWatch 2
昕诺飞宣布在中国成功部署的智能互连道路照明系统及LED路灯已突破两万套
重庆大学OpenHarmony技术俱乐部正式揭牌成立
高速PCB设计简介:FR-4是高速PCB设计的最佳板材料选择吗?
黑客窃取了3种Microsoft产品的源代码
制动系统,制动系统是什么意思
半导体超声波发生器的应用范围
CPU的内存区域详解
E分析:拆解了54台手机,看看部件厂家如何分布
超威集团每年投重资用于电池制造的绿色改造
日防卫省重视人工智能及无人机研发 预算相关研发费达1676亿日元