2011年10月24日 星期一

TIMER0



//**************************************************************************
//*  MCU : PIC16F886
//*  DATE : 20111003 EDITED BY GARY KAO
//*  建立100ms , 1s 與 10s的TIMER0 中斷, 輸出到RB LED顯示
//**************************************************************************

#include <pic.h>
#include "DELAY.H"

// CONFIG
//__CONFIG(FOSC_INTRC_NOCLKOUT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & BOREN_OFF & DEBUG_ON & CPD_OFF &LVP_ON&WRT_OFF&FCMEN_OFF&IESO_OFF&CP_OFF&BOR4V_BOR21V);
__CONFIG (FOSC_INTRC_CLKOUT & WDTE_OFF & PWRTE_OFF & MCLRE_ON & CP_OFF & CPD_OFF & BOREN_ON & IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_ON);
__CONFIG (BOR4V_BOR21V & WRT_OFF);

void InitIO();
void InitAD();
void InitTMR0();

unsigned char a;
unsigned char TMR0_100ms;
unsigned char TMR0_1s;
unsigned char TMR0_10s;

void main(void)
{
InitIO();

InitTMR0();
//PORTB = 0X03;
//OSCCON = 0x61; // Fosc : 4MHz
OSCCON = 0X71; // 8MHz
/* if<PS2-PS0> SET 011, 預除器1:16, 表示當osc為4MHz時, 每16us TMR0加1
若要4ms時, TMR0產生溢位: 4ms/16us = 250 , 256-250=6
所以TMR0初值要設定為6,表示TMR0由6開始遞增, 遞增到256時觸發中斷
剛好為4ms
*/

/* 若Fosd : 8MHz, 表示 1 / (8Mhz/4) = 0.5us為一個指令週期,
預除器1:8,表示每 8 * 0.5us = 4us加1
若TMR0初值設定為6, 表示TMR0由6開始遞增, 遞增到256時觸發中斷, 總共遞增250次 (256-6)
所以觸發中斷時間為 4us * 250 = 1ms


*/
TMR0 = 0x06;

/* 如何產生1s的計時中斷?
1s / 4ms = 250
在中斷程式中判斷, 當第250次中斷發生時也是1s時間到了
此時再去執行真正想做的動作
*/
TMR0_100ms = 0;
TMR0_1s = 0;
TMR0_10s = 0;

//DelayMs(50); // delay 100ms @ 4MHz
GIE = 1;


while(1)
{


}
}

//*****************
//  TIMER0 INITIALIZE
//*****************
void InitTMR0()
{
//OPTION_REG = 0X00;
OPTION_REGbits.PS0 = 0; // PRESCALER 1:8
OPTION_REGbits.PS1 = 1;
OPTION_REGbits.PS2 = 0;
OPTION_REGbits.PSA = 0; // 0: TIMER0 ; 1: WDT
OPTION_REGbits.T0SE = 1; // 一般指clock由RA4/T0CKI輸入時
// 0:正緣觸發  ;  1:負緣觸發

OPTION_REGbits.T0CS = 0; // 0:TIMER(clock週期與指令週期相同)
// 1:COUNTER(clock由RA4/T0CKI輸入)

T0IE = 1; // ENABLE TIMER0 INT

}

//*****************
//  IO INITIALIZE
//*****************
void InitIO()
{

TRISB = 0x00;
PORTB = 0x00;

TRISC = 0X00;
TRISCbits.TRISC2 = 1;  // SET RC2 INPUT
//TRISC = 0X04;
}


interrupt void AD_isr()
{
if(T0IF)
{
TMR0_100ms++;
if(TMR0_100ms == 100)
{
PORTBbits.RB0 = !PORTBbits.RB0;
TMR0_100ms = 0;

TMR0_1s++;
if(TMR0_1s == 10) // 100ms * 10 = 1s
{
PORTBbits.RB1 = !PORTBbits.RB1;
TMR0_1s = 0;

TMR0_10s++;
if(TMR0_10s == 10) // 1s * 10 = 10s
{
PORTBbits.RB2 = !PORTBbits.RB2;
TMR0_10s = 0;
}

}

}



T0IF = 0;

}
}

沒有留言:

張貼留言