OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2942|回复: 0

MCU单片机LED指示灯模块化编程程序思考

[复制链接]

56

主题

167

帖子

4

精华

高级会员

Rank: 4

积分
602
金钱
602
注册时间
2013-10-18
在线时间
59 小时
发表于 2022-11-22 10:46:38 | 显示全部楼层 |阅读模式
#include "led.h"

///////////////////////////////////////////////////////////////////////////////////////////////////
//初始化,time_callback单位ms
/************************************函数说明**********************************
**形参:略
**返回值:略
**创建者:绍兴科立新科技有限公司
**仅供学习使用,不得用于商业用途
*******************************************************************************/
void LedObjInit(sLed *led, sLedInitObj init_obj,uint32_t time_callback)
{
        uint8_t i,j;
        //硬件指针缓存初始化
                led->run_obj.time_base  =  0u;
//                led->run_obj.init_obj->buff_cnt  = 0;//最大的缓存数进行初始化
                led->run_obj.cur_led_run_flag = 0u;
                led->run_obj.init_obj->led_init  =  init_obj.led_init;
                led->run_obj.init_obj->led_init();//led端口初始化
                led->run_obj.init_obj->led_on  =  init_obj.led_on;
                led->run_obj.init_obj->led_off  =  init_obj.led_off;

                //灯的控制参数初始化
                led->run_obj.init_obj->set_obj = init_obj.set_obj;
               
                if(time_callback > 0u)
                {
                        led->run_obj.callback_time = time_callback;
                }
                else
                {
                        led->run_obj.callback_time = LED_CALLBACK_BASE_TIME;
                }

}
/************************************函数说明**********************************
**形参:略
**返回值:略
**创建者:绍兴科立新科技有限公司
**仅供学习使用,不得用于商业用途
*******************************************************************************/
static void LedCallInit(sLed *led)
{

        led->run_obj.sta_cur = LED_STA_IDLE;
        led->run_obj.time_base  =  0u;
        led->run_obj.cur_led_run_flag = 0u;
}
/************************************函数说明**********************************
**形参:略
**返回值:略
**创建者:绍兴科立新科技有限公司
**仅供学习使用,不得用于商业用途
*******************************************************************************/
static uint8_t LedSetCall(sLed *led, uint16_t on_time , uint16_t off_time , uint16_t loop_cnt , uint8_t ctr_mode)
{
                uint8_t ret=0;
                //所有传入参数有效性判断
                if(on_time > 65530u)
                {
                        on_time = 65530u;
                }
                if(off_time > 65530u)
                {
                        off_time = 65530u;
                }

                if(loop_cnt < 1u)
                {
                        loop_cnt = 1;
                }
                if(ctr_mode > 3u)
                {
                        ctr_mode = CTR_MODE_NOR;
                }
               
                if(ctr_mode<2u)
                {

                                //赋值
                                if(ctr_mode!=CTR_MODE_NOR)//暂只做覆盖式抢占
                                {
                                                led->run_obj.init_obj->set_obj.led_ontime =  on_time;
                                                led->run_obj.init_obj->set_obj.led_offtime   =  off_time;
                                                led->run_obj.init_obj->set_obj.loop_cnt  =  loop_cnt;
                                                ret = 1;//成功
                                }
                                else
                                {
                                       
                                                led->run_obj.init_obj->set_obj.led_ontime =  on_time;
                                                led->run_obj.init_obj->set_obj.led_offtime   =  off_time;
                                                led->run_obj.init_obj->set_obj.loop_cnt  =  loop_cnt;
                                                ret = 1;//成功                 
                                }
                               
                                if(ret  ==  1u)
                                {
                                                //端口打开
                                                //led->run_obj.cur_led_run_flag = 1;
                                                //led->run_obj.time_base  =  0;
                                }
                                                                       

                        }
                        else
                        {
                               
                                        if(ctr_mode == CTR_LED_ON)
                                        {
                                                                                //端口打开
                                                                                led->run_obj.init_obj->led_on();
                                                                                LedCallInit(led);
                                        }
                                        else
                                        {
                                                                                //端口关闭
                                                                                led->run_obj.init_obj->led_off();
                                                                                LedCallInit(led);
                                               
                                        }
                                        ret = 1;//成功
                        }

      return ret;
}

/************************************函数说明**********************************
**形参:略
**返回值:略
**创建者:绍兴科立新科技有限公司
**仅供学习使用,不得用于商业用途
*******************************************************************************/
//对外调用接口 1:成功 0:失败
//调用举例:常亮1秒熄灭LedCall(xxx, 1000 , 0, 1, CTR_MODE_CTR)
uint8_t LedCall(sLed *led, uint16_t on_time , uint16_t off_time , uint16_t loop_cnt , uint8_t ctr_mode)
{
    uint8_t ret;

    ret = LedSetCall(led, on_time , off_time , loop_cnt , ctr_mode);

    return ret;
}

/************************************函数说明**********************************
**形参:略
**返回值:略
**创建者:绍兴科立新科技有限公司
**仅供学习使用,不得用于商业用途
*******************************************************************************/
//定时器回调函数 1-100ms调用一次
void LedTimerHandle(sLed *led)
{
        if(led->run_obj.cur_led_run_flag)
        {
                if(led->run_obj.time_base < 65530u)
                {
                        led->run_obj.time_base += led->run_obj.callback_time;
                }
        }
}

/************************************函数说明**********************************
**形参:略
**返回值:略
**创建者:绍兴科立新科技有限公司
**仅供学习使用,不得用于商业用途
*******************************************************************************/
//未实测
uint8_t LedMainHandle(sLed *led)
{

    uint8_t i;
       
        uint8_t sta_temp;
       
        sta_temp = led->run_obj.sta_cur;
        switch(sta_temp)
        {
               
                case LED_STA_IDLE:/*空闲*/
                {
                        if(led->run_obj.cur_led_run_flag)
                        {
                                        led->run_obj.init_obj->led_on();
                                        led->run_obj.time_base = 0u;
                                        led->run_obj.state_change = 0u;
                                        led->run_obj.sta_change = 0u;
                                        led->run_obj.sta_change |= LED_STA_RUN;
                                        led->run_obj.sta_cur = LED_STA_RUN;
                                        led->run_obj.cur_led_run_flag = 1U;
                        }
                        else
                        {
                                        led->run_obj.sta_change = led->run_obj.sta_change << 4u;
                                        led->run_obj.sta_change |= LED_STA_IDLE;       
                        }
                }
                break;
               
                case LED_STA_RUN:
                {
                       
                                led->run_obj.sta_change = led->run_obj.sta_change << 4u;
                                led->run_obj.sta_change |= LED_STA_RUN;
                                if(led->run_obj.init_obj->set_obj.loop_cnt!=0)
                                {
                                          if(led->run_obj.state_change==0)
                                          {
                                                          if(led->run_obj.time_base >= led->run_obj.init_obj->set_obj.led_ontime)
                                                          {
                                                                          led->run_obj.time_base=0;
                                                                          led->run_obj.init_obj->led_off();//
                                                                          led->run_obj.state_change=1;
                                                                          
                                                          }
                                          }
                                          else
                                          {
                                                          if(led->run_obj.time_base >= led->run_obj.init_obj->set_obj.led_offtime)
                                                          {
                                                                          led->run_obj.time_base=0;
                                                                         
                                                                          led->run_obj.state_change=0;
                                                                          led->run_obj.init_obj->set_obj.loop_cnt--;
                                                                          if(led->run_obj.init_obj->set_obj.loop_cnt!=0)
                                                                          {
                                                                                        led->run_obj.init_obj->led_on();//
                                                                          }
                                                                          else
                                                                          {
                                                                                        led->run_obj.sta_change = led->run_obj.sta_change << 4u;
                                                                                        led->run_obj.sta_change |= LED_STA_END;
                                                                                        led->run_obj.sta_cur = LED_STA_END;
                                                                                  
                                                                          }
                                                                          
                                                          }
                                          }
                                }
                                else
                                {
                                                led->run_obj.sta_change = led->run_obj.sta_change << 4u;
                                                led->run_obj.sta_change |= LED_STA_END;
                                                led->run_obj.sta_cur = LED_STA_END;  
                                }       
                }
                break;
                case LED_STA_END:/*结束*/
                {
                        led->run_obj.init_obj->led_off();//确保最后是关闭的
                        led->run_obj.cur_led_run_flag = 0u;
                        led->run_obj.sta_change = led->run_obj.sta_change << 4u;
                        led->run_obj.sta_change |= LED_STA_IDLE;
                        led->run_obj.sta_cur = LED_STA_IDLE;
                               
                }
                break;
                default:

                break;
               
        }
       
        return (uint8_t)led->run_obj.sta_change;
}

/************************************函数说明**********************************
**形参:略
**返回值:略
**创建者:绍兴科立新科技有限公司
**仅供学习使用,不得用于商业用途
*******************************************************************************/
uint8_t LedIsRun(sLed *led)
{
        return led->run_obj.cur_led_run_flag;
}















#ifndef LED_H
#define LED_H

#include "type.h"


#define CTR_MODE_NOR 0u
#define CTR_MODE_CTR 1u


#define CTR_LED_ON 2u
#define CTR_LED_OFF 3u



#define LED_CALLBACK_BASE_TIME 1u//ms毫秒定义回调函数执行的时间、频率



typedef enum
{
        LED_STA_IDLE=0x00,
        LED_STA_RUN=0x01,
        LED_STA_END        = 0x02
} eLedSta;

typedef struct
{

        uint16_t        led_ontime;      //亮时间
        uint16_t        led_offtime;     //灭时间
        uint16_t        loop_cnt;        //亮灭次数
        uint8_t         ctr_mode;        //控制方式 抢占等待还是其他私有函数执行
}sLedSetObj;

typedef struct
{
    sLedSetObj         set_obj;
        void (*led_init)(void);
        void (*led_on)(void);
        void (*led_off)(void);
}sLedInitObj;






typedef struct
{
                sLedInitObj *init_obj;
                eLedSta         sta_cur;
                uint8_t         sta_change;
                uint32_t    callback_time;
                uint16_t         time_base;
                uint8_t           cur_led_run_flag;
                uint8_t         state_change;
}sLedRunObj;

typedef struct
{               
   sLedRunObj run_obj;

}sLed;






///////////////////////////////////////////////////////////////////

extern void LedObjInit(sLed *led, sLedInitObj init_obj,uint32_t time_callback);                  
extern void LedTimerHandle(sLed *led);      
extern uint8_t LedMainHandle(sLed *led);               

//对外调用接口 1:成功 0:失败 ( on_time off_time ms参数)
extern uint8_t LedCall(sLed *led, uint16_t on_time , uint16_t off_time , uint16_t loop_cnt , uint8_t ctr_mode);
extern uint8_t LedIsRun(sLed *led);


#endif














正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-25 13:41

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表