0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

单片机“花式点灯”实现方法

strongerHuang 来源:strongerHuang 2023-01-15 14:30 次阅读
有初学者问了这样的问题:单片机真正开发产品和学习的时候有什么差别,平时学的LEDADC这些东西,在实际项目中会用到吗? 虽然技术更新迭代很快,但有很多基本的技术,仍然在实际项目中会用到,今天就拿LED为例来说说吧。

LED有哪些作用

别小看LED,它在实际生活中应用很广泛的。 首先就是以LED为光源的项目,比如呼吸灯、广告灯、LED显示屏等,这类控制LED亮灭(闪烁),或者亮度渐变。 再次就是LED背光灯,像液晶灯、按键等,这种也是需要控制LED变化的。我做过有按键的项目,按键背光灯需要渐变、配合音效控制LED不同频率闪烁,目的就是为了达到更好的体验效果。 再再次,LED作为指示灯电源指示灯、状态指示灯,这种就和接近初学者的学习时的LED灯,但这种却在项目中很常见。354d71ee-9471-11ed-bfe3-dac502259ad0.gif  拿状态指示灯来说,一个项目的LED状态指示灯可以直观明了的指示设备的运行状态,比如:运行、故障、待机、死机等常见状态。通过RGB,或者红黄绿不同颜色LED组合,可以实现更多状态的指示。 下面针对LED状态灯,说几点细节的内容。

LED状态灯实现

这里结合代码为大家分享一些项目中常见的LED状态灯的实现方法。 1.单色LED运行状态指示灯通过闪烁(一亮一灭)指示设备运行的状态的指示灯,一个关键作用:设备有没有死机 很多产品中都会用到,你买一个开发板,提供的综合例程也基本都有。 裸机情况下(一般状态机,在某一个状态实现LED闪烁:
int main(void)
{
//系统初始化
  while(1)
  {
//dosomething
    switch(State)
    {
      case 状态1
        //do something
      break;


      case 状态2
        //do something
break;
      ·
      ·
·
      case 状态灯:
        ED_TOGGLE();  //LED闪烁
      break;
    }
  }
}
RTOS情况下,新建一个状态灯线程,在线程里面直接控制即可:
void StatusLight_Task(void *pvParameters)
{
staticTickType_txLastWakeTime;
  //初始化
  xLastWakeTime = xTaskGetTickCount();


  for(;;)
  {
    //do something


    LED_TOGGLE();                       //LED闪烁
    vTaskDelayUntil(&xLastWakeTime, 500);
  }
}
2.单色LED渐变LED渐变在生活中其实也有一些场景在用,呼吸灯、键盘等,其实原来也很简单,就是控制LED亮度。 控制方法有很多,电压、PWM都能达到控制LED亮度的效果。当然,现在还有控制LED渐变的专有芯片355d5f32-9471-11ed-bfe3-dac502259ad0.gif  但是,对于单片机项目来说,单片机自身就能实现,如果单独用一个芯片,就显得有点多余。 使用DAC输出模拟量可以实现,但如果多路就不现实,因此这种方法不常见。 常见的是PWM控制IO高低电平(从而控制电压),这种对于单片机来说有两种方法:
  • 定时器硬件PWM
  • 控制GPIO口高低电平
a.定时器硬件PWM一个定时器输出PWM波形的同时,还需要一个定时器定时更新PWM输出占空比(修改亮度)。 b.控制GPIO口高低电平这个方法就比较简单,控制IO口高低电平时间,只是这个时间需要结合整个项目业务逻辑(特别是裸机情况下),不能出现“卡机”情况。 当然,在RTOS情况下,业务逻辑就比较简单,单独一个线程:
LED_ON();
vTaskDelay(TimesON);


LED_OFF();
vTaskDelay(TimesOFF);

这里TimesONTimesOFF是需要结合项目情况修改的变量(比如渐变时间)。 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)
{
staticTickType_txLastWakeTime;
  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
    led
    +关注

    关注

    242

    文章

    23402

    浏览量

    664121
  • 单片机
    +关注

    关注

    6044

    文章

    44632

    浏览量

    639453
  • 光源
    +关注

    关注

    3

    文章

    718

    浏览量

    67937

原文标题:单片机“花式点灯”实现方法

文章出处:【微信号:strongerHuang,微信公众号:strongerHuang】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    单片机中断技术详解

    在现代电子设备中,单片机作为控制核心发挥着举足轻重的作用。而在其高效运作的背后,中断机制是推动单片机实现实时响应与高效执行的关键因素。本文将深入探讨单片机中的中断概念、中断系统的结构、
    的头像 发表于 02-02 15:57 220次阅读

    使用单片机实现直流电机的PWM调速控制原理图

    使用单片机实现直流电机的PWM调速控制
    发表于 12-10 15:29 6次下载

    上位如何实现发送参数给单片机单片机保存接收的参数重复运行指定的功能

    简单说明一下发这个贴子/问答的原因,很早以前就想实现这个功能了,但是一直没有找到好的方法,也没有什么思路,所以发帖问一问大佬们,希望大佬们指点一二。 需求/功能 描述: 上位部分主要是设定一些参数
    发表于 12-04 08:19

    单片机调试常见问题与解决方法

    烧录到单片机时,烧录软件显示无法与单片机通信。 解决方法: 检查单片机的电源是否正常,确保电源电压在规定的范围内。 检查烧录线的连接是否正确,包括数据线和地线。 确认烧录软件是否选择了
    的头像 发表于 11-01 14:11 1299次阅读

    如何实现51单片机与PC的串行通信

    51单片机与PC的串行通信是一种常见的通信方式,它允许单片机通过串行接口与PC进行数据交换。这种通信方式在嵌入式系统、工业控制、物联网等领域有着广泛的应用。以下是
    的头像 发表于 10-21 11:35 1357次阅读

    单片机怎么写入程序

    单片机(Microcontroller Unit,MCU)是一种集成电路芯片,它将计算机的CPU、存储器、输入/输出接口等功能集成在一个芯片上。单片机广泛应用于嵌入式系统和物联网设备中。编写单片机
    的头像 发表于 10-21 11:21 1020次阅读

    单片机的中断机制

    单片机的中断机制是一种重要的处理方式,它允许单片机在执行主程序的过程中,能够暂停当前任务,转而处理外部或内部紧急事件。这种机制极大地提高了系统的响应速度和处理能力,使得单片机在各种应用领域中得到广泛应用。以下是对
    的头像 发表于 10-17 18:03 1067次阅读

    单片机烧录程序用什么软件

    单片机烧录程序是单片机开发过程中的一个重要环节,涉及到将编写好的程序代码通过烧录器写入单片机的ROM中,以实现单片机的控制。 烧录器的类型
    的头像 发表于 09-02 10:05 1759次阅读

    单片机烧录程序的线比单片机上的少还能烧录吗

    的存储器通常分为两类:ROM(只读存储器)和RAM(随机存取存储器)。ROM用于存储程序代码,而RAM用于存储程序运行过程中的数据。烧录过程就是将程序代码写入ROM中。 单片机烧录方法 单片机烧录的
    的头像 发表于 09-02 09:54 641次阅读

    单片机烧录程序的基本步骤是什么

    单片机烧录程序是单片机开发过程中非常重要的一步,它涉及到将编写好的程序代码通过一定的方式传输到单片机内部的存储器中,使单片机能够按照预定的逻辑执行任务。 一、硬件准备
    的头像 发表于 09-02 09:47 1558次阅读

    单片机boot0和boot1怎么设置

    单片机的启动模式通常包括从内部ROM启动、从外部ROM启动、从外部Flash启动等。 不同的启动模式对应不同的Boot0和Boot1设置。 Boot0和Boot1的设置方法 Boot0和Boot1通常通过
    的头像 发表于 08-22 09:50 3222次阅读

    单片机中的几种环形缓冲区的分析和实现

    单片机中的几种环形缓冲区的分析和实现一、简介环形缓冲区(RingBuffer)是一种高效的使用内存的方法,它将一段固定长度的内存看成一个环形结构,用于存储数据,能够避免使用动态申请内存导致的内存碎片
    的头像 发表于 08-14 08:39 1154次阅读
    <b class='flag-5'>单片机</b>中的几种环形缓冲区的分析和<b class='flag-5'>实现</b>

    蓝牙模块如何实现单片机和手机端数据互传

    蓝牙模块实现单片机和手机端数据互传的过程可以分为以下几个步骤: 硬件准备 : 确保你有一个支持蓝牙通信的单片机开发板,如Arduino、Raspberry Pi等。 准备一个兼容的蓝牙模块,如
    的头像 发表于 07-24 17:59 2997次阅读
    蓝牙模块如何<b class='flag-5'>实现</b><b class='flag-5'>单片机</b>和手机端数据互传

    如何系统、科学地自学单片机

    的自学单片机呢?自学单片机需要一定的计划和方法,以下是具体的步骤和建议。如何系统、科学地自学单片机?学习电子基础知识:理解电路原理、数字电子技术、模拟电子技术等基础
    的头像 发表于 03-28 08:03 1229次阅读
    如何系统、科学地自学<b class='flag-5'>单片机</b>?

    8-Bit 触控式 Flash 单片机中文资料

    而又有效的实现方法。 触摸按键功能完全集成于单片机内,使用较少的外部元件便可实现触摸按键的 应用。该系列单片机除了 Flash 程序存储器,
    发表于 02-28 10:01 4次下载