Problem med TMR1/TMR0 och meny... (C/MikroC)
Postat: 18 juli 2007, 13:17:22
Tja.
Försöker knåpa ihop en meny på LCD, men jag har problem med koden, närmare bestämmt TMR1 och TMR0.
Jag kan inte få TMR1 att fungera utan TMR0. Så som koden ser ut nu så fungerar allt, men så fort jag tar bort något som har med TMR0 att göra så fungerar det inte längre. Grejen är att jag använder inte TMR0 i koden (har tagit bort det som använde TMR0). Förstår inte vad det beror på!?
TMR1 använder jag i "void debounceStateMachine(void)".
Ge gärna förslag på hur jag skall förbättra koden! Är mitt första C-program.
PIC:en är en 628A @ 10MHz.
mvh Jonas
Försöker knåpa ihop en meny på LCD, men jag har problem med koden, närmare bestämmt TMR1 och TMR0.
Jag kan inte få TMR1 att fungera utan TMR0. Så som koden ser ut nu så fungerar allt, men så fort jag tar bort något som har med TMR0 att göra så fungerar det inte längre. Grejen är att jag använder inte TMR0 i koden (har tagit bort det som använde TMR0). Förstår inte vad det beror på!?
TMR1 använder jag i "void debounceStateMachine(void)".
Ge gärna förslag på hur jag skall förbättra koden! Är mitt första C-program.
PIC:en är en 628A @ 10MHz.
Kod: Markera allt
#define TRUE 1
#define FALSE 0
void interrupt(void);
void TMRInit(void);
void LCDInit(void);
void menuStateMachine(void);
void debounceStateMachine(void);
char weGotTMR1Interrupt = 0; // glbal var which tells the program (main) if we got TMR1 interrupt.
char PushbuttonUpPushed = FALSE;
enum state1 {bootsState, dustState, invulnState, mercState};
enum state1 menuStateVar = bootsState;
enum state2 {idleState, pressingState, pressedState};
enum state2 debounceStateVar = idleState;
//------------------MAIN--------------------------------------------------------
void main()
{
CMCON = 0b00000111; //Turn comparators off --> pins becomes I/O
TRISA = 0x1f; // inputs
TRISB = 0; // outputs
LCDInit();
TMRInit();
while (1)
{
debounceStateMachine(); // polls button
menuStateMachine();
PushbuttonUpPushed = FALSE;
}
}
//------------------------------------------------------------------------------
void menuStateMachine(void)
{
switch(menuStateVar)
{
case bootsState:
LCD_Out(2,1,"boots");
if(PushbuttonUpPushed == TRUE)
{
menuStateVar = dustState;
}
break;
case dustState:
LCD_Out(2,1,"dust");
if(PushbuttonUpPushed == TRUE)
{
menuStateVar = invulnState;
}
break;
case invulnState:
LCD_Out(2,1,"invuln");
if(PushbuttonUpPushed == TRUE)
{
menuStateVar = mercState;
}
break;
case mercState:
LCD_Out(2,1,"merc");
if(PushbuttonUpPushed == TRUE)
{
menuStateVar = bootsState;
}
break;
}
}
void debounceStateMachine(void)
{
switch(debounceStateVar)
{
case idleState:
if(PORTA.F0 == 1)
{
T1CON.TMR1ON = 1; // start TMR1.
debounceStateVar = pressingState;
}
break;
case pressingState:
if(weGotTMR1Interrupt == 1)
{
T1CON.TMR1ON = 0; // stop TMR1.
if(PORTA.F0 == 1)
{
debounceStateVar = pressedState; //om fortfarande en 1:a
//så registrerar vi ett
} //knapptryck.
else
debounceStateVar = idleState; // om inte en 1:a hoppa
} // tillbaka till början
weGotTMR1Interrupt = 0; // reset variable
break;
case pressedState:
PushbuttonUpPushed = TRUE;
debounceStateVar = idleState;
break;
}
}
void LCDInit(void)
{
LCD_Init(&PORTB); // Initialize LCD connected to PORTB
LCD_Config(&PORTB, 1, 3, 2, 7, 6, 5, 4);
LCD_Cmd(LCD_CLEAR); // Clear display
LCD_Cmd(LCD_CURSOR_OFF); // Turn cursor off
}
void TMRInit(void)
{
// interuppt from TMR0
INTCON.T0IE = 1; // eneble intrrupt on overflow.
OPTION_REG.T0CS = 0; // timer-mode.
// interrupt from TMR1 is init to interrupt after xxms.
PIE1.TMR1IE = 1; // enebles timer1 interrupts
T1CON.TMR1CS = 0; // timer mode
TMR1L = 0b00000000; // räknar upp till 20000-->26ms innan overflow...
TMR1H = 0b00000000; // ... med o.4us per instruktion (10MHz).
T1CON.T1CKPS1 = 1; // prescaler 8 --> 200ms before overflow.
T1CON.T1CKPS1 = 1;
INTCON.GIE = 1; // eneble global interrupt.
}
void interrupt(void)
{
// TMR0 overflow interrupt. on TMR0 interrupt TOIF is set.
if(INTCON.T0IF == 1)
{
INTCON.T0IF = 0; // reset flag
}
// TMR1 overflow interrupt.
if(PIR1.TMR1IF == 1)
{
weGotTMR1Interrupt = 1;
TMR1L = 0b00000000; // reloed TMR1.
TMR1H = 0b00000000; //
T1CON.T1CKPS1 = 1; // prescaler is reset when writing to TMR1L/H
T1CON.T1CKPS1 = 1;
PIR1.TMR1IF = 0; // reset flag
}
//INTCON.GIE = 1; // Global interrupt is reset after return?
}