Forum Replies Created
Viewing 1 post (of 1 total)
-
AuthorPosts
-
May 13, 2014 at 2:33 pm in reply to: AT89C External timer inputs do not work as regular inputs #11727
Joris Dallaire
ParticipantHello,
Thank you for the helping hand! Here’s the code. There is a debounce routine in there, but basically when any button connected to P3 is pushed the “State” variable becomes greater than 1. Here the PB_UP and PB_DOWN buttons are set to pins 1 and 0 and it works, but it doesn’t when set to T0 and T1.
Thanks you in advance for your advice.
__sfr __at (0x90) P1;
__sfr __at (0xB0) P3;
__sfr __at (0x89) TMOD;
__sfr __at (0x8A) TL0;
__sfr __at (0x8C) TH0;
__sbit __at (0x8C) TR0;
__sfr __at (0x8B) TL1;
__sfr __at (0x8D) TH1;
__sbit __at (0x8E) TR1;
__sbit __at (0xAF) EA;
/* 0=Disable all interrupts */
__sbit __at (0xA9) ET0;
/* 1=Enable Timer 0 interrupt */
__sbit __at (0xAB) ET1;
/* 1=Enable Timer 0 interrupt */
__sbit __at (0x8F) TF1;
#define PB_DOWN 0 // Bit position of switch in input port
#define PB_UP 1 // Bit position of switch in input port
#define MAX_CHECKS 10 // # checks before a switch is debounced
volatile
unsigned
char
Debounced_State = 0;
// Debounced state of the switches
volatile
unsigned
char
State[MAX_CHECKS];
// Array that maintains bounce status
volatile
unsigned
int
Index;
// Pointer into Switch state array
volatile
unsigned
char
selectedPosition = 0;
static
unsigned
char
maxPosition = 7;
volatile
unsigned
char
freezeLoops = MAX_CHECKS*2;
// Number of loops that the switches are frozen after a press is detected
volatile
unsigned
char
currentFreezeLoop;
// Holds the countdown of loops during the frozen state
unsigned
char
getBtnStatus(unsigned
char
bitPosition) {
// Bit extraction: (x >> lsb) & ~(~0 << (msb-lsb+1))
return
(Debounced_State >> bitPosition) & ~(~0 << 1);
}
void
updateIndex() {
if
(getBtnStatus(PB_DOWN) && selectedPosition > 0) selectedPosition--;
if
(getBtnStatus(PB_UP) && selectedPosition < maxPosition) selectedPosition++;
TF1 = 1;
/* Force Timer 1 overflow to provoque ISR execution */
}
// Service routine called by a timer interrupt
void
debounceSwitches() {
unsigned
int
i=MAX_CHECKS, j=0xFF;
State[Index]=~P3;
//Load status of all switches connected to P3 in a state byte. Inverted switch logic so that a swtch press (0 volts) equals a logic 1
++Index;
do
{ j = j & State; }
while
(--i);
if
(Debounced_State != j) {
/* Change of switch state */
Debounced_State = j;
}
if
(Debounced_State > 0 && !currentFreezeLoop ) {
/* One of P3 pins has changed and the port is "unfrozen" */
currentFreezeLoop = freezeLoops;
/* Reset frozen state counter */
updateIndex();
}
if
(currentFreezeLoop) currentFreezeLoop--; {
/* frozen state, decrement frozen state counter */
}
if
( Index >= MAX_CHECKS ) Index=0;
}
void
ext0(
void
) __interrupt 0 __using 0 {
// External Interrupt 0: Highest priority ISR
}
void
intT0(
void
) __interrupt 1 __using 1 {
// Timer 0 Over?ow: Second highest priority ISR, scans input buttons
debounceSwitches();
TL0=0xDF;
//Load value of 45535 into timer, leaving 20000 ticks ( approx. 10 ms) before next overflow
TH0=0xB1;
}
void
ext1(
void
) __interrupt 2 __using 2 {
// External Interrupt 1: Third highest priority ISR
}
void
intT1(
void
) __interrupt 3 __using 3 {
// Timer 1 Over?ow: Second highest priority ISR
P1=~(1 << selectedPosition);
}
main() {
P3=0xFF;
/* Intitalize all pins of P3 as inputs */
TMOD|=0x1;
/* Timer 0 Mode 1 */
// TMOD|=0x11; /* Both timers in Mode 1 */
TH0=0;
TL0=0;
TL0=0xDF;
//Load value of 45535 into timer, leaving 20000 ticks ( approx. 10 ms) before next overflow
TH0=0xB1;
TR0=1;
/* Start Timer 0 */
ET0=1;
/* Enable Timer 0 */
TL1=0;
TH1=0;
// TR1=1; /* Start Timer 0 */
ET1=1;
/* Enable Timer 0 */
/* Bit or byte addressable. If EA is 0, all interrupts are disabled.
If EA is 1, any interrupt is enabled by setting its bit to 1:
– EA, IE.7: if EA=0, neither interrupt will be acknowledged. If
EA=1, each interrupt source may be individually enabled or disabled.
– ET2, IE.5: timer 2 overflow
– ES, IE.4: interrupt serial port
– ET1, IE.3: Timer 1 overflow
– EX1, IE.2: external interrupt 1
– ET0, IE.1: Timer 0 overflow
– EX0, IE.0: external interrupt 0
*/
EA=1;
/* global interrupt enable */
/* TCON register
• Bit or byte addressable. Bit functions:
– TF1, TCON.7: Flag Timer 1 overflow. Hardware erased when interrupt routine is running
– TR1, TCON.6: Timer 1 control bit. if TR1=1, Timer 1 ON. if TR1=0, Timer1 OFF.
– TF0, TCON.5: Flag Timer 0 overflow. Same as Flag Timer 1 overflow.
– TR0, TCON.4: Timer 0 control bit.Same as for Timer1.
– IE1, TCON.3: Flag for external interrupt 1. Set hardware when external interrupt 1 edge detected; hardware reset when processing interrupt.
– IT1, TCON.2: Interrupt 1 type control bit. If IT1=1, interrupt 1 is triggered
by a falling down edge. If IT1=0, interrupt 1 is triggered by level 0.
– IE0, TCON.1: Flag for external interrupt 0. Set hardware when interrupt edge detected, hardware erased when interrupt processing. */
updateIndex();
// Load initial relay conditions (selected position 0, mute )
while
(1);
}
-
AuthorPosts
Viewing 1 post (of 1 total)