天天看點

PMS150C應廣單片機開發案例

PMS150C應廣單片機開發案例

   應廣單片機價格美麗,成本效益高,mini-c好用,适用于消費電子開發。但是案例demo太少了,為了友善大家能夠快速入門。這裡貼出了一份經典PMS150C的點燈程式代碼。不是Hello world!那種,是偏向于實際産品的那種。

涉及到的内容有不少,包括應廣單片機PMS150C:

1.端口輸入輸出配置

2.Tmr16中斷配置(systick),倒計時

3.按鍵檢測,包括防抖,可以用于長按鍵檢測

4.低功耗,睡眠配置

5.喚醒

6.系統時鐘配置,系統時鐘切換

7.看門狗應用

8.狀态機應用

其他比如PMS152,PMS132設定也類似,希望大家喜歡!

#include    "extern.h"

#define     HIGH    1

#define  LOW    0

#define DISABLE 0

#define ENABLE 1

#define EMPTY 0

#define FULL 1

#define ON 1

#define OFF 0

#define LED_OPEN 0

#define LED_FLASH 1

#define LED_BREATH 2

#define LED_CLOSE  3

//#define RUN_TMR  60000

/*機關 ms*/

#define RUN_TMR     15000

#define LOW_POW_TIMING_TMR  3000

BIT     LED_G           :        PA.3;

BIT     KEY_HIT            :        PA.4;

#define KEY_DEBOUNCE_CNT  20

#define KEY_LONG_PRESS_TIMER 1200

#define GRE_LED_FLASH  {if(LED_G){LED_G=0;}else{ LED_G=1;}}

/*計數值Cinit*/

word ucFlashTmrCnt;

/*cinit*/

BIT ubMsFlag; 

/*cinit*/

BIT  ubEnLedFlash; 

/*cinit*/

bit ubMod;

byte ucSysSt;

//byte ucLedPwmDt;

/*定時時間是否到了cinit*/

bit     FLAG_NMS;

/*計數值cinit*/

byte    count;

/*定時器初始化cinit*/

word    T16COUNTER;

Eword ueLowPowAltTm;

byte ucKeyHitHigtCnt;

byte ucKeyHitLowCnt;

byte ucKeyHitSt;

byte ucKeyHitBak;

word usKeyHitLoPreCnt;

word usKeyHitLoPreCntSet;

bit ucKeyHitPreSt;

byte ucLedSt;

void UpDateLedSt(void);

/***************************************/

void    TIME16_Init(void)

{

    /*計數值清零*/

    T16COUNTER    =488;

    /*ms标記reset*/

    FLAG_NMS    =0;

    /*使能定時器*/

    $    INTEN    T16;

    /*關中斷*/

    INTRQ        =    0;

    /*停止定時器*/

       T16M.5        =0;               

    STT16 T16COUNTER;

    /*計算方法16M/*/

    $    T16M    IHRC,/1,BIT11;     

}

void StartLowPowTmr(void)

{

    ueLowPowAltTm=RUN_TMR;

}

/*低功耗*/

void LowPow(void)

{

    /*退出功能則進入低功耗*/

   if((!ueLowPowAltTm) )

   {

           ubEnLedFlash=0;

           GRE_LED_OFF;

        wdreset;

        /*IHRC ->ILRC,關看門狗*/

        CLKMD=0xf4;

        /*禁用IHRC*/

        CLKMD.4=0;

        while(1)

        {

             /*低功耗*/

             STOPSYS;

             /*有按鍵按下,充電和按鍵喚醒*/

              if(KEY_HIT==0)

              { 

                    /*退出低功耗*/

                    break; 

              }

        }

        /*ILRC->IHRC ,

             b7:5@001=IHRC/8,

             b4@1=IHRC

             b3@1=模式1

             b2@ 1=ILRC啟動

             b1@ 1=看門狗開啟

             b0@ 0=Pa5;

             模式口1;開看門狗*/

        CLKMD=0b001_1_1110;

        ucLedSt=1;

        ucSysSt=LED_CLOSE;

        StartLowPowTmr();

    }

}

void UpdateLedTmr(void)

{

   /*使能,閃燈*/    

   if(ubEnLedFlash)

   {

         /*1ms進行一次計數*/

        ucFlashTmrCnt++;

        if(ucFlashTmrCnt>250)

        {

            ucFlashTmrCnt=0;

            /*标記*/

            ubMsFlag=1; 

        }

   }

}

/*閃燈*/

void FlashLed(void)

{

    /*定時時間到*/

    if(ubMsFlag)

    {

        /*閃燈*/

        GRE_LED_FLASH;

        ubMsFlag=0;

    }

}

/*端口檢測*/

void ResetKeyTmr(void)

{

    if(KEY_HIT)

    {

        ucKeyHitHigtCnt=KEY_DEBOUNCE_CNT;

    }

    /*目前狀态為0*/

    else

    {

        ucKeyHitLowCnt=KEY_DEBOUNCE_CNT;

    }

}

/*1ms任務函數*/

void UpDateKeyTmr(void)

{

      /*重新設定計數值*/ 

     ResetKeyTmr();

      /*KeyHit高電平計數值*/

     if(ucKeyHitHigtCnt)

     {

         ucKeyHitHigtCnt--;

        if(!ucKeyHitHigtCnt)

        {

            /*高電平倒計時完成說明目前為低*/

            ucKeyHitSt=LOW;

        }

     }

     /*高電平計數值為0*/

     else

     {

         usKeyHitLoPreCnt++;

        /*做飽和加*/

        if(usKeyHitLoPreCnt>20000)

        {

            usKeyHitLoPreCnt=20000;

        }

        if(usKeyHitLoPreCnt==usKeyHitLoPreCntSet)

        {

            /*10s 鐘定信号*/

            ucKeyHitPreSt=1;

        }

     }

      /*KeyHit低電平計數值*/

     if(ucKeyHitLowCnt)

     {

         ucKeyHitLowCnt--;

        if(!ucKeyHitLowCnt)

        {

            /*低電平倒計時完成,說明目前為高*/

            ucKeyHitSt=HIGH;

            usKeyHitLoPreCnt=0;

            ucKeyHitPreSt=0;

        }

     }

}

void MsTask(void)

{

    /*按鍵*/

    UpDateKeyTmr();

    UpdateLedTmr();

    FlashLed();

    /*低功耗定時器*/

    if(ueLowPowAltTm)

    {

        ueLowPowAltTm--;

    }

    LowPow();

}

void UpDateLedSt(void)

{

    ucSysSt++;

    if(ucSysSt>1)

    {

        ucSysSt=0;

    }

    switch(ucSysSt)

    {

        /*開閃爍*/

        case 0:

            ubEnLedFlash=1;

            break;

        /*關燈*/

        case 1:

            ueLowPowAltTm=LOW_POW_TIMING_TMR;

            ubEnLedFlash=0;

            /*關燈,關閃爍*/

            GRE_LED_OFF;

            /*關燈*/

            break;

        default:

        break;

    }

}

/*狀态切換*/

void GetKeySt(void)

{

   /*狀态有變化*/

   if(ucKeyHitSt!=ucKeyHitBak)

   {

          /*儲存目前狀态*/

          ucKeyHitBak=ucKeyHitSt;

       if(!ucKeyHitSt)

       {    

             /*更新倒計時*/

                StartLowPowTmr();

             /*狀态切換*/

             UpDateLedSt(); 

       }

   }

}

/*端口狀态初始化*/

void KeyAppInit(void)

{

    if(KEY_HIT)

    {

        ucKeyHitSt=HIGH;

        ucKeyHitBak=HIGH;

    }

    else

    {

        ucKeyHitSt=LOW;

        ucKeyHitBak=LOW;

    }

   ucKeyHitHigtCnt=KEY_DEBOUNCE_CNT;

   ucKeyHitLowCnt=KEY_DEBOUNCE_CNT;

   usKeyHitLoPreCnt=0;

   ucKeyHitPreSt=0;

}

void    FPPA0 (void)

{

    .ADJUST_IC    SYSCLK=IHRC/8, IHRC=16MHz, VDD=3.0V;

    $ CLKMD IHRC/8,En_IHRC,En_ILRC,En_WatchDog;

    /**/

    .delay 40000;

    $  LED_G    OUT,HIGH;          

    $  KEY_HIT    IN,PULL;   

    TIME16_Init();

    KeyAppInit();

    ucLedSt=1;

    ubMsFlag=0;

    ubEnLedFlash=0;

    /*長按鍵時間*/

    usKeyHitLoPreCntSet=3000;

    ucSysSt=LED_CLOSE;

    engint;

    while (1)

    {

            wdreset;

         /*1ms定時時間到*/

         if ( FLAG_NMS )

         {

            MsTask();

            /*清除标記*/

            FLAG_NMS=0;

        }

        /*取得按鍵狀态*/

        GetKeySt();

    }

}

void    Interrupt ( void )

{

    pushaf;

    if ( Intrq.T16 )  

    {

        Intrq.T16    =    0;

        STT16 T16COUNTER;

        if ( count>0 )

        {

            count--;

        }

        else

        {

            count   =   9;

            /*1ms*/

            FLAG_NMS=   1;      

        }

    }