Microcontroller › 8051 › AT89C External timer inputs do not work as regular inputs
- This topic has 3 replies, 3 voices, and was last updated 10 years, 7 months ago by Ashutosh Bhatt.
-
AuthorPosts
-
May 12, 2014 at 6:03 pm #3086Joris DallaireParticipant
Hello,
First post here, from a newbie hobbyist.
I have an atmel AT89C2051 and i can’t get the external timer inputs (T0 and T1) to work as regular inputs. I write 1s to the whole P3 port and all available pins work as expected except those two.
I do use the timers, and they are set in TMOD as timer mode (not counter), so the pins should be available as regular input pins, no?
Any help appreciated.
Joris
May 13, 2014 at 4:44 am #11726SHAH DISHANT H.ParticipantHi,
Ya what you said is perfectly fine and you must get those pins as GPIO.
Can you post ur code so that we can verify ?
May 13, 2014 at 2:33 pm #11727Joris DallaireParticipantHello,
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);
}
May 15, 2014 at 3:47 pm #11732Ashutosh BhattParticipantthere are two timer/counter in 8051
at a time it can work as timer or counter
if T0 you are configuring as timer. it will count internal pulses at 1 MHz
else if you are configurating T0 as counter it will count external pulses (max at 1 MHz)
similar for T1. no need to configure anything else.
-
AuthorPosts
- You must be logged in to reply to this topic.