可复用性程序设计(电源管理)

每次慌慌张张码完一段代码,总是感觉惨不忍睹。但是进度紧,没办法只能想着调好了再来整理,但是整下项目折腾完了,人都筋疲力尽了,又懒得整理了。所以每隔一年半载看以前的代码都觉得是一堆垃圾。

下面找了个简易的电源管理的模块开刀,试着将通用的部分提取出来。

这个是未做处理的文件,我们一般也是按正常的逻辑来编码。

#include "MKL26Z4.h"
#include "bat.h"
#include "err.h"
#include "ntc.h"
#include "Events.h"
#include "OLED_96X32.h"

extern void (*display_array[])(void);

void bat_manage_init(void)
{
    SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;

    //FGPIOB_PDDR &= ~(1<<16);  // Configure as input
    GPIOB_PDDR &= ~(1<<16);  // Configure as input

    PORTB_PCR16 = (PORT_PCR_MUX(1)
                  | PORT_PCR_PE_MASK
                  | PORT_PCR_PS_MASK);
}

void bat_manage_main_thread(void)
{
    unsigned char iFun=0;
    static unsigned char bat_charge_cmplt=0;
    static unsigned char bat_charge_pass=0;
    static unsigned char old_disp_save_cmplt=0;
    static unsigned char old_disp_resume_cmplt=0;
    static unsigned char curr_disp_load_cmplt=0;

    static void (*pFunSave[FUN_MAX])(void);

    if(hw_adc_ave(9,16,20)< BAT_PRE_VALUE)
    {
      bat_charge_cmplt = 0;
    }
    else
    {
      bat_charge_cmplt =1;
    }
    //接上充电插座
    if(!(GPIOB_PDIR&(1<<16)))
    {
         //开始充电
         if(!bat_charge_cmplt)
         {
            //保存以前的显存
            if(!old_disp_save_cmplt)
            {
                for(iFun = 0;iFun< FUN_MAX;iFun++)
                {
                    pFunSave[iFun]=display_array[iFun];
                }
                old_disp_save_cmplt = 1;
            }

            //加载当前的显存
            if(!curr_disp_load_cmplt)
            {
                for(iFun = 0;iFun< FUN_MAX;iFun++)
                {
                    display_array[iFun] = NULL;
                }
                display_array[5] = DisplayBatCharge;
                curr_disp_load_cmplt = 1;
            }

         }
         //已经充满
         else
         {

         }

         bat_charge_pass = 1;
    }
    //没有充电
    else
    {
        //已经冲过电了
        if(bat_charge_pass)
        {
            //恢复以前的显存
            if(!old_disp_resume_cmplt)
            {
                for(iFun = 0;iFun< FUN_MAX;iFun++)
                {
                    display_array[iFun]=pFunSave[iFun];
                }
                old_disp_resume_cmplt = 1;
            }
            bat_charge_pass = 0;

            bat_charge_cmplt = 0;
            old_disp_save_cmplt = 0;
            curr_disp_load_cmplt = 0;
            old_disp_resume_cmplt = 0;
        }
        //没冲过电
        else
        {

        }
    }

}

瞄了一眼上面代码的逻辑,发现锂电池充电都只有这四个状态:

1)正在充电:a、还未充满       b、已经充满

2)没有充电:a、已经冲过电了  b、没有冲过电

于是公共部分就是4个状态,提取如下:

bat.h

#ifndef BAT_H
#define BAT_H

#ifndef FUN_MAX
  #define FUN_MAX  5
#endif

#ifndef BAT_GPIO
    #define BAT_GPIO 0//GPIOB_PDIR&=(1<<16)
#endif

#ifndef NULL
  #define  NULL   0x00u
#endif

class bat
{
public:
    bat();
    inline void bat_manage_init(void);
    void bat_monit();
    void bat_manage_main_thread(void);
    void bat_charge_cmplt_callback();
    void bat_charge_not_cmplt_callback();
    void bat_charge_pass_callback();
    void bat_charge_not_pass_callback();
private:
    unsigned char bat_charge_cmplt;
    unsigned char bat_charge_pass;

};

bat.cpp

#include "bat.h"

bat::bat()
{
    bat_manage_init();
}

void bat::bat_manage_init()
{}

void bat::bat_monit()
{
    bat_charge_cmplt = 0;
    bat_charge_pass = 0;
}

void bat::bat_charge_cmplt_callback()
{}

void bat::bat_charge_not_cmplt_callback()
{
}

void bat::bat_charge_pass_callback()
{
}

void bat::bat_charge_not_pass_callback()
{}

void bat::bat_manage_main_thread(void)
{
    bat_monit();
    //接上充电插座
    if(!BAT_GPIO)
    {
         //开始充电
         if(!bat_charge_cmplt)
         {
             bat_charge_not_cmplt_callback();
         }
         //已经充满
         else
         {
            bat_charge_cmplt_callback();
         }
    }
    //没有充电
    else
    {
        //已经冲过电了
        if(bat_charge_pass)
        {
            bat_charge_pass_callback();
        }
        //没冲过电
        else
        {
            bat_charge_not_pass_callback();
        }
    }
}

一眨眼,代码从C变成C++了,别纠结了,你可以把C++的Class改成C的Struct,Class就是一个带权限管理的Struct。
把公共部分的4个状态提取出来作为一个基类,充电过程中需要定制化处理的部分改造成4个状态的回调函数。

下次要用到锂电池充电管理就可以直接在这个基类的基础上继承一个派生类,重载这四个回调函数即可!

    void bat_charge_cmplt_callback();
    void bat_charge_not_cmplt_callback();
    void bat_charge_pass_callback();
    void bat_charge_not_pass_callback();

这个代码的实例在网盘里,感兴趣的可以下载debug耍耍,http://pan.baidu.com/s/1VCy6 ,用的QT4.8.5来调试的。程序跟平台无关,随便用什么编译环境都可以。

可复用性程序设计(电源管理)

时间: 2024-08-07 00:18:03

可复用性程序设计(电源管理)的相关文章

Android:PowerManager类 电源管理

PowerManager类用于对设备电源状态进行管理:PowerManager.WakeLock类用于保持设备常亮:Android中通过各种Lock锁对电源进行控制,需要注意的是加锁和解锁必须成对出现. 使用Activity的生命周期,以调用保持屏幕常亮和释放屏幕常亮动作. /** * <功能描述> 保持屏幕常亮 * * @return void [返回类型说明] */ private void keepScreenWake() { // 获取WakeLock锁,保持屏幕常亮 mPowerMa

(7)MSP430F5529 电源管理模块

我觉得电源管理与监控是一个很复杂很难掌控的部分,不仅涉及到到源模式的选择,还牵扯到复杂的中断.以及中断如何处理等等.虽然学好这一部分对实现降低功耗的目的很有帮助,但对于目前的我们来说貌似“功耗”一词还稍微远了点.此外,这部分控制对防止和处理供电意外( (过高过低等)的发生很有帮助,不过貌似这个开发板如果不独立拿来做项目而只是接在电脑USB供电的话,一般也不会有什么问题.所以,我也只打算简单学一下. I/O口和所有模拟单元包括晶振在内都由DVCC供电.内存(flash和RAM)和数字单元由核心电压

linux驱动程序之电源管理 之linux休眠与唤醒(2)

在Linux中,休眠主要分三个主要的步骤:(1)冻结用户态进程和内核态任务:(2)调用注册的设备的suspend的回调函数:(3)按照注册顺序休眠核心设备和使CPU进入休眠态.       冻结进程是内核把进程列表中所有的进程的状态都设置为停止,并且保存下所有进程的上下文.当这些进程被解冻的时候,他们是不知道自己被冻结过的,只是简单的继续执行.如何让Linux进入休眠呢?用户可以通过读写sys文件/sys /power/state 是实现控制系统进入休眠.比如: # echo standby >

linux驱动程序之电源管理之标准linux休眠与唤醒机制分析(一)

1. Based on linux2.6.32,  only for mem(SDR) 2. 有兴趣请先参考阅读: 电源管理方案APM和ACPI比较.doc Linux系统的休眠与唤醒简介.doc 3. 本文先研究标准linux的休眠与唤醒,android对这部分的增改在另一篇文章中讨论 4. 基于手上的一个项目来讨论,这里只讨论共性的地方 虽然linux支持三种省电模式:standby.suspend to ram.suspend to disk,但是在使用电池供电的手持设备上,几乎所有的方案

linux驱动程序之电源管理之linux的电源管理架构(3)

设备电源管理 Copyright (c) 2010 Rafael J. Wysocki<[email protected]>, Novell Inc. Copyright (c) 2010 Alan Stern[email protected] ************************************************************* 本文由DroidPhone翻译于2011.8.5 ***************************************

ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现

ARM linux电源管理——Cortex A系列CPU(32位)睡眠和唤醒的底层汇编实现 承接 http://www.wowotech.net/pm_subsystem/suspend_and_resume.html Linux电源管理(6)_Generic PM之Suspend功能一文中的下图. 本文主要分析平台相关的CPU睡眠和唤醒,即下电和上电流程,以及ARM底层汇编代码实现. 内核版本:3.1.0               CPU:ARM Cortex-A7 1 平台相关函数执行流程

【翻译】树莓派2:关闭无线网卡电源管理功能

原文链接:http://www.modmypi.com/blog/disable-wifi-power-management 现象: 树莓派2使用usb无线网卡时,有时ssh会自动断开,这种情况可能是由于启用了电源管理功能, 无线网卡在空闲时会自动关闭. 运行iwconfig,观察Power Management状态,如果为on则需要修改. 解决: 修改配置文件: sudo nano /etc/network/interfaces 在无线网卡(一般是wlan0)中添加一句 wireless-po

linux驱动程序之电源管理之Run-time PM 详解(4)

Run-time PM. 每个device或者bus都会向run-time PM core注册3个callback struct dev_pm_ops { ... int (*runtime_suspend)(struct device *dev); int (*runtime_resume)(struct device *dev); int (*runtime_idle)(struct device *dev); ... }; 每个device或者bus都会有2个计数器,一个是device的u

linux驱动程序之电源管理之新版linux系统设备架构中关于电源管理方式的变更

新版linux系统设备架构中关于电源管理方式的变更 based on linux-2.6.32 一.设备模型各数据结构中电源管理的部分 linux的设备模型通过诸多结构体来联合描述,如struct device,struct device_type,struct class, struct device_driver,struct bus_type等. @kernel/include/linux/devices.h中有这几中结构体的定义,这里只列出和PM有关的项,其余查看源码: struct d