Hi buddies! In this post, let’s explore the Timer and Counter feature in the Buddy51 board.
Why use a Timer instead of NOP?
In our previous examples, we used NOP-based software delays. However, these are not accurate. To achieve precise timing, we use hardware-based timers and counters.
What is a Timer or Counter?
A timer or counter is a register that increments with each clock pulse. If the pulse is from an external pin, it’s a counter. If it’s from the system clock, it’s a timer. Once it overflows, a flag is set, which we use to take action.
Think of it like an alarm on your phone. When time is up, the alarm rings. Similarly, in the MCU, the flag is set when time is up.
Example: RPM Meter
An RPM meter counts the number of pulses from a proximity sensor in one second. Timer0 acts as the counter, and Timer1 is used for the 1-second delay.
Number of Timers
The Buddy51 has 3 timers:
- Timer0
- Timer1
- Timer2
This can vary depending on the IC manufacturer.
Timer Modes in Buddy51
Buddy51 supports four timer modes: Mode 0, Mode 1, Mode 2, and Mode 3.
- Mode 0: 13-bit timer, max count 8191. Rarely used.
- Mode 1: 16-bit timer, max count 65536. Most commonly used.
- Mode 2: 8-bit auto-reload mode. TL is counter, TH is reload value.
- Mode 3: Split Timer Mode. Timer0 is split into two 8-bit timers. Timer1 is disabled in this mode.
Timer Initialization Steps
- Select Timer and Mode
- Load Timer Value
- Start Timer
- Check Overflow
Step 1: Timer and Mode Selection using TMOD
The TMOD (Timer Mode) register is an 8-bit register used to configure Timer0 and Timer1.
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
Label | GATE1 | C/T1 | M1 | M0 | GATE0 | C/T0 | M1 | M0 |
- GATE: Allows external signal to control timer
- C/T: Selects between Counter (1) and Timer (0)
- M1/M0: Select timer mode
Example: TMOD = 0x01;
configures Timer0 in Mode 1.
Step 2: Load Timer Value
In 16-bit Mode, to generate 50ms delay with 11.0592MHz clock:
- Machine cycle ≈ 1.085 microseconds
- Counts needed = 50,000 / 1.085 ≈ 46080
- Initial value = 65536 – 46080 = 19456 = 0x4C00
So, set:
1 2 | THx = 0x4C; TLx = 0x00; |
Step 3 & 4: Start Timer and Check Overflow
Use TCON (Timer Control Register):
Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
Label | TF1 | TR1 | TF0 | TR0 | IE1 | IT1 | IE0 | IT0 |
- TR0: Start Timer0
- TF0: Timer0 Overflow Flag
When TF0 is set, delay is complete.
Example: RPM Meter using Counter
Sensor input connected to P3.4
(T0 pin). Timer0 is Counter, Timer1 is 1s delay generator.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <8052.h> // Include 8051 microcontroller header #include <stdio.h> // For sprintf function #include "../library/LCD4/LCD4.h" // BuddyKit LCD 4-bit mode library // Function to create approximately 1-second delay using Timer 1 void Delay1Sec() { u8 ms50 = 20; // Loop 20 times for 20 * 50ms = ~1 second while (ms50--) { TH1 = 0x4C; // Set Timer 1 high byte TL1 = 0x00; // Set Timer 1 low byte TR1 = 1; // Start Timer 1 while (!TF1); // Wait until Timer 1 overflows TR1 = 0; // Stop Timer 1 TF1 = 0; // Clear overflow flag } } void main() { u16 count = 0; // To store the number of pulses u8 buff[17]; // Buffer to hold RPM display string u16 rpm = 0; // Variable to hold calculated RPM LCD_Init(); // Initialize LCD LCD_Puts("HI BUDDIES!"); // Display welcome message on LCD TMOD = 0x15; // Timer 1 = Timer Mode, Timer 0 = Counter Mode P3_4 = 1; // INT0 pin (usually used with IR sensor input) while (1) { TH0 = 0x00; // Reset Timer 0 high byte TL0 = 0x00; // Reset Timer 0 low byte TR0 = 1; // Start Timer 0 (count pulses from IR sensor) Delay1Sec(); // Wait for 1 second TR0 = 0; // Stop Timer 0 count = TL0 | (TH0 << 8); // Combine high and low byte for final count rpm = count * 60; // Convert to RPM (60 seconds) sprintf(buff, "RPM: %u", rpm); // Format RPM to string LCD_ClearRow(2); // Clear second row of LCD LCD_Puts(buff); // Display RPM value on LCD } } |
That’s it! Your basic RPM meter using Buddy51 is ready!
What’s Next?
In the next post, we’ll use timer + interrupt to build a real-time application.
Leave Your Reply
You must be logged in to post a comment.