應廣單片機價格美麗,性價比高,mini-c好用,適用于消費電子開發。但是案例demo太少了,為了方便大家能夠快速入門。這
里貼出了一份經典PMS150C的點燈程序代碼。不是Hello world!那種,是偏向于實際產品的那種
PMS150通用 OTP 系列
MC150/PMS150是一個10類型、完全靜態,以OTPQ為程序存儲基礎的單片機。它運用RISC的架構基礎使大部分執行指令周期,。
口有D部分指令需要兩個指令周期。PMC150/PMS150內置1KW OTP程序內存以及60字節數據存儲器:另外PMC150/PMS150還提供一個16
立的硬件計數器
不建議使用于AC 阻容降壓供電或有高EFT要求之應用
工作溫度范圍: -20°C ~ 70°C
系統特性
1. 1KW OTP 程序儲存器
2. 60 Bytes 數據儲存器
3. 一個16位定時器
4. 快速喚醒功能
5. 內置高頻 RC 振蕩器(IHRC)
6. 內置Band-gap 硬件模塊輸出 1.20V 參考電壓
7. 6 個IO 引腳具有10mA 電流驅動能力
8. 操作電壓范圍: 2.2V ~ 5.5V
9. 時鐘源:內部高頻震蕩器,內部低頻震蕩器
10. 每個IO 引腳都可設定喚醒功能
11. 8 段LVR 復位設定: 4.1V, 3.6V, 3.1V, 2.8V, 2.5V, 2.2V, 2.0V, 1.8V
12. 1 個外部中斷引腳
CPU 特性
1. 單一處理單元工作模式
2. 提供79 個有效指令
3. 1T(單周期)指令
4. 可程序設定的堆棧指針和堆棧深度
5. 數據存取支持直接和間接尋址模式,用數據存儲器即可當作間接尋址模式的數據指針(index pointer)
6. IO 地址以及儲存地址空間互相獨立
PMS150封裝圖
涉及到的內容有不少,包括應廣單片機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;
1
/*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) )
{
2
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)
{
/*閃燈*/
3
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;
4
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)
5
{
/*保存當前狀態*/
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)
{
6
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;
}
}
popaf;
}