zoukankan      html  css  js  c++  java
  • 美容仪器IPL激光脱毛仪程序设计

    今日再次把几年前做过的脱毛仪拿出来,重新换了个8051的更便宜的单片机做了一遍,重复是最没有意义的,做的更快更好,才有意义,所以我综合了近年来编程方面的心得,特意记下来,形成总结文档,既是抛砖引玉,也是自我提高。 我常常思考,怎么样才能提高代码复用,像高级语言那样,基本上调用一些接口就可以了,驱动和应用分离,这种思路就可以实现。 开局一张图,内容全靠吹

    在这个功能多样,杂散的局面下,我综合采取了面向对象+模块化+状态机+分层封装的方法,下面分别总结下。

    • 状态机

        最核心的部分就是复杂的升压和出光了。要求是额定功率下最快的速度升压,出光之前要稳住电压400V左右(根据档位)。此时还有自动模式和手动模式,根据设置和皮肤触摸情况来出光。 状态机切换程序原则上只做状态的切换,不要做功能上的实现。功能方面另外单独做个函数去实现。 主题的状态机就是:

     1 //系统状态
     2  enum systermstate
     3 {
     4   SYSERROR, //系统错误
     5   SYSIDLE, //待机
     6   AGINGMODE, //老化模式
     7   NOGETVOL, //未满电,升压
     8   GETVOL,   //满电待出光
     9   SHINING, //出光
    10   AGINGDONE, //老化模式完成
    11   LIFEAPANREDUCE, //出光后寿命减
    12 };
    13 //----------------------------------------------------------------------
    14 // Function: static void sysStateDispatch(void) 
    15 // Description:
    16 // 状态机切换
    17 //-------------------------------------------------------------------
    18 static void sysStateDispatch(void) //
    19 {
    20   switch (sysState)
    21   {
    22   case SYSERROR: //系统错误SYSERROR
    23   { 
    24     PWM1SetdutyCycle((UINT8)0); 
    25   }
    26   break;
    27    case SYSIDLE: //待机
    28   { 
    29     PWM1SetdutyCycle(0); 
    30     if (keyPowerLongFlag) // 开机键
    31     {
    32       keyPowerLongFlag = 0;
    33       sysState = NOGETVOL;
    34       PWM1ChargeInit();
    35       timeOuts = 0;
    36       timeOutsConts = 0;
    37       pwm1DutyCycle = 13;
    38     }
    39   }
    40   break;
    41   case NOGETVOL: //升压
    42   {
    43     timeOuts++;
    44     if (timeOuts > 30) //
    45     {
    46       timeOuts = 0;
    47       timeOutsConts++;
    48       adcSelectADCCh(POWER_I_CHA);
    49       if(gadcValue < 80)
    50      {
    51       pwm1DutyCycle++;
    52      }
    53     }
    54     PWM1SetdutyCycle(pwm1DutyCycle);      adcSelectADCCh(HIGHVOL);
    55     if ((timeOutsConts > 80) ||(gadcValue > ADCMAX[gearAdjustment])) 时间和电压综合判断
    56     {
    57       timeOuts = 0;
    58       timeOutsConts = 0;
    59       pwm1DutyCycle = 0;
    60       //PWM1dutyCycle((UINT8)0); //测试
    61       sysState = GETVOL; //电压升满,去发射    
    62  }
    63   }
    64   break;
    • 模块化:

           虽然状态机囊裹了几乎程序所有的状态,理论上所有的功能都可以在状态机哈函数实现,但是我还是强烈建议分开实现,目的是为了程序可读性,方便维护。例如一个简单的灯光只是,我本来是在状态机函数去做的,后来我还是独立出来了,其中sysState 是状态机变量:

     1 //-----------------------------------------------------------------------------
     2 // Function: static void ledtask(void)
     3 // Description:
     4 // 指示灯任务,在每个任务下的表现。 在100Ms轮询事件里调用
     5 //-----------------------------------------------------------------------------
     6  static void ledtask(void)
     7 {
     8   if (sysState == SYSERROR || sysState == AGINGDONE || (sysState == GETVOL && !touchIn)) //异常或者测试完成后
     9   {
    10     timeOuts++;
    11     if (timeOuts > ((sysState == SYSERROR) ? 1 : 6))
    12     {
    13       timeOuts = 0;
    14       greenled = !greenled; //指示灯闪烁
    15     }
    16   }
    17   if (sysState == SYSIDLE || sysState == SYSIDLEPRE || sysState == NOGETVOL) //异常或者测试完成后
    18   {
    19     greenled = 0;
    20   }
    21   if ((sysState == GETVOL && touchIn) || sysState == SHINING) // 满电和出光
    22   {
    23     greenled = 1;
    24   }
    25 }

    如此一来,就把指示灯独立出来了,客户更改了需求,可以快速更改!否则会有啥情况,是不是你得全局搜索这个led,然后满大街的去修改? 其他的比如风扇控制,放电控制,等等都独立出来,依据状态去改变。

    • 分层封装:

          以断码屏为例,断码屏驱动芯片是HT1621B,最终是需要把相关数据传送在HT1621。那么此时,驱动层和应用层应该独立,只保留一个接口来调用即可。 接口类型声明:

    1 typedef struct { 
    2    void (*Init)(void); //初始化
    3 void (*sendCmd)(unsigned char); //发命令
    4    void (*writeData)(unsigned char addr, unsigned char xdata *buf, unsigned char cnt); //更新显示数据 
    5 }HT1621funs_t;
    6 HT1621funs_t HT1621funs;接口类型定义:

    在底层驱动文件HT1621Dri.c里面定义好每一个驱动函数:

    1 static void HT1621B_SendCmd(unsigned char command)
    2 static void HT1621B_SendBit(unsigned char ddata, unsigned char cnt)
    3 。。。

    在应用层文件diaplcd.c中,只需要调用: HT1621funs.writeData(0, bufferDisp.Icon_buf, 8); //刷新数据 即可。

    • 面向对象:

           还是以HT1621为例,如果下次换成了HT1902(假设),可能驱动有所不同,此时再实例化一个: HT1621funs_t HT1902funs; 实例化的时候,使用1902的驱动去实例化即可,接口HT1621funs_t类型还是不变。

     1 //-----------------------------------------------------------------------------------------
     2 //函数名称:void HT1902funsInit(void)
     3 //功能描述: HT1902实例化接口成员函数
     4 //说 明:初始化后,其他文件只需要调用HT1902funs结构体成员函数即可
     5 //-----------------------------------------------------------------------------------------
     6 void HT1902funsInit(void)
     7 {
     8 HT1902funs.Init = HT1902_Init; //初始化
     9 HT1902funs.sendCmd = HT1902_SendCmd;//发命令
    10 HT1902funs.writeData = HT1902_WriteData;//更新显示数据 
    11 } 

    以上,基本上说完了使用到的方法,思想,细节方面欢迎讨论。综合采用这些编程思想,基本可以做到既快又好的完成项目开发或者修改需求。稳定性也得到充分的保证。

    接下来我尝试移植RTThread到此项目上,目的是在状态复杂的项目里面,多使用分时系统,以应对更复杂的需求。 欢迎交流,交流技术和项目合作均可。 

    专业提供PCBA设计,软件设计。

            这里美容仪器市场上一般有的功能,这里都能实现,常用的市场上这些美容类的产品,这里开发周期短,最快一到两周出样,配合您的idea设计,配合不错的话,一般一个月内可以上市。

    市场上能找到美容类的方案板,我们这里都可以开发,市场上面找不到的板,我们这里也可以快速开发,这个世界快鱼吃慢鱼,抓住机会,美容仪器方案开发,选专业的我们,期待与您合作!

    我们的合作模式:

    1、和客户电话,面谈,电子联络方式确定开发电路板的规格及2D图等资料

    2、签订开发合同,根据客户的产品难易程序收取一定的诚意金。

    3、开发产品,软硬件开发,制作样品,客户确认或复验至合格。

    4、以上视开发阶段完成,客户提出需求,订制PCBA

    5、PCBA按客户需求出货,出货一般到20K无条件退还诚意金。

  • 相关阅读:
    机器语言 汇编语言 C C++ Java C# javaScript Go 编译型语言 解释型语言
    计算机历史(二战前)
    可维护性组件的编写原则
    the lasted discuss about h5 optimize
    The last discussion about the inherit
    The last discussion about the prototype
    font-size line-height vertual-align的复杂关系
    vertical-align
    retina屏 适配问题
    XMLHttpRequest2.0的进步之处
  • 原文地址:https://www.cnblogs.com/zhihui-3669/p/13525430.html
Copyright © 2011-2022 走看看