{
Cnt++; // Increment Cnt
if (Cnt == 100) Cnt = 0; // Count between 0 and 99
Delay_ms(1000); // Wait 1 second
}
}
Figure 6.36: Program of the project
Inside the interrupt service routine, register TMR0L is reloaded, TMR0 interrupts are reenabled, and the timer interrupt flag is cleared so that further timer interrupts can be generated. The display digits are then updated alternately. A variable called Flag is used to determine which digit to update. Function Display is called, as in Project 6, to find the bit pattern to be sent to PORTC.
Modifying the Program
In Figure 6.36 the display counts as 00 01…09 10 11…99 00 01… (i.e., the first digit is shown as 0 for numbers less than 10). The program could be modified so the first digit is blanked if the number to be displayed is less than 10. The modified program (called SEVEN5.C) is shown in Figure 6.37. Here, the first digit (MSD) is not enabled if the number to be displayed is 0.
/************************************************
Dual 7-SEGMENT DISPLAY COUNTER
==============================
In this project two common cathode 7-segment LED displays are
connected to PORTC of a PIC18F452 microcontroller and the
microcontroller is operated from a 4MHz resonator. Digit 1 (left
digit) enable pin is connected to port pin RB0 and digit 2
(right digit) enable pin is connected to port pin RB1 of the
microcontroller. The program counts up from 0 to 99 with one
second delay between each count.
The display is updated in a timer interrupt service routine at
every 5ms.
In this version of the program the first digit is blanked if the
number is 0.
Author: Dogan Ibrahim
Date: July 2007
File: SEVEN5.C
************************************************/
#define DIGIT1 PORTB.F0
#define DIGIT2 PORTB.F1
unsigned char Cnt = 0;
unsigned char Flag = 0;
//
// This function finds the bit pattern to be sent to the port to display a number
// on the 7-segment LED. The number is passed in the argument list of the function.
//
unsigned char Display(unsigned char no) {
unsigned char Pattern;
unsigned char SEGMENT[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,
0x7D,0x07,0x7F,0x6F};
Pattern = SEGMENT[no]; // Pattern to return
return (Pattern);
}
//
// TMR0 timer interrupt service routine. The program jumps to the
// ISR at every 5ms.
//
void interrupt() {
unsigned char Msd, Lsd;
TMR0L = 100; // Re-load TMR0
INTCON = 0x20; // Set T0IE and clear T0IF
Flag = ~Flag; // Toggle Flag
if (Flag == 0) // Do digit 1
{
DIGIT2 = 0;
Msd = Cnt / 10; // MSD digit
if (Msd != 0) {
PORTC = Display(Msd); // Send to PORTC
DIGIT1 = 1; // Enable digit 1
}
} else { // Do digit 2
DIGIT1 = 0; // Disable digit 1
Lsd = Cnt % 10; // LSD digit
PORTC = Display(Lsd); // Send to PORTC
DIGIT2 = 1; // Enable digit 2
}
}
//
// Start of MAIN Program. configure PORTB and PORTC as outputs.
// In addition, configure TMR0 to interrupt at every 10ms
//
void main() {
TRISC = 0; // PORTC are outputs
TRISB = 0; // RB0, RB1 are outputs
DIGIT1 = 0; // Disable digit 1
DIGIT2 = 0; // Disable digit 2
//
// Configure TMR0 timer interrupt
//
T0CON = 0xC4; // Prescaler = 32
TMR0L = 100; // Load TMR0 with 100
INTCON = 0xA0; // Enable TMR0 interrupt
Delay_ms(1000);
for(;;) // Endless loop
{
Cnt++; // Increment Cnt
if (Cnt == 100) Cnt = 0; // Count between 0 and 99
Delay_ms(1000); // Wait 1 second
}
}
Figure 6.37: Modified program
PROJECT 6.8 — Voltmeter with LCD Display
Project Description
In this project a voltmeter with LCD display is designed. The voltmeter can be used to measure voltages 0–5V. The voltage to be measured is applied to one of the analog inputs of a PIC18F452-type microcontroller. The microcontroller reads the analog voltage, converts it into digital, and then displays it on an LCD.
In microcontroller systems the output of a measured variable is usually displayed using LEDs, 7-segment displays, or LCD displays. LCDs make it possible to display alphanumeric or graphical data. Some LCDs have forty or more character lengths with the capability to display several lines. Other LCD displays can be used to display graphics images. Some modules offer color displays, while others incorporate backlighting so they can be viewed in dimly lit conditions.
There are basically two types of LCDs as far as the interface technique is concerned: parallel and serial. Parallel LCDs (e.g., Hitachi HD44780) are connected to a microcontroller by more than one data line and the data is transferred in parallel form. Both four and eight data lines are commonly used. A four-wire connection saves I/O pins but is slower since the data is transferred in two stages. Serial LCDs are connected to the microcontroller by only one data line, and data is usually sent to the LCD using the standard RS-232 asynchronous data communication protocol. Serial LCDs are much easier to use, but they cost more than the parallel ones.
The programming of a parallel LCD is a complex task and requires a good understanding of the internal operation of the LCD controllers, including the timing diagrams. Fortunately, the mikroC language provides special library commands for displaying data on alphanumeric as well as graphic LCDs. All the user has to do is connect the LCD to the microcontroller, define the LCD connection in the software, and then send special commands to display data on the LCD.