Assignment title: Information
NIE2206 Electronic Logbook
Embedded Systems
By submitting this logbook I confirm that I understand this is an individual assignment and that this work is entirely my own.
Laboratory Practical:
DATE: 20-10-2016
ROOM: CWG/02
Laboratory Aim:
An introduction to the hardware and software tools required for the Embedded Systems in the lab is the main aim of this lab. This will help understand how to develop, build and debug complex C programs.
Exercise 1 – Matrix E-block development system orientation
Aim of exercise:
Understanding the Matrix E-block development board orientation is the main goal of this exercise.
Procedure:
PIC Multiprogrammer:
The PIC microcontroller programmer connects to the PC via USB to provide with one of world’s most flexible and lowest cost PICmicro microcontroller programmers. The board can be used with Assembly, C or Flowcode programming utilities provided by MatrixMultimedia. The board will program most 8, 14, 18, 20, 28 and 40 pin flash PICmicro microcontroller devices using the flexible programming software provided. The board also provides clean access to all I/O lines on the relevant PICmicro MCU devices. A schematic diagram of the main board is given below.
Board diagram below:
Numbers on the layout diagram is below:
There are three other attachable parts to complete the development board.
• LCD Board
• Switch board
• LED board
• Sensor boards.
LCD Board:
This is an LCD Display designed for E-blocks which can be used as a flexible display for development use and for projects. The display is a 16 character, 2-line alphanumeric LCD device which connects to an upstream E-block board via a single 9-way D-type connector. The LCD display requires data in a serial format on 5 data inputs. Programming details and a full character set are provided.
The upstream board uses pins 1 - 6 on the 9-way D-type connector (when DEFAULT link option is chosen) to program the LCD, as shown in the circuit diagram below. When the LCD board is turned on, data can only be sent to it after 30ms, this is the time taken for the LCD to initialize [as it clears all the RAM and sets up the Entry Mode].
LCD timing diagram
Switch Board:
This Switch Board is part of the E-Blocks range. The board allows you to connect up to 8 switches to any of the I/O ports on the E-Block Multi / Lite programmer board. The standard 9-way D-type connector associated with EBlocks makes the upstream and downstream connection. Further E-Blocks can be connected to this E-Block. The two D-type connectors provide a bus system that enables ‘clean’ access to all I/O lines
LED Board:
The board allows you to connect up to 8 LEDs to any of the I/O ports on an upstream board to indicate the status of each line on the port. The LED board connects to upstream boards using a 9 way D type plug. Further downstream boards can also be connected to the LED board using the 9 way D type socket. This allows the LED board to be used as to indicate the status of the lines on an E-blocks bus within a system.
Sensor Interface:
It allows to digital or analogue sensors to any of the I/O ports on the E-Block. It also allows you to use the on-board light sensor and variable resistor for quick system operational checks.
Outcomes:
E-block hardware have been investigated and their functionality understood from this exercise.
Conclusion:
E-block is a versatile board with many functionalities and there are many things to learn about these as the labs progress.
Exercise 2 – PPP programmer application orientation
Aim of exercise:
How to configure and use the PPPv3 programmer for the programming of PIC in the development board. .
Procedure:
PPP launch window is below:
PPP set up and configuration window:
Outcomes:
EBLOCK_TEST.hex was tested to learn how to use PPP. It has been noticed that the LEDs on both E‐block LED boards are lighting up sequentially as the MCU executes the machine code contained in the HEX file.
Conclusion:
Learnt how to use PPP programmer for PIC 16F877A.
Exercise 3 - Microchip PIC MCU family orientation
Aim of exercise:
Familiarisation of PIC16F877A microcontrollers and other families from Microchip.
Procedure:
PIC16F877A:
Unit price: £4.39; Program memory size: 14 KB; RAM: 368 Bytes; Pin count: 40; CPU Speed: 5 MIPS
Other families from Microchip:
PIC10F222 PIC12F752 PIC18F452
Pin Count 6 8 40
Program memory size 0.75 KB 1.8 KB 32 KB
RAM size 23 Bytes 64 Bytes 1536 Bytes
Speed CPU 2 MIPS 5 MIPS 10 MIPS
Price 47p 77p £5.81
Outcomes:
Familiarised with PIC16F877A microcontrollers and other families from Microchip.
Conclusion:
Understanding of the differences between many types of microcontroller families.
Exercise 4 - MPLAB X IDE Orientation
Aim of exercise:
To demonstrate the use of software tool, MPLAB IDE is the main aim of this exercise by creating a project and compiling a code.
Procedure:
Instructions in the lab sheet have been followed to create the project that has been asked to make from the new project window and selecting the correct settings.
Then the source file was copied to the project from the lab sheet:
// Filename: Lab1Ex4.c
// Version: 1.0
// Date: 20-10-2016
// Author: TALAL
//
// Description: A simple program to monitor a switch press and light up an LED
// using a PIC16f877A.
#include // Required by the XC8 compiler
void main(void)
{
// Make PORTD input and PORTB output
TRISD=0xFF; // Make PORTD input
TRISB=0x00; // Make PORTB output
while (1) // Infinite (endless) loop
{
if (RD0==1) // Has SW0 switch on PORTD been pressed?
{
PORTB=0xff; // Turn all PORTB LEDs ON
}
else
{
PORTB=0x00; // Otherwise switch all PORTB LEDs OFF
}
}
}
Outcomes:
When RD0 is pressed as input:
PORTB = 0xFF and when RD0 is released PORTB = 0x00, so for each options outputs have performed different operations.
Conclusion:
Input and output have both been used in this program.
Laboratory Practical 2 - General Purpose Input and Output (GPIO)
DATE: 27-10-2016
ROOM: CWG/02
Laboratory Aim:
This lab will introduce to the basic input output systems of the PIC16F877A microcontrollers. Exercises will show how these GPIO pins can be configured for inputs and outputs from the LED and Switch boards that have been available in the laboratory.
Exercise 1 – PORTB timed lighting sequence
Aim of exercise:
This project makes a code that will create a PORTB timed lighting sequence.
Procedure
Code:
// Filename: Lab2Ex1.c
// Version: 1.0
// Date: 27-10-2016
// Author: TALAL
//
// Description: A simple program to produce a repeating sequence on PORTB on a
// PIC16F877A
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
void main(void)
{
TRISB=0x00; // Make all of PORTB output
while(1)
{
PORTB=0xf0; // Turn ms nibble on
__delay_ms(200); // Wait 200 msecs
PORTB=0x0f; // Turn ls nibble on
__delay_ms(200); // Wait 200 msecs
}
}
PORTB was configured as outputs and in the main program these outputs are used to create a timed lighting sequence.
Outcomes:
The PORTB LEDs were lighting F0 and 0F at an interval of 200 ms which is the delay that has been implemented. Other values of delay and LEDs have been tried to get a good understanding of how it works.
Conclusion:
A simple output program using the PORTB LEDs has been created.
Exercise 2 - Combining input and output
Aim of exercise:
The aim of this exercise is to combine both inputs with output to make a project.
Procedure:
Code:
// Filename: Lab2Ex1.c
// Version: 1.0
// Date: 27-10-2016
// Author: TALAL
// Description: Creates a lighting sequence on PORTB that depends on the status
// of the pushbutton connected to RD0 (SW0)
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
void main (void)
{
TRISD=0x01; // Make bit 0 of PORTD input and bits 1:7 output
// Remember 0x01 = 0b00000001
TRISB=0x00; // Make all of PORTB output i.e. 0b00000000
while(1)
{
if (RD0==1) // Is bit 0 of PORTD high? i.e. SW0 on e‐block pressed
PORTB=0xAA; // Light every other LEDs: 0xAA = 0b10101010
else
PORTB=0x55; // Light the alternate LED: 0x55 = 0b01010101
}
}
The flow chart for the program is given below.
The complete arrowed loops are the while (1) loop and the true and false block is the if/else statement.
Outcomes:
When RD0 is pressed as input:
PORTB = 0xAA and when RD0 is released PORTB = 0x55, so for each options alternate LEDs were lighting and this was correctly seen in the LEDs.
Conclusion:
Input and output have both been used in this program.
Exercise 3 - Adding functional complexity
Aim of exercise:
This exercise aims to add more complex functionality compared to the previous program.
Procedure:
Function table of the program is given below:
Flow chart for this is:
// Filename: Lab2Ex3.c
// Version: 1.0
// Date: 27-10-2016
// Author: TALAL
//
// Description: This program has more complex functions
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
void main (void)
{
TRISD=0x03; // Make bit 0 and 1 of PORTD inputs
TRISB=0x00; // Make all of PORTB output i.e. 0b00000000
while(1)
{
if(RD0==1&&RD1==0) //RD0 SW ON
{
PORTB=0x0F; // 0b00001111
}
if(RD0==0&&RD1==1) //RD1 SW ON
{
PORTB=0xAA; // 0b10101010
__delay_ms(100); // Wait 100 msecs
PORTB=0x55; // 0b01010101
__delay_ms(100); // Wait 100 msecs
}
if(RD0==1&&RD1==1) //RD0and RD1 both SWs ON
{
PORTB=0x00; // Clear all LEDs
}
else //RD0and RD1 both SWs OFF
PORTB=0xF0; // 0b11110000
}
}
Outcomes:
The code developed works according to the program function table provided and this has been checked using the LED and Switch boards.
Conclusion:
A complex program using 2 inputs and outputs have been created.
Laboratory Practical 3 - Liquid Crystal Display (LCD)
DATE: 3-11-2016
ROOM: CWG/02
Laboratory Aim:
There is a LCD module available with the development board in the lab. It is an industry standard 2x16 LCD driven by the dedicated driver. Using the custom LCD library many functions such as displaying characters, animations and displaying numerical values can be done one the LCD.
Exercise 1 – Demonstrating the custom LCD library
Aim of exercise:
To compile a given program in order to see how the functions of the built in LCD libraries work in the program.
Procedure:
One of the first tasks of the project creation for the LCD part to include the LCD custom files in the project which has been done for the project that has been created. Study of the code shows that it works using the following flow chart:
The code for the project:
// Filename: Lab3Ex1.c
// Version: 1.0
// Date: 3-11-2016
// Author: TALAL
// Description: Simple demonstration of the LCD custom library functions
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
#include "LCDdrive.h" // Header file needed to access to LCD custom
// library
void main(void)
{
char myString[] = {"Embedded Systems"}; // Initialise an array with a string
unsigned short i; // Indexing variable
LCD_initialise(); // Initialise the LCD ready for use
LCD_puts(myString); // Display the myString string
LCD_cursor(0,1); // Move the cursor to the 2nd line
LCD_cursor_on(); // Turn flashing cursor ON
// Illustration of the putch() function
__delay_ms(2000); // Wait 2 seconds
LCD_putch('A'); // Print character A
__delay_ms(2000); // Wait 2 seconds
LCD_putch('B'); // Print character B
__delay_ms(2000); // Wait 2 seconds
LCD_putch('C'); // Print character C
__delay_ms(2000); // Wait 2 seconds
LCD_cursor_off(); // Turn flashing cursor OFF
for (i=0; i<1000; i++) // Set up loop to display counting numerals
{
LCD_cursor(4,1); // Move the cursor to the column 4 on the 2nd line
LCD_display_value(i); // Display the value of x at the cursor position
__delay_ms(100); // Short delay
}
}
The main parts are:
Displaying numerical value
for (i=0; i<1000; i++) // Set up loop to display counting numerals
{
LCD_cursor(4,1); // Move the cursor to the column 4 on the 2nd line
LCD_display_value(i); // Display the value of x at the cursor position
__delay_ms(100); // Short delay
}
A flashing cursor
LCD_cursor_on(); // Turn flashing cursor ON
Printing of individual characters
__delay_ms(2000); // Wait 2 seconds
LCD_putch('A'); // Print character A
__delay_ms(2000); // Wait 2 seconds
LCD_putch('B'); // Print character B
__delay_ms(2000); // Wait 2 seconds
LCD_putch('C'); // Print character C
__delay_ms(2000); // Wait 2 seconds
Printing of a string
LCD_initialise(); // Initialise the LCD ready for use
LCD_puts(myString); // Display the myString string
Outcome:
Uploaded program worked by demonstrating functions that has been created for the exercise. The message is shown on the LCD. Characters are displayed at 2 seconds delay. Number are then displayed at 100 ms delay. This is how the program should work so it worked expectedly.
Conclusion:
Demonstration of the custom built LCD libraries have been received through this program.
Exercise 2 – Animation using LCD display
Aim of exercise:
Animation is to be created using the LCD library functions.
Procedure:
Code given has been compiled and is given below:
// Filename: Lab3Ex2.c
// Version: 1.0
// Date: 3-11-2016
// Author: TALAL
// Description: Simple animation using the LCD custom library functions
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
#include "LCDdrive.h" // Header file needed to access the LCD custom
// library
void main(void)
{
char myString[] = {"LCDs are great"}; // Initialise an array with a string
unsigned short i; // Indexing variable
LCD_initialise(); // Initialise the LCD ready for use
LCD_puts(myString); // Display the myString string
while(1) // Infinite loop
{
for (i=0; i<16; i++) // Set up loop to move character
{
LCD_cursor(i,1); // Move cursor into position
LCD_putch('O'); // Display character
__delay_ms(200); // Short delay
LCD_cursor(i,1); // Move the cursor back to original position
LCD_putch(' '); // Erase character
}
}
}
The program flow chart derived from the explanation and study of the code is given below:
The program has been modified so that now the animation to the right of LCD screen and when the last place is reached it changes direction. Added code to the main program is given below:
// Filename: Lab3Ex2.c
// Version: 1.0
// Date: 3-11-2016
// Author: TALAL
// Description: This part has been done to bring the character back
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
#include "LCDdrive.h" // Header file needed to access the LCD custom
// library
void main(void)
{
char myString[] = {"LCDs are great"}; // Initialise an array with a string
unsigned short i; // Indexing variable
LCD_initialise(); // Initialise the LCD ready for use
LCD_puts(myString); // Display the myString string
while(1) // Infinite loop
{
for (i=0; i<16; i++) // Set up loop to move character
{
LCD_cursor(i,1); // Move cursor into position
LCD_putch('O'); // Display character
__delay_ms(200); // Short delay
LCD_cursor(i,1); // Move the cursor back to original position
LCD_putch(' '); // Erase character
}
for (i=15; i>0; i--) // Set up loop to move character
{
LCD_cursor(i,1); // Move cursor into position
LCD_putch('O'); // Display character
__delay_ms(200); // Short delay
LCD_cursor(i,1); // Move the cursor back to original position
LCD_putch(' '); // Erase character
}
}
}
Outcome:
Uploaded program worked by displaying the string and moving the running animation. Then the modified code ensured that the running animation changes direction when reaches the end.
Conclusion:
A fully running animation has been created by using the LCD functions.
Exercise 3 – Displaying numerical information
Aim of exercise:
The main objective of the exercise is to be able to create a program that sorts the odd numbers between 1 and 99 and displays them on the LCD at 0.5 second delay between each update.
Procedure:
The program was first designed to know how the odd numbers can be detected by the program. This can be done by a simple division by 2. Odd values will have remainders and even values won’t and this way odd numbers will be detected.
Code:
// Filename: Lab3Ex3.c
// Version: 1.0
// Date: 3-11-2016
// Author: TALAL
// Description: Display of the odd numbers between 1-99
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
#include "LCDdrive.h" // Header file needed to access to LCD custom
// library
void main(void)
{
unsigned short i; // Indexing variable
LCD_initialise(); // Initialise the LCD ready for use
for (i=1; i<100; i++) // Set up loop to display counting numerals
{
if (i % 2)
{
LCD_cursor(0,1);
LCD_display_value(i); // Display the value of i at the cursor position
__delay_ms(500);
} // Short delay
else
{
__delay_ms(500); // Short delay
}
}
}
Flow chart:
Outcome:
This program perfectly displays all he odd numbers between 1 and 99 and displays them with a interval of 0.5 second on the LCD screen.
Conclusion:
Required program has been developed and tested successfully.
Laboratory Practical 4 – Timer0 module
DATE: 10-11-2016
ROOM: CWG/02
Laboratory Aim:
This lab will introduce to the timer0 module that is available for the PIC16F877A. This module is one of the main three timers/counters of the PIC. Precise delays and deterministic timing can be generated using the timers for various applications and this is demonstrated in this lab. Configuration and programming of this timer0 module is the main aim of this lab.
Exercise 1 – Creating a simple delay using Timer0 module
Aim of exercise:
Main aim of the exercise is to be able to create a simple delay using the timer0 in timer mode.
Procedure:
The code for the exercise has been provided. By studying the code flow chart of the program is given below.
The timer calculation equation is also provided in the lab sheet which has been used to calculate the delay produced.
TMR0 count = 256 - preload
Prescaler is set = 256
Delay=(4 x 256 x 256)/(3.2768 MHz)=80ms
Code:
// Filename: Lab4Ex1.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: Simple demonstration of a timer delay
#include // Required for all MPLAB XC8 source files
void main(void)
{
unsigned char preload = 0x00; // TMR0 preload variable
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bit field to 111 for 1:256
while(1) // Infinite loop
{
TMR0 = preload; // Preload timer0
while(!INTCONbits.TMR0IF); // Delay loop: Wait until TMR0 overflows
INTCONbits.TMR0IF = 0; // Reset overflow flag, TMR0IF
PORTD++; // Increment PORTD
}
}
Outcome:
Code works as it should by increasing the PORTD LEDs at 80 ms interval in binary values. Other values of TMR0 has been tried such as 100, 150 and the delay becomes less and this can be observed on the LEDs. Stopwatch shows that the delay is accurate.
Conclusion:
Exercise has been completed successfully by creating a small delay using timer0 in timer mode.
Exercise 2 – Creating longer delays
Aim of exercise:
Aim is to create a longer delay by cascading number of short delays.
Procedure:
The code for the exercise has been provided. The timer calculation equation is also provided in the lab sheet which has been used to calculate the delay produced.
TMR0 count = 256 - 192
Prescaler is set = 256
Delay=(4 x 256 x 64)/(3.2768 MHz)=20ms
This has been cascaded 8 times to get a delay of 160 ms.
Code:
// Filename: Lab4Ex2.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: Looping of a short timer delay to create a longer one
#include // Required for all MPLAB XC8 source files
void main(void)
{
unsigned char preload = 192; // TMR0 preload variable
unsigned char i; // Loop index variable
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1) // Infinite loop
{
for(i=0;i<8;i++) // Loop to cascade several short delays together
{
TMR0 = preload; // Preload timer0
while(!INTCONbits.TMR0IF); // Delay loop: Wait until TMR0 overflows
INTCONbits.TMR0IF = 0; // Reset overflow flag, TMR0IF
}
PORTD++; // Increment PORTD
}
}
For one second delay,
TMR0 count = 256 - 224
Prescaler is set = 256
Delay=(4 x 256 x 32)/(3.2768 MHz)=10ms
This has been cascaded 25 times to get a delay of 1 s.
25 x 40 ms = 1 s delay total in cascade.
Code:
// Filename: Lab4Ex2.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: one second delay
// Creates a one second delay
#include // Required for all MPLAB XC8 source files
void main(void)
{
unsigned char preload = 224; // TMR0 preload variable 224
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1) // Infinite loop
{
for(i=0;i<100;i++) // Loop to cascade several short delays together
{
TMR0 = preload; // Preload timer0
while(!INTCONbits.TMR0IF); // Delay loop: Wait until TMR0 overflows
INTCONbits.TMR0IF = 0; // Reset overflow flag, TMR0IF
}
PORTD++; // Increment PORTD
}
}
Outcome:
Code works as it should by increasing the PORTD LEDs at 160 ms interval in binary values. Stopwatch shows that the delay is accurate. 1 second delay code works as well by increasing the PORTD LEDs at 1 second interval in binary values. Stopwatch shows that the delay is accurate.
Conclusion:
Exercise has been completed successfully by creating a long delay by cascading a number of small delay using timer0 in timer mode.
Exercise 3 – Creating a one second delay function
Aim of exercise:
One second delay function will be created that can be used in any program.
Procedure:
The two values created previously: number of loops and the size of the delay needed to be put in the code provided which was done to get the 1 second delay function required by the exercise. The compiled code is given below.
// Filename: Lab4Ex3.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: Implementing a Timer0 delay function
#include // Required for all MPLAB XC8 source files
void one_sec_delay (void); // Function prototype
void main(void)
{
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
while(1) // Infinite loop
{
one_sec_delay(); // Call delay function
PORTD++; // Increment PORTD
}
}
void one_sec_delay (void)
{
unsigned char preload = 224; // TMR0 preload variable 224
unsigned char i; // Loop index variable
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
for(i=0;i<100;i++) // Loop to cascade several short delays together
// Number of loops derived from Ex2
{
TMR0 = preload; // Preload timer0
while(!INTCONbits.TMR0IF); // Delay loop: Wait until TMR0 overflows
INTCONbits.TMR0IF = 0; // Reset overflow flag, TMR0IF
}
}
Outcome:
1 second delay code works as a function as well by increasing the PORTD LEDs at 1 second interval in binary values. Stopwatch shows that the delay is accurate.
Conclusion:
Exercise has been completed successfully by creating a one second delay function.
Exercise 4 – Creating a variable delay function
Aim of exercise:
Aims to develop a variable delay function that can produce integer multiples of 1 second delay that has been created earlier in the lab session.
Procedure:
The code that has been compiled and developed for this purpose is given below.
// Filename: Lab4Ex4.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: implementation of a variable delay
#include // Required for all MPLAB XC8 source files
void delay (unsigned char delay_length); // Function prototype
void main(void)
{
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
while(1) // Infinite loop
{
delay(1); // Call delay function
PORTD++; // Increment PORTD
}
}
void delay (unsigned char delay_length)
{
unsigned char preload = 224; // TMR0 preload variable 224
unsigned char i; // Loop index variable
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
for(i=0;i // Required for all MPLAB XC8 source files
void main(void)
{
TRISD = 0x00; // Set up ports
PORTD = 0x00;
INTCON = 0xA0; // SET GIE, TMR0IE
// Set up Timer0 for 80 ms per overflow
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1); // Do nothing
}
// Interrupt service routine
void interrupt myISR(void)
{
if(TMR0IF) // Timer0 overflow interrupt specific code
{
PORTD++;
INTCONbits.TMR0IF = 0; // Reset flag
}
}
Outcome:
The interrupt is working properly which has been confirmed by the incrementing LEDs of PORTD at every 80 ms. this code for LED is in the interrupt service routine so it can only work if the program is interrupted and goes into ISR.
Conclusion:
Learnt how to successfully create an interrupt using timer0 and the full functionality of this interrupt. Also understanding of interrupt service routine has been gained.
Exercise 2 – Creating precise delays using interrupts
Aim of exercise:
To create a precise delay that increments PORTD LEDs at a rate of 1 Hz.
Procedure:
In order to do this: TMR0 value is reset after every interrupt to 224 in ISR. The PORTD LEDs will only update after 100 interrupts which has been put in an if/else statement. This counting is done in the ISR after every interrupt. The code is given below:
// Filename: Lab5Ex2.c
// Version: 1.0
// Date: 24-11-2016
// Author: TALAL
//
// Description: Precise one second delay using interrupt
#include // Required for all MPLAB XC8 source files
unsigned char cont=0; //this variable counts number of interrupts
void main(void)
{
TRISD = 0x00; // Set up ports
PORTD = 0x00;
INTCON = 0xA0; // SET GIE, TMR0IE
// Set up Timer0 for 80 ms per overflow
OPTION_REGbits.T0CS = 0; // Set cloccont source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1); // Do nothing
}
// Interrupt service routine
void interrupt myISR(void)
{
if(TMR0IF) // Timer0 overflow interrupt specific code
{
cont=cont+1; //count events of interrupt
if(cont==100)
{PORTD++;
cont=0;}
INTCONbits.TMR0IF = 0; // Reset flag
}
TMR0 = 224; // Preload timer0 224
}
Flow chart of the ISR has been created as follows:
Outcome:
Precise delay of 1 s has been created that increments PORTD LEDs at a rate of 1 Hz. This has been confirmed by the use of stopwatch.
Conclusion:
Delay creation of precision level has been learnt through this exercise using timer0 interrupts.
Exercise 3 – Adding background code functionality
Aim of exercise:
To add background functionality to the existing program.
Procedure:
The additional feature is to have bit 7 of PORTB toggling away at a rate of 250ms. This has been done in the code below in a simple manner. XOR gate has been used to toggle using the following truth table:
IP IP output
0 0 0
0 1 1
1 0 1
1 1 0
// Filename: Lab5Ex3.c
// Version: 1.0
// Date: 24-11-2016
// Author: TALAL
//
// Description: Addition of background functionality to the code
#define _XTAL_FREQ 3276800
#include // Required for all MPLAB XC8 source files
unsigned char cont=0; //counts interrupts
void main(void)
{
TRISD = 0x00; // Set up ports
TRISB = 0x00; // Set up ports
PORTD = 0x00;
PORTB = 0x00;
INTCON = 0xA0; // SET GIE, TMR0IE
// Set up Timer0 for 80 ms per overflow
OPTION_REGbits.T0CS = 0; // Set cloccont source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1)
{
PORTB = PORTB ^ 0x80; //Toggle bit 7 of PORTB
__delay_ms(200); //short delay
}
}
// Interrupt service routine
void interrupt myISR(void)
{
if(TMR0IF) // Timer0 overflow interrupt specific code
{
cont=cont+1; //count events of interrupt
if(cont==100)
{PORTD++;
cont=0;}
INTCONbits.TMR0IF = 0; // Reset flag
}
TMR0 = 224; // Preload timer0 224
}
Outcome:
Bit 7 of PORTB toggling away at a rate of 250ms and this has been observed meaning the program written is working properly as needed.
Conclusion:
More operations can be added in the main program body while the interrupt is implemented.
Exercise 4 – Servicing multiple interrupts
Aim of exercise:
Two interrupts can be implemented and serviced in a code and this will be demonstrated by this program.
Procedure:
INTCON = 0xB0; RB0 interrupt is enabled as well.
PORTB reconfigured to ensure that bit 0 is input now.
Code is below:
// Filename: Lab5Ex4.c
// Version: 1.0
// Date: 24-11-2016
// Author: TALAL
//
// Description: multiple interrupt implementation
#define _XTAL_FREQ 3276800
#include // Required for all MPLAB XC8 source files
unsigned char cont=0; //count
void main(void)
{
TRISD = 0x00; // Set up ports
TRISB = 0x01; // Set up ports RB0=Input for interrupt
PORTD = 0x00;
PORTB = 0x00;
INTCON = 0xB0; // SET GIE, TMR0IE and RB0/INT
// Set up Timer0 for 80 ms per overflow
OPTION_REGbits.T0CS = 0; // Set cloccont source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1)
{
PORTB = PORTB ^ 0x80; //Toggle 0x80
__delay_ms(250); //short delay
}
}
// Interrupt service routine
void interrupt myISR(void)
{
if(INTF) // RB0/INT interrupt specific code
{
PORTD = 0x00;
INTCONbits.INTF = 0; // Reset flag
TMR0 = 224; // Preload timer0
}
else if(TMR0IF) // Timer0 overflow interrupt specific code
{
if(TMR0IF) // Timer0 overflow interrupt specific code
{
cont=cont+1; //count events of interrupt
if(cont==100)
{PORTD++;
cont=0;}
INTCONbits.TMR0IF = 0; // Reset flag
}
TMR0 = 224; // Preload timer0 224
}
}
Outcome:
Both interrupts have found to be working correctly. Especially RB0 interrupt works by resetting the PORTD when pressed.
Conclusion:
It is very straightforward to have and service two interrupts in a code.
NIE2206 Electronic Logbook
Embedded Systems
By submitting this logbook I confirm that I understand this is an individual assignment and that this work is entirely my own.
Laboratory Practical:
DATE: 20-10-2016
ROOM: CWG/02
Laboratory Aim:
An introduction to the hardware and software tools required for the Embedded Systems in the lab is the main aim of this lab. This will help understand how to develop, build and debug complex C programs.
Exercise 1 – Matrix E-block development system orientation
Aim of exercise:
Understanding the Matrix E-block development board orientation is the main goal of this exercise.
Procedure:
PIC Multiprogrammer:
The PIC microcontroller programmer connects to the PC via USB to provide with one of world’s most flexible and lowest cost PICmicro microcontroller programmers. The board can be used with Assembly, C or Flowcode programming utilities provided by MatrixMultimedia. The board will program most 8, 14, 18, 20, 28 and 40 pin flash PICmicro microcontroller devices using the flexible programming software provided. The board also provides clean access to all I/O lines on the relevant PICmicro MCU devices. A schematic diagram of the main board is given below.
Board diagram below:
Numbers on the layout diagram is below:
There are three other attachable parts to complete the development board.
• LCD Board
• Switch board
• LED board
• Sensor boards.
LCD Board:
This is an LCD Display designed for E-blocks which can be used as a flexible display for development use and for projects. The display is a 16 character, 2-line alphanumeric LCD device which connects to an upstream E-block board via a single 9-way D-type connector. The LCD display requires data in a serial format on 5 data inputs. Programming details and a full character set are provided.
The upstream board uses pins 1 - 6 on the 9-way D-type connector (when DEFAULT link option is chosen) to program the LCD, as shown in the circuit diagram below. When the LCD board is turned on, data can only be sent to it after 30ms, this is the time taken for the LCD to initialize [as it clears all the RAM and sets up the Entry Mode].
LCD timing diagram
Switch Board:
This Switch Board is part of the E-Blocks range. The board allows you to connect up to 8 switches to any of the I/O ports on the E-Block Multi / Lite programmer board. The standard 9-way D-type connector associated with EBlocks makes the upstream and downstream connection. Further E-Blocks can be connected to this E-Block. The two D-type connectors provide a bus system that enables ‘clean’ access to all I/O lines
LED Board:
The board allows you to connect up to 8 LEDs to any of the I/O ports on an upstream board to indicate the status of each line on the port. The LED board connects to upstream boards using a 9 way D type plug. Further downstream boards can also be connected to the LED board using the 9 way D type socket. This allows the LED board to be used as to indicate the status of the lines on an E-blocks bus within a system.
Sensor Interface:
It allows to digital or analogue sensors to any of the I/O ports on the E-Block. It also allows you to use the on-board light sensor and variable resistor for quick system operational checks.
Outcomes:
E-block hardware have been investigated and their functionality understood from this exercise.
Conclusion:
E-block is a versatile board with many functionalities and there are many things to learn about these as the labs progress.
Exercise 2 – PPP programmer application orientation
Aim of exercise:
How to configure and use the PPPv3 programmer for the programming of PIC in the development board. .
Procedure:
PPP launch window is below:
PPP set up and configuration window:
Outcomes:
EBLOCK_TEST.hex was tested to learn how to use PPP. It has been noticed that the LEDs on both E‐block LED boards are lighting up sequentially as the MCU executes the machine code contained in the HEX file.
Conclusion:
Learnt how to use PPP programmer for PIC 16F877A.
Exercise 3 - Microchip PIC MCU family orientation
Aim of exercise:
Familiarisation of PIC16F877A microcontrollers and other families from Microchip.
Procedure:
PIC16F877A:
Unit price: £4.39; Program memory size: 14 KB; RAM: 368 Bytes; Pin count: 40; CPU Speed: 5 MIPS
Other families from Microchip:
PIC10F222 PIC12F752 PIC18F452
Pin Count 6 8 40
Program memory size 0.75 KB 1.8 KB 32 KB
RAM size 23 Bytes 64 Bytes 1536 Bytes
Speed CPU 2 MIPS 5 MIPS 10 MIPS
Price 47p 77p £5.81
Outcomes:
Familiarised with PIC16F877A microcontrollers and other families from Microchip.
Conclusion:
Understanding of the differences between many types of microcontroller families.
Exercise 4 - MPLAB X IDE Orientation
Aim of exercise:
To demonstrate the use of software tool, MPLAB IDE is the main aim of this exercise by creating a project and compiling a code.
Procedure:
Instructions in the lab sheet have been followed to create the project that has been asked to make from the new project window and selecting the correct settings.
Then the source file was copied to the project from the lab sheet:
// Filename: Lab1Ex4.c
// Version: 1.0
// Date: 20-10-2016
// Author: TALAL
//
// Description: A simple program to monitor a switch press and light up an LED
// using a PIC16f877A.
#include // Required by the XC8 compiler
void main(void)
{
// Make PORTD input and PORTB output
TRISD=0xFF; // Make PORTD input
TRISB=0x00; // Make PORTB output
while (1) // Infinite (endless) loop
{
if (RD0==1) // Has SW0 switch on PORTD been pressed?
{
PORTB=0xff; // Turn all PORTB LEDs ON
}
else
{
PORTB=0x00; // Otherwise switch all PORTB LEDs OFF
}
}
}
Outcomes:
When RD0 is pressed as input:
PORTB = 0xFF and when RD0 is released PORTB = 0x00, so for each options outputs have performed different operations.
Conclusion:
Input and output have both been used in this program.
Laboratory Practical 2 - General Purpose Input and Output (GPIO)
DATE: 27-10-2016
ROOM: CWG/02
Laboratory Aim:
This lab will introduce to the basic input output systems of the PIC16F877A microcontrollers. Exercises will show how these GPIO pins can be configured for inputs and outputs from the LED and Switch boards that have been available in the laboratory.
Exercise 1 – PORTB timed lighting sequence
Aim of exercise:
This project makes a code that will create a PORTB timed lighting sequence.
Procedure
Code:
// Filename: Lab2Ex1.c
// Version: 1.0
// Date: 27-10-2016
// Author: TALAL
//
// Description: A simple program to produce a repeating sequence on PORTB on a
// PIC16F877A
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
void main(void)
{
TRISB=0x00; // Make all of PORTB output
while(1)
{
PORTB=0xf0; // Turn ms nibble on
__delay_ms(200); // Wait 200 msecs
PORTB=0x0f; // Turn ls nibble on
__delay_ms(200); // Wait 200 msecs
}
}
PORTB was configured as outputs and in the main program these outputs are used to create a timed lighting sequence.
Outcomes:
The PORTB LEDs were lighting F0 and 0F at an interval of 200 ms which is the delay that has been implemented. Other values of delay and LEDs have been tried to get a good understanding of how it works.
Conclusion:
A simple output program using the PORTB LEDs has been created.
Exercise 2 - Combining input and output
Aim of exercise:
The aim of this exercise is to combine both inputs with output to make a project.
Procedure:
Code:
// Filename: Lab2Ex1.c
// Version: 1.0
// Date: 27-10-2016
// Author: TALAL
// Description: Creates a lighting sequence on PORTB that depends on the status
// of the pushbutton connected to RD0 (SW0)
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
void main (void)
{
TRISD=0x01; // Make bit 0 of PORTD input and bits 1:7 output
// Remember 0x01 = 0b00000001
TRISB=0x00; // Make all of PORTB output i.e. 0b00000000
while(1)
{
if (RD0==1) // Is bit 0 of PORTD high? i.e. SW0 on e‐block pressed
PORTB=0xAA; // Light every other LEDs: 0xAA = 0b10101010
else
PORTB=0x55; // Light the alternate LED: 0x55 = 0b01010101
}
}
The flow chart for the program is given below.
The complete arrowed loops are the while (1) loop and the true and false block is the if/else statement.
Outcomes:
When RD0 is pressed as input:
PORTB = 0xAA and when RD0 is released PORTB = 0x55, so for each options alternate LEDs were lighting and this was correctly seen in the LEDs.
Conclusion:
Input and output have both been used in this program.
Exercise 3 - Adding functional complexity
Aim of exercise:
This exercise aims to add more complex functionality compared to the previous program.
Procedure:
Function table of the program is given below:
Flow chart for this is:
// Filename: Lab2Ex3.c
// Version: 1.0
// Date: 27-10-2016
// Author: TALAL
//
// Description: This program has more complex functions
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
void main (void)
{
TRISD=0x03; // Make bit 0 and 1 of PORTD inputs
TRISB=0x00; // Make all of PORTB output i.e. 0b00000000
while(1)
{
if(RD0==1&&RD1==0) //RD0 SW ON
{
PORTB=0x0F; // 0b00001111
}
if(RD0==0&&RD1==1) //RD1 SW ON
{
PORTB=0xAA; // 0b10101010
__delay_ms(100); // Wait 100 msecs
PORTB=0x55; // 0b01010101
__delay_ms(100); // Wait 100 msecs
}
if(RD0==1&&RD1==1) //RD0and RD1 both SWs ON
{
PORTB=0x00; // Clear all LEDs
}
else //RD0and RD1 both SWs OFF
PORTB=0xF0; // 0b11110000
}
}
Outcomes:
The code developed works according to the program function table provided and this has been checked using the LED and Switch boards.
Conclusion:
A complex program using 2 inputs and outputs have been created.
Laboratory Practical 3 - Liquid Crystal Display (LCD)
DATE: 3-11-2016
ROOM: CWG/02
Laboratory Aim:
There is a LCD module available with the development board in the lab. It is an industry standard 2x16 LCD driven by the dedicated driver. Using the custom LCD library many functions such as displaying characters, animations and displaying numerical values can be done one the LCD.
Exercise 1 – Demonstrating the custom LCD library
Aim of exercise:
To compile a given program in order to see how the functions of the built in LCD libraries work in the program.
Procedure:
One of the first tasks of the project creation for the LCD part to include the LCD custom files in the project which has been done for the project that has been created. Study of the code shows that it works using the following flow chart:
The code for the project:
// Filename: Lab3Ex1.c
// Version: 1.0
// Date: 3-11-2016
// Author: TALAL
// Description: Simple demonstration of the LCD custom library functions
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
#include "LCDdrive.h" // Header file needed to access to LCD custom
// library
void main(void)
{
char myString[] = {"Embedded Systems"}; // Initialise an array with a string
unsigned short i; // Indexing variable
LCD_initialise(); // Initialise the LCD ready for use
LCD_puts(myString); // Display the myString string
LCD_cursor(0,1); // Move the cursor to the 2nd line
LCD_cursor_on(); // Turn flashing cursor ON
// Illustration of the putch() function
__delay_ms(2000); // Wait 2 seconds
LCD_putch('A'); // Print character A
__delay_ms(2000); // Wait 2 seconds
LCD_putch('B'); // Print character B
__delay_ms(2000); // Wait 2 seconds
LCD_putch('C'); // Print character C
__delay_ms(2000); // Wait 2 seconds
LCD_cursor_off(); // Turn flashing cursor OFF
for (i=0; i<1000; i++) // Set up loop to display counting numerals
{
LCD_cursor(4,1); // Move the cursor to the column 4 on the 2nd line
LCD_display_value(i); // Display the value of x at the cursor position
__delay_ms(100); // Short delay
}
}
The main parts are:
Displaying numerical value
for (i=0; i<1000; i++) // Set up loop to display counting numerals
{
LCD_cursor(4,1); // Move the cursor to the column 4 on the 2nd line
LCD_display_value(i); // Display the value of x at the cursor position
__delay_ms(100); // Short delay
}
A flashing cursor
LCD_cursor_on(); // Turn flashing cursor ON
Printing of individual characters
__delay_ms(2000); // Wait 2 seconds
LCD_putch('A'); // Print character A
__delay_ms(2000); // Wait 2 seconds
LCD_putch('B'); // Print character B
__delay_ms(2000); // Wait 2 seconds
LCD_putch('C'); // Print character C
__delay_ms(2000); // Wait 2 seconds
Printing of a string
LCD_initialise(); // Initialise the LCD ready for use
LCD_puts(myString); // Display the myString string
Outcome:
Uploaded program worked by demonstrating functions that has been created for the exercise. The message is shown on the LCD. Characters are displayed at 2 seconds delay. Number are then displayed at 100 ms delay. This is how the program should work so it worked expectedly.
Conclusion:
Demonstration of the custom built LCD libraries have been received through this program.
Exercise 2 – Animation using LCD display
Aim of exercise:
Animation is to be created using the LCD library functions.
Procedure:
Code given has been compiled and is given below:
// Filename: Lab3Ex2.c
// Version: 1.0
// Date: 3-11-2016
// Author: TALAL
// Description: Simple animation using the LCD custom library functions
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
#include "LCDdrive.h" // Header file needed to access the LCD custom
// library
void main(void)
{
char myString[] = {"LCDs are great"}; // Initialise an array with a string
unsigned short i; // Indexing variable
LCD_initialise(); // Initialise the LCD ready for use
LCD_puts(myString); // Display the myString string
while(1) // Infinite loop
{
for (i=0; i<16; i++) // Set up loop to move character
{
LCD_cursor(i,1); // Move cursor into position
LCD_putch('O'); // Display character
__delay_ms(200); // Short delay
LCD_cursor(i,1); // Move the cursor back to original position
LCD_putch(' '); // Erase character
}
}
}
The program flow chart derived from the explanation and study of the code is given below:
The program has been modified so that now the animation to the right of LCD screen and when the last place is reached it changes direction. Added code to the main program is given below:
// Filename: Lab3Ex2.c
// Version: 1.0
// Date: 3-11-2016
// Author: TALAL
// Description: This part has been done to bring the character back
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
#include "LCDdrive.h" // Header file needed to access the LCD custom
// library
void main(void)
{
char myString[] = {"LCDs are great"}; // Initialise an array with a string
unsigned short i; // Indexing variable
LCD_initialise(); // Initialise the LCD ready for use
LCD_puts(myString); // Display the myString string
while(1) // Infinite loop
{
for (i=0; i<16; i++) // Set up loop to move character
{
LCD_cursor(i,1); // Move cursor into position
LCD_putch('O'); // Display character
__delay_ms(200); // Short delay
LCD_cursor(i,1); // Move the cursor back to original position
LCD_putch(' '); // Erase character
}
for (i=15; i>0; i--) // Set up loop to move character
{
LCD_cursor(i,1); // Move cursor into position
LCD_putch('O'); // Display character
__delay_ms(200); // Short delay
LCD_cursor(i,1); // Move the cursor back to original position
LCD_putch(' '); // Erase character
}
}
}
Outcome:
Uploaded program worked by displaying the string and moving the running animation. Then the modified code ensured that the running animation changes direction when reaches the end.
Conclusion:
A fully running animation has been created by using the LCD functions.
Exercise 3 – Displaying numerical information
Aim of exercise:
The main objective of the exercise is to be able to create a program that sorts the odd numbers between 1 and 99 and displays them on the LCD at 0.5 second delay between each update.
Procedure:
The program was first designed to know how the odd numbers can be detected by the program. This can be done by a simple division by 2. Odd values will have remainders and even values won’t and this way odd numbers will be detected.
Code:
// Filename: Lab3Ex3.c
// Version: 1.0
// Date: 3-11-2016
// Author: TALAL
// Description: Display of the odd numbers between 1-99
#define _XTAL_FREQ 3276800 // This tells the compiler that the 16F877A
// is clocked at 3.2768 MHz. Required by the
// __delay_ms macro.
#include // Required for all MPLAB XC8 source files
#include "LCDdrive.h" // Header file needed to access to LCD custom
// library
void main(void)
{
unsigned short i; // Indexing variable
LCD_initialise(); // Initialise the LCD ready for use
for (i=1; i<100; i++) // Set up loop to display counting numerals
{
if (i % 2)
{
LCD_cursor(0,1);
LCD_display_value(i); // Display the value of i at the cursor position
__delay_ms(500);
} // Short delay
else
{
__delay_ms(500); // Short delay
}
}
}
Flow chart:
Outcome:
This program perfectly displays all he odd numbers between 1 and 99 and displays them with a interval of 0.5 second on the LCD screen.
Conclusion:
Required program has been developed and tested successfully.
Laboratory Practical 4 – Timer0 module
DATE: 10-11-2016
ROOM: CWG/02
Laboratory Aim:
This lab will introduce to the timer0 module that is available for the PIC16F877A. This module is one of the main three timers/counters of the PIC. Precise delays and deterministic timing can be generated using the timers for various applications and this is demonstrated in this lab. Configuration and programming of this timer0 module is the main aim of this lab.
Exercise 1 – Creating a simple delay using Timer0 module
Aim of exercise:
Main aim of the exercise is to be able to create a simple delay using the timer0 in timer mode.
Procedure:
The code for the exercise has been provided. By studying the code flow chart of the program is given below.
The timer calculation equation is also provided in the lab sheet which has been used to calculate the delay produced.
TMR0 count = 256 - preload
Prescaler is set = 256
Delay=(4 x 256 x 256)/(3.2768 MHz)=80ms
Code:
// Filename: Lab4Ex1.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: Simple demonstration of a timer delay
#include // Required for all MPLAB XC8 source files
void main(void)
{
unsigned char preload = 0x00; // TMR0 preload variable
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bit field to 111 for 1:256
while(1) // Infinite loop
{
TMR0 = preload; // Preload timer0
while(!INTCONbits.TMR0IF); // Delay loop: Wait until TMR0 overflows
INTCONbits.TMR0IF = 0; // Reset overflow flag, TMR0IF
PORTD++; // Increment PORTD
}
}
Outcome:
Code works as it should by increasing the PORTD LEDs at 80 ms interval in binary values. Other values of TMR0 has been tried such as 100, 150 and the delay becomes less and this can be observed on the LEDs. Stopwatch shows that the delay is accurate.
Conclusion:
Exercise has been completed successfully by creating a small delay using timer0 in timer mode.
Exercise 2 – Creating longer delays
Aim of exercise:
Aim is to create a longer delay by cascading number of short delays.
Procedure:
The code for the exercise has been provided. The timer calculation equation is also provided in the lab sheet which has been used to calculate the delay produced.
TMR0 count = 256 - 192
Prescaler is set = 256
Delay=(4 x 256 x 64)/(3.2768 MHz)=20ms
This has been cascaded 8 times to get a delay of 160 ms.
Code:
// Filename: Lab4Ex2.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: Looping of a short timer delay to create a longer one
#include // Required for all MPLAB XC8 source files
void main(void)
{
unsigned char preload = 192; // TMR0 preload variable
unsigned char i; // Loop index variable
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1) // Infinite loop
{
for(i=0;i<8;i++) // Loop to cascade several short delays together
{
TMR0 = preload; // Preload timer0
while(!INTCONbits.TMR0IF); // Delay loop: Wait until TMR0 overflows
INTCONbits.TMR0IF = 0; // Reset overflow flag, TMR0IF
}
PORTD++; // Increment PORTD
}
}
For one second delay,
TMR0 count = 256 - 224
Prescaler is set = 256
Delay=(4 x 256 x 32)/(3.2768 MHz)=10ms
This has been cascaded 25 times to get a delay of 1 s.
25 x 40 ms = 1 s delay total in cascade.
Code:
// Filename: Lab4Ex2.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: one second delay
// Creates a one second delay
#include // Required for all MPLAB XC8 source files
void main(void)
{
unsigned char preload = 224; // TMR0 preload variable 224
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1) // Infinite loop
{
for(i=0;i<100;i++) // Loop to cascade several short delays together
{
TMR0 = preload; // Preload timer0
while(!INTCONbits.TMR0IF); // Delay loop: Wait until TMR0 overflows
INTCONbits.TMR0IF = 0; // Reset overflow flag, TMR0IF
}
PORTD++; // Increment PORTD
}
}
Outcome:
Code works as it should by increasing the PORTD LEDs at 160 ms interval in binary values. Stopwatch shows that the delay is accurate. 1 second delay code works as well by increasing the PORTD LEDs at 1 second interval in binary values. Stopwatch shows that the delay is accurate.
Conclusion:
Exercise has been completed successfully by creating a long delay by cascading a number of small delay using timer0 in timer mode.
Exercise 3 – Creating a one second delay function
Aim of exercise:
One second delay function will be created that can be used in any program.
Procedure:
The two values created previously: number of loops and the size of the delay needed to be put in the code provided which was done to get the 1 second delay function required by the exercise. The compiled code is given below.
// Filename: Lab4Ex3.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: Implementing a Timer0 delay function
#include // Required for all MPLAB XC8 source files
void one_sec_delay (void); // Function prototype
void main(void)
{
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
while(1) // Infinite loop
{
one_sec_delay(); // Call delay function
PORTD++; // Increment PORTD
}
}
void one_sec_delay (void)
{
unsigned char preload = 224; // TMR0 preload variable 224
unsigned char i; // Loop index variable
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
for(i=0;i<100;i++) // Loop to cascade several short delays together
// Number of loops derived from Ex2
{
TMR0 = preload; // Preload timer0
while(!INTCONbits.TMR0IF); // Delay loop: Wait until TMR0 overflows
INTCONbits.TMR0IF = 0; // Reset overflow flag, TMR0IF
}
}
Outcome:
1 second delay code works as a function as well by increasing the PORTD LEDs at 1 second interval in binary values. Stopwatch shows that the delay is accurate.
Conclusion:
Exercise has been completed successfully by creating a one second delay function.
Exercise 4 – Creating a variable delay function
Aim of exercise:
Aims to develop a variable delay function that can produce integer multiples of 1 second delay that has been created earlier in the lab session.
Procedure:
The code that has been compiled and developed for this purpose is given below.
// Filename: Lab4Ex4.c
// Version: 1.0
// Date: 10-11-2016
// Author: TALAL
//
// Description: implementation of a variable delay
#include // Required for all MPLAB XC8 source files
void delay (unsigned char delay_length); // Function prototype
void main(void)
{
// PORTD setup
TRISD = 0x00; // Set PORTD all outputs
PORTD = 0x00; // Clear PORTD
while(1) // Infinite loop
{
delay(1); // Call delay function
PORTD++; // Increment PORTD
}
}
void delay (unsigned char delay_length)
{
unsigned char preload = 224; // TMR0 preload variable 224
unsigned char i; // Loop index variable
//Timer0 setup
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
for(i=0;i // Required for all MPLAB XC8 source files
void main(void)
{
TRISD = 0x00; // Set up ports
PORTD = 0x00;
INTCON = 0xA0; // SET GIE, TMR0IE
// Set up Timer0 for 80 ms per overflow
OPTION_REGbits.T0CS = 0; // Set clock source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1); // Do nothing
}
// Interrupt service routine
void interrupt myISR(void)
{
if(TMR0IF) // Timer0 overflow interrupt specific code
{
PORTD++;
INTCONbits.TMR0IF = 0; // Reset flag
}
}
Outcome:
The interrupt is working properly which has been confirmed by the incrementing LEDs of PORTD at every 80 ms. this code for LED is in the interrupt service routine so it can only work if the program is interrupted and goes into ISR.
Conclusion:
Learnt how to successfully create an interrupt using timer0 and the full functionality of this interrupt. Also understanding of interrupt service routine has been gained.
Exercise 2 – Creating precise delays using interrupts
Aim of exercise:
To create a precise delay that increments PORTD LEDs at a rate of 1 Hz.
Procedure:
In order to do this: TMR0 value is reset after every interrupt to 224 in ISR. The PORTD LEDs will only update after 100 interrupts which has been put in an if/else statement. This counting is done in the ISR after every interrupt. The code is given below:
// Filename: Lab5Ex2.c
// Version: 1.0
// Date: 24-11-2016
// Author: TALAL
//
// Description: Precise one second delay using interrupt
#include // Required for all MPLAB XC8 source files
unsigned char cont=0; //this variable counts number of interrupts
void main(void)
{
TRISD = 0x00; // Set up ports
PORTD = 0x00;
INTCON = 0xA0; // SET GIE, TMR0IE
// Set up Timer0 for 80 ms per overflow
OPTION_REGbits.T0CS = 0; // Set cloccont source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1); // Do nothing
}
// Interrupt service routine
void interrupt myISR(void)
{
if(TMR0IF) // Timer0 overflow interrupt specific code
{
cont=cont+1; //count events of interrupt
if(cont==100)
{PORTD++;
cont=0;}
INTCONbits.TMR0IF = 0; // Reset flag
}
TMR0 = 224; // Preload timer0 224
}
Flow chart of the ISR has been created as follows:
Outcome:
Precise delay of 1 s has been created that increments PORTD LEDs at a rate of 1 Hz. This has been confirmed by the use of stopwatch.
Conclusion:
Delay creation of precision level has been learnt through this exercise using timer0 interrupts.
Exercise 3 – Adding background code functionality
Aim of exercise:
To add background functionality to the existing program.
Procedure:
The additional feature is to have bit 7 of PORTB toggling away at a rate of 250ms. This has been done in the code below in a simple manner. XOR gate has been used to toggle using the following truth table:
IP IP output
0 0 0
0 1 1
1 0 1
1 1 0
// Filename: Lab5Ex3.c
// Version: 1.0
// Date: 24-11-2016
// Author: TALAL
//
// Description: Addition of background functionality to the code
#define _XTAL_FREQ 3276800
#include // Required for all MPLAB XC8 source files
unsigned char cont=0; //counts interrupts
void main(void)
{
TRISD = 0x00; // Set up ports
TRISB = 0x00; // Set up ports
PORTD = 0x00;
PORTB = 0x00;
INTCON = 0xA0; // SET GIE, TMR0IE
// Set up Timer0 for 80 ms per overflow
OPTION_REGbits.T0CS = 0; // Set cloccont source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1)
{
PORTB = PORTB ^ 0x80; //Toggle bit 7 of PORTB
__delay_ms(200); //short delay
}
}
// Interrupt service routine
void interrupt myISR(void)
{
if(TMR0IF) // Timer0 overflow interrupt specific code
{
cont=cont+1; //count events of interrupt
if(cont==100)
{PORTD++;
cont=0;}
INTCONbits.TMR0IF = 0; // Reset flag
}
TMR0 = 224; // Preload timer0 224
}
Outcome:
Bit 7 of PORTB toggling away at a rate of 250ms and this has been observed meaning the program written is working properly as needed.
Conclusion:
More operations can be added in the main program body while the interrupt is implemented.
Exercise 4 – Servicing multiple interrupts
Aim of exercise:
Two interrupts can be implemented and serviced in a code and this will be demonstrated by this program.
Procedure:
INTCON = 0xB0; RB0 interrupt is enabled as well.
PORTB reconfigured to ensure that bit 0 is input now.
Code is below:
// Filename: Lab5Ex4.c
// Version: 1.0
// Date: 24-11-2016
// Author: TALAL
//
// Description: multiple interrupt implementation
#define _XTAL_FREQ 3276800
#include // Required for all MPLAB XC8 source files
unsigned char cont=0; //count
void main(void)
{
TRISD = 0x00; // Set up ports
TRISB = 0x01; // Set up ports RB0=Input for interrupt
PORTD = 0x00;
PORTB = 0x00;
INTCON = 0xB0; // SET GIE, TMR0IE and RB0/INT
// Set up Timer0 for 80 ms per overflow
OPTION_REGbits.T0CS = 0; // Set cloccont source to internal (timer mode)
OPTION_REGbits.PSA = 0; // Set prescaler to Timer 0
OPTION_REGbits.PS = 7; // Set prescaler bits to 111 for 1:256
while(1)
{
PORTB = PORTB ^ 0x80; //Toggle 0x80
__delay_ms(250); //short delay
}
}
// Interrupt service routine
void interrupt myISR(void)
{
if(INTF) // RB0/INT interrupt specific code
{
PORTD = 0x00;
INTCONbits.INTF = 0; // Reset flag
TMR0 = 224; // Preload timer0
}
else if(TMR0IF) // Timer0 overflow interrupt specific code
{
if(TMR0IF) // Timer0 overflow interrupt specific code
{
cont=cont+1; //count events of interrupt
if(cont==100)
{PORTD++;
cont=0;}
INTCONbits.TMR0IF = 0; // Reset flag
}
TMR0 = 224; // Preload timer0 224
}
}
Outcome:
Both interrupts have found to be working correctly. Especially RB0 interrupt works by resetting the PORTD when pressed.
Conclusion:
It is very straightforward to have and service two interrupts in a code.