HO CHI MINH NATIONAL UNIVERSITY
HO CHI MINH UNIVERSITY OF TECHNOLOGY
🙞···☼···🙜
MICRO-CONTROLLER COURSE
CLASS EXERCISE 1
Lecturer: Assoc. Prof: Lê Đức Hạnh
STUDENT NAME STUDENT ID
Nguyễn Ngọc Khoa 2053139
Phạm Anh Hoàng 2152082
Vũ Minh Dũng 2152489
Lê Thành 2052706
HO CHI MINH CITY, 2024
EXERCISE 1
1. Hardware explain
- Firstly, we take out the PIC16F877A (U1), three 7-segments LCD from the
library and place it in our Schematic.
a. PIC16F877A Microcontroller
- Port B of the microcontroller (RB0 to RB6) are used to control the 1 st seven-
segment display. Likewise, Port C and Port B are used to control the 2 nd and the
3rd seven-segment display.
- Pin 13 and 14 of the microcontroller is connected to an external crystal
oscillator, which provide the clock signal for the microcontroller’s operation,
ensuring reliable and precise operation
2. Programming Explain
#include <16F877A.h>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18)
used for I/O
#use delay(crystal=20000000)
#byte port_b=0x06
#byte port_c=0x07
#byte port_d=0x08
#byte tris_b=0x86
#byte tris_c=0x87
#byte tris_d=0x88
void main()
{
int8
sevensegmentcode[10]={0b01000000,0b01111001,0b10100100,0b00110000,0b000
11001,0b00010010,0b00000010,0b01111000,0b00000000,0b00010000};
int16 biendem=0;
int8 tram=0,chuc=0,donvi=0;
tris_b=0x00;
tris_c=0x00;
tris_d=0x00;
while(TRUE)
{
tram=biendem/100;
chuc=(biendem/10)%10;
donvi=biendem%10;
port_b=sevensegmentcode[tram];
port_c=sevensegmentcode[chuc];
port_d=sevensegmentcode[donvi];
biendem+=1;
if(biendem>999) biendem=0;
delay_ms(150);
}
}
a) Initialization:
- The code begins by including the necessary header file for the PIC16F877A
microcontroller and setting up the device configuration fuses. It also sets the
clock frequency for the delay function and defines the SFRs for the ports that
the seven-segment displays are connected to.
b) Seven-Segment Code Array:
- The sevensegmentcode array is defined with the binary codes for displaying
numbers 0-9 on a seven-segment display. Each binary code corresponds to the
segments that need to be lit up to display a particular number.
c) Main Function:
- The main function is where the main logic of the program resides. It starts by
setting the data direction registers (tris_b, tris_c, tris_d) to 0, which configures
the corresponding ports as output ports.
- Using Special Function Registers (SFRs): In our code, we’ve used SFRs to
directly control the ports of the PIC16F877A microcontroller. SFRs are specific
registers of a microcontroller which carry out special functions. The lines #byte
port_b=0x06, #byte port_c=0x07, and #byte port_d=0x08 define the SFRs for
ports B, C, and D respectively. Similarly, #byte tris_b=0x86, #byte
tris_c=0x87, and #byte tris_d=0x88 define the SFRs for the data direction
registers of these ports. By writing to these SFRs, you’re directly controlling
the hardware of the microcontroller.
- Not Using Existing Functions: Apart from the delay_ms function provided by
the compiler, our code does not use any other existing functions. All the logic
for controlling the seven-segment displays is implemented directly in the main
function. This includes the logic for calculating the digits to be displayed and
the logic for outputting the segment codes to the ports.
d) Infinite Loop:
- Inside the main function, there’s an infinite while(TRUE) loop. This loop keeps
the program running indefinitely, continuously updating the displays with the
current number.
e) Number Display Logic:
- Inside the infinite loop, the code calculates the hundreds (tram), tens (chuc),
and ones (donvi) digits of the current number (biendem). It then uses these
digits to index into the sevensegmentcode array and get the corresponding
segment codes. These segment codes are output to the ports that the seven-
segment displays are connected to, thereby displaying the current number.
f) Number Increment and Delay:
- After displaying the current number, the code increments biendem by 1.
If biendem exceeds 999, it is reset back to 0. The delay_ms(150) function call
introduces a delay between each update to make the count visible.
3. Simulation
- The three seven-segment displays are arranged from left to right, with the first
display on the far right and the third display on the far left.
- After insert the programming file to the controller and hit the run button, the
number is displayed on the rightmost display.
- The rightmost LCD start displaying number from zero, and when it hits number
9, the middle LCD start displaying. When the first two LCD reach 99, the
leftmost display starts showing the number 1, while the rightmost and middle
display continues counting from 0 to 9.
- This pattern continues, with each display incrementing its value once the
previous display reaches its maximum count.
- Here is our simulation running on proteus:
o https://drive.google.com/file/d/
1qr56EmM4cH9WeADVDPh9z4C0urS8uL0G/view?usp=sharing
EXERCISE 2
1. Hardware explain
- Firstly, take out the microcontroller PIC16F877A, one LCD LM016L, a
Potentionmeter and place it in the Schematic
a. The microcontroller PIC 16F877A
- Pin 20 (RD1) of the PIC is connected to pin 4 (RS) of the LCD
o The RD1 pin of the PIC16F877A microcontroller is used to control the
RS pin of the LCD. By setting RD1 high or low, the microcontroller can
switch the LCD between command mode and data mode as needed. This
allows the microcontroller to send commands to the LCD to control its
operation, and also send data to be displayed.
- Pin 21 (RD2) of the PIC is connected to pin 5 (RW) of the LCD
o The RW (Read/Write) pin of the LCD is used to switch between read
mode and write mode.
When RW is low (0), the LCD is in write mode. In this mode, the
microcontroller can send data or commands to the LCD.
When RW is high (1), the LCD is in read mode. In this mode, the
microcontroller can read data from the LCD.
o The RD2/PSP2 pin of the PIC16F877A microcontroller is used to
control the RW pin of the LCD. By setting RD2 high or low, the
microcontroller can switch the LCD between read mode and write mode
as needed.
- Pin 22 (RD3) of the PIC is connected to pin 6 (E) of the LCD
o The E (Enable) pin of the LCD is used to start data read/write
operations.
When the E pin is high (1), the LCD is enabled and can carry out
the command or data operation that has been set up on its other
pins.
When the E pin is low (0), the LCD is disabled and will ignore
commands and data on its other pins.
o The RD3/PSP3 pin of the PIC16F877A microcontroller is used to
control the E pin of the LCD. By setting RD3 high or low, the
microcontroller can enable or disable the LCD as needed.
- Pin RD4, RD5, RD6, RD7 is connected to pin D4, D5, D6, D7 of the LCD
o This connection used to send information from the microcontroller to
the LCD.
o In 4-bit mode, which is being used in our setup, data is sent from the
microcontroller to the LCD in 4-bit chunks. The RD4-RD7 pins of the
microcontroller are configured as output pins and are used to send these
4-bit chunks to the D4-D7 pins of the LCD.
b. The LCD LM016L
- Pin 1 - VSS (Ground): This pin is connected to the ground of the power
supply. It’s the reference point for all voltage levels in a circuit.
- Pin 2 - VDD (Power Supply): This pin is connected to the positive voltage of
the power supply. It provides the power needed for the LCD to operate.
- Pin 3 - VEE (Contrast Adjust): This pin is used to control the contrast of the
LCD. By varying the voltage at this pin, we can make the characters on the
LCD appear darker or lighter.
o The potentiometer (POT-HG) is used to vary this voltage. One end of
the potentiometer is connected to VDD, the other end is connected to
VSS, and the middle pin (the wiper) is connected to VEE. By adjusting
the potentiometer, you can change the voltage at VEE and thereby adjust
the contrast of the LCD.
- The other pins are connected to the microcontroller as mentioned above
c. The potentionmeter POT-HG
- the VSS and VDD pins of the LCD are connected to the potentiometer to
provide power to the LCD, and the VEE pin is connected to the potentiometer
to allow for contrast adjustment.
2. Programming explain
#include <16F877A.h>
#device ADC=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used
for I/O
#use delay(crystal=20000000)
#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_ENABLE_PIN PIN_D3
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c>
#include <string.h>
char text[] = " Mechatronics xxxx ";
unsigned char Character1[8] = { 0x00, 0x0A, 0x15, 0x11, 0x0A, 0x04, 0x00,
0x00 }; //Custom char set for alphanumeric LCD Module
unsigned char Character2[8] = { 0x04, 0x1F, 0x11, 0x11, 0x1F, 0x1F, 0x1F, 0x1F };
unsigned char Character3[8] = { 0x04, 0x0E, 0x0E, 0x0E, 0x1F, 0x00, 0x04, 0x00 };
unsigned char Character4[8] = { 0x01, 0x03, 0x07, 0x1F, 0x1F, 0x07, 0x03, 0x01 };
unsigned char Character5[8] = { 0x01, 0x03, 0x05, 0x09, 0x09, 0x0B, 0x1B, 0x18 };
unsigned char Character6[8] = { 0x0A, 0x0A, 0x1F, 0x11, 0x11, 0x0E, 0x04, 0x04 };
unsigned char Character7[8] = { 0x00, 0x00, 0x0A, 0x00, 0x04, 0x11, 0x0E, 0x00 };
unsigned char Character8[8] = { 0x00, 0x0A, 0x1F, 0x1F, 0x0E, 0x04, 0x00, 0x00 };
void scroll_left(int16 speed) {
for (int j = 0; j <= 35; j++) {
for (int i = 1; i <= 16; i++) {
if (i + j == 17) {
lcd_gotoxy(i, 1);
lcd_putc(1);
continue;
}
lcd_gotoxy(i, 1);
printf(lcd_putc, "%c", text[i + j - 1]);
}
delay_ms(speed);
}
}
void scroll_right(int16 speed) {
for (int j = 0; j <= 35; j++) {
for (int i = 1; i <= 16; i++) {
if (35 + i - j == 17) {
lcd_gotoxy(i, 1);
lcd_putc(1);
continue;
}
lcd_gotoxy(i, 1);
printf(lcd_putc, "%c", text[35 + i - j - 1]);
}
delay_ms(speed);
}
}
void update(int16 number) {
int thousand = number / 1000;
int hundred = (number / 100) % 10;
int ten = (number / 10) % 10;
int unit = number % 10;
text[31] = (char)('0' + thousand);
text[32] = (char)('0' + hundred);
text[33] = (char)('0' + ten);
text[34] = (char)('0' + unit);
}
void main() {
set_tris_d(0x00);
lcd_init();
lcd_putc('\f');
int16 counter;
// Save custom characters into CGRAM
lcd_set_cgram_char(0, Character1);
lcd_set_cgram_char(1, Character2);
lcd_set_cgram_char(2, Character3);
lcd_set_cgram_char(3, Character4);
lcd_set_cgram_char(4, Character5);
lcd_set_cgram_char(5, Character6);
lcd_set_cgram_char(6, Character7);
lcd_set_cgram_char(7, Character8);
int16 start_value = 2012;
int16 end_value = 2024;
int16 speed = 50; // scrolling speed
counter = start_value;
update(counter);
// Display custom characters on the second line
lcd_gotoxy(5, 2); lcd_putc(0); // Display Character1 at position 5
lcd_gotoxy(6, 2); lcd_putc(1); // Display Character2 at position 6
lcd_gotoxy(7, 2); lcd_putc(2); // Display Character3 at position 7
lcd_gotoxy(8, 2); lcd_putc(3); // Display Character4 at position 8
lcd_gotoxy(9, 2); lcd_putc(4); // Display Character5 at position 9
lcd_gotoxy(10, 2); lcd_putc(5); // Display Character6 at position 10
lcd_gotoxy(11, 2); lcd_putc(6); // Display Character7 at position 11
lcd_gotoxy(12, 2); lcd_putc(7); // Display Character8 at position 12
while (true) {
scroll_right(speed);
update(counter += 1);
if (counter == end_value + 1) {
counter = start_value;
update(counter);
}
scroll_left(speed);
update(counter += 1);
if (counter == end_value + 1) {
counter = start_value;
update(counter);
if (counter == end_value + 1) {
break;// Exit the loop when counter reaches end_value
}
}
}
}
a) Initialization:
The #include <16F877A.h> directive includes the header file for the
PIC16F877A microcontroller, which is the target microcontroller for this code.
#device ADC=16 specifies that the Analog-to-Digital Converter (ADC)
module should use 16-bit resolution.
#FUSES are configuration settings for the microcontroller. Here, NOWDT,
NOBROWNOUT, and NOLVP specify that the Watchdog Timer, Brownout
Reset, and Low-Voltage Programming features are disabled, respectively.
#use delay(crystal=20000000) sets up the delay function using a 20 MHz
crystal oscillator.
b) LCD Pin Definitions:
Definitions are provided for various pins used to interface with the LCD
module. These definitions will be used later to control the LCD.
c) Include LCD Library:
The lcd.c file is included, which likely contains functions to interface with the
LCD module.
d) Custom Character Definitions:
Eight custom characters are defined using arrays of hexadecimal values. These
characters will be stored in the CGRAM (Character Generator RAM) of the
LCD and used for special symbols or icons.
e) Scrolling Functions:
Two functions, scroll_left and scroll_right, are defined to implement left and
right scrolling of text on the LCD.
These functions take a speed parameter to control the scrolling speed.
Inside each function, a nested loop is used to iterate through the text and update
the displayed portion on the LCD, creating the scrolling effect.
f) Update Function:
The update function is defined to update the text displayed on the LCD with a
new counter value.
It takes a number as input, extracts individual digits (thousand, hundred, ten,
and unit), and updates specific positions in the text[] array.
g) Main Function:
The main function initializes the microcontroller and LCD, clears the display,
and sets the initial counter value.
Custom characters are loaded into the CGRAM of the LCD.
The initial counter value is set, and the custom characters are displayed on the
second line of the LCD.
The main loop continuously scrolls the text to the right, updates the counter
value, checks if the counter has reached the end value, resets the counter if
necessary, then scrolls the text to the left, updates the counter again, and
repeats the process indefinitely.
h) Display:
The display on the LCD continuously scrolls the text from the start_value to
the end_value, displaying numbers in a scrolling fashion along with custom
characters.
3. Simulation
- After setting up, insert the program to the microcontroller and hit the run button
in Proteus, we can see on the screen that:
o The text start rolling from left to right display exactly the requirements:
“ symbol Mechatronics number ”, where symbol is a custom character in
accordance with group 2 and number is the variable increases from 2012
to 2024
o On the second line, there are all the custom character from the
requirements.
o The text rolling from right to left while increasing the number. This
pattern repeats until it hit 2024.
- Here is our simulation running on Proteus:
o https://drive.google.com/file/d/1uD4-
JRl8DDdyn_uol4MkG5854o4ULOoW/view?usp=sharing
THE END