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.