//**************************************************************************
//* MCU : PIC16F886
//* DATE : 20111003 EDITED BY GARY KAO
//* 轉動可變電阻, 透過A/D 10bit轉換, 取ADRESH 8bit結果, 顯示於RB LED
//**************************************************************************
/*
說明:
此AD解析度是10BIT, 若可變電阻接5V分壓, 則每跳動1 BIT變化0.0048V
5 / 1024 = 0.0048
若設定AD結果靠左, 且只取ADRESH, 忽略ADRESL時, 則每跳動1 BIT變化0.0048 * 4 = 0.0195V
因為ADRESL有3 BIT, 表示每次需經過3次,第4次會進位到ADRESH, ADRESH才會加1
所以若將5V分為5區間, 則判斷式設定如下
1. 0.25V / 0.0195 = 12.8
2. 1.25V / 0.0195 = 64
3. 2.5V / 0.0195 = 128
4. 3.75V / 0.0195 = 192
5. 5V / 0.0195 = 256
*/
#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 main(void)
{
InitIO();
InitAD();
OSCCON = 0x61; // Fosc : 4MHz
GIE = 1;
while(1)
{
GO = 1; // enable ad interrupt
}
}
//*****************
// IO INITIALIZE
//*****************
void InitIO()
{
TRISB = 0x00;
PORTB = 0x00;
TRISC = 0X00;
TRISCbits.TRISC2 = 1; // SET RC2 INPUT
//TRISC = 0X04;
}
//*****************
// A/D INITIALIZE
//*****************
void InitAD()
{
TRISA = 0X01;
ANSEL = 0X01;
ADCON0 = 0X00; // RESET ADCON0
ADCS0 = 1; // OSC : FRC
ADCS1 = 1;
ADON = 1; // ENABLE ADC
ADCON1 = 0X00; // VREF : VSS-VDD
ADFM = 0; // 0 : 左對位
ADRESL = 0X00;
ADRESH = 0X00;
//GIE = 1; // ENABLE GLOBLE INT
PEIE = 1;
ADIE = 1; // ENABLE ADC
}
interrupt void AD_isr()
{
if(ADIF == 1)
{
if(ADRESH <= 13)
{
PORTB = 0X00;
}
else if ( (ADRESH <= 64) && (ADRESH > 13) )
{
PORTB = 0X01;
}
else if ( (ADRESH < 128) && (ADRESH > 64) )
{
PORTB = 0X03;
}
else if ( (ADRESH < 192) && (ADRESH >= 128) )
{
PORTB = 0X07;
}
else
{
PORTB = 0X0F;
}
ADIF = 0;
}
}
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;
}
}
訂閱:
文章 (Atom)