//**************************************************************************
//* MCU : PIC16F886
//* DATE : 20111003 EDITED BY GARY KAO
//* 轉動可變電阻, 透過A/D 10bit轉換, 取ADRESH 8bit結果, 顯示於RB LED
//* 啟動時進入sleep mode, 按下RB4 wake up, 觸發RBIF中斷, 啟動AD (GO = 1), enableRB4INT = 1
//* while(1)判斷enableRB4INT是否為1, 且AD是否轉換完成(GO = 0)
//* 若條件成立, show BAT level, 利用TIMER 0延遲8秒後再進入sleep mode
//**************************************************************************
//* 此程式使用RB中斷喚醒MCU, 沒使用 A/D中斷
//**************************************************************************
/*
說明:
此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 InitTMR0();
void sleep();
void showChargingState();
bit enableRB4INT;
unsigned char TMR0_1ms;
unsigned char TMR0_100ms;
unsigned char TMR0_1s;
void main(void)
{
OSCCON = 0x61; // Fosc : 4MHz
enableRB4INT = 0;
InitIO();
InitAD();
InitTMR0();
TMR0 = 0x06; // TMR0: 6~256 ; 250次
TMR0_1ms = 0;
TMR0_100ms = 0;
TMR0_1s = 0;
RBIE = 1;
GIE = 1;
// GO = 1;
sleep();
while(1)
{
if(enableRB4INT == 1)
{
if(GO == 0) // if A/D completed
{
showChargingState();
T0IE = 1; // ENABLE TIMER0 INT
if(TMR0_1s == 8)
{
PORTBbits.RB0 = 0;
PORTBbits.RB1 = 0;
PORTBbits.RB2 = 0;
PORTBbits.RB3 = 0;
T0IE = 0; // Disable TIMER0 INT
TMR0_1s = 0;
enableRB4INT = 0;
sleep();
}
}
}
}
}
void showChargingState()
{
if(ADRESH < 180) // < 3.5v
{
PORTBbits.RB0 = !PORTBbits.RB0;
PORTBbits.RB1 = !PORTBbits.RB1;
PORTBbits.RB2 = !PORTBbits.RB2;
PORTBbits.RB3 = !PORTBbits.RB3;
DelayMs(200);
//PORTB = 0x0f;
//DelayMs(200);
}
else if ( (ADRESH >= 180) && (ADRESH < 186) ) // 3.51v ~ 3.62v
{
PORTBbits.RB0 = 1;
PORTBbits.RB1 = !PORTBbits.RB1;
PORTBbits.RB2 = !PORTBbits.RB2;
PORTBbits.RB3 = !PORTBbits.RB3;
//PORTB = 0X01;
DelayMs(200);
}
else if ( (ADRESH >= 186) && (ADRESH < 198) ) // 3.63v ~ 3.86v
{
PORTBbits.RB0 = 1;
PORTBbits.RB1 = 1;
PORTBbits.RB2 = !PORTBbits.RB2;
PORTBbits.RB3 = !PORTBbits.RB3;
DelayMs(200);
}
else if ( (ADRESH >= 198) && (ADRESH < 209) ) // 3.87v ~ 4.07v
{
PORTBbits.RB0 = 1;
PORTBbits.RB1 = 1;
PORTBbits.RB2 = 1;
PORTBbits.RB3 = !PORTBbits.RB3;
DelayMs(200);
}
else // > 4.08v
{
PORTB = 0X0F;
}
}
//*****************
// TIMER0 INITIALIZE
//*****************
void InitTMR0()
{
//OPTION_REG = 0X00;
OPTION_REGbits.PS0 = 1; // PRESCALER 1:4; 4us加1, 4us*250 = 1ms
OPTION_REGbits.PS1 = 0;
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()
{
ANSELH = 0X00; // disable AN8~AN13
TRISB = 0x10; // RB4 : INPUT
PORTB = 0x10; // RB4 : INPUT
WPUB = 0X10; // enable RB4 weak pull high
IOCB = 0X10; // enable RB4 interrupt
OPTION_REGbits.nRBPU = 0; // enable weak pull high
OPTION_REGbits.INTEDG = 0; // falling edge interrupt
//TRISB = 0x00;
//PORTB = 0x00;
//TRISC = 0X00;
//TRISCbits.TRISC2 = 1; // SET RC2 INPUT
//TRISC = 0X04;
}
//*****************
// A/D INITIALIZE
//*****************
void InitAD()
{
TRISA = 0X01; // RA0:input
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 INT
}
interrupt void AD_isr()
{
/*if(ADIF == 1)
{
ADIF = 0;
}*/
if(T0IF) // 1ms
{
TMR0_1ms++;
if(TMR0_1ms == 100) // 100ms
{
//PORTBbits.RB0 = !PORTBbits.RB0;
TMR0_100ms++;
if(TMR0_100ms == 10) // 1s
{
//PORTBbits.RB3 = !PORTBbits.RB3;
TMR0_1s++;
//if(TMR0_1s == 3) // 1s * 3 = 3s
// pressed3Sec = 1;
//else
// PORTBbits.RB0 = 0;
TMR0_100ms = 0;
}
TMR0_1ms = 0;
}
T0IF = 0;
}
if(RBIF)
{
if(PORTBbits.RB4 == 0) // RB4 pressed
{
DelayUs(100);
GO = 1; // A/D start
enableRB4INT = 1;
}
RBIF = 0;
}
}
void sleep()
{
#asm
SLEEP
#endasm
}
沒有留言:
張貼留言