You are on page 1of 24

Microcontroller Report

EE312: Instrumentation and Microcontroller


1/27/2012 University of Strathclyde Jeswin Mathew 200901475 Electrical and Mechanical Engineering

Table of Contents
Introduction ............................................................................................................................................................. 2 Operation of a Microcontroller ............................................................................................................................ 2 Application .......................................................................................................................................................... 2 Interrupts ............................................................................................................................................................ 2 Interrupt Vectors ................................................................................................................................................. 3 Timers................................................................................................................................................................. 3 Laboratory Procedure and Code Dissection ........................................................................................................... 4 Tutorial 1&2: ....................................................................................................................................................... 4 Tutorial (Hardware): ............................................................................................................................................ 4 Tutorial 3: Basic port I/0 Operations and Display Driving ................................................................................... 5 Tutorial 4: Interrupts............................................................................................................................................ 7 Tutorial 5: Timers and ADC .............................................................................................................................. 10 Tutorial 6: Drivers ............................................................................................................................................. 12 Conclusion ............................................................................................................................................................ 13 References............................................................................................................................................................ 13 Appendix ............................................................................................................................................................... 13

Introduction
Operation of a Microcontroller
A simple Diagram of the microcontroller is shown below:

The microcontroller contains a CPU to execute code and make decisions. The RAM and ROM are used as memory blocks; the ROM is a (Read only memory) and cannot be changed. It also contains peripheral units such as timers, serials and I/O. The I/O is used to interface with the outside world. The microprocessor is dedicated to one program only which is stored in its RAM. [2]

Application
A microcontroller has numerous applications in modern society. Electronic appliances either industrial or household incorporate embedded systems to monitor and manage its functionality. An application of microcontroller is the motion detectors which are used to switch on and off lights when a person enters/leaves the room using infra-red sensors to detect body heat. A motion sensor may also possess its own lighting function that controls the lightings. Microcontrollers are equipped with ADC convertors to interface with the infrared sensors that can send the data to a microprocessor which then makes the decision using the pre-defined data stored in its memory by sending a digital signal to the DAC which then sends it to I/Os available so that it can interface with the control for the lighting. The timers in the microcontroller also come into play: the timer starts when nobody is in the room and then counts until a defined timer period at which the processor will make the decision to switch off. The interrupt functionality of a micro controller can be activated when a person comes in while the timer is counting.[4]

Interrupts
The sequential processing in Micro-controllers unlike computers cannot be changed while the process is running. An interrupt is an input to a microprocessor that temporarily redirects the program flow [1]. On trigger the microprocessor saves the current location and the status register and the program branches to an interrupt routine set in the interrupt vector table. A trigger may include a new data on an ADC, overflow in a timer or a switch being pressed; all these hardware possess their own interrupt inputs in the interrupt vector table along 2

with the location of the interrupt service routine (The processes to be executed by the microprocessor). Once the routine designed to the interrupt is completed the processor retrieves the return address from the stack and resumes execution [1].

Interrupt Vectors
Interrupt vectors direct the processor to the required location of the interrupt routine to be serviced. The destination is labelled as the interrupt service address/process [1] and this performs whatever functions are required. Most microprocessors possess a pre-defined vector table that specifies the address where the processor must go when a hardware requests interrupt. Interrupts can either be edge or level sensitive. In the control register for the interrupt vector, the interrupt can be programmed to be the former or the latter. A level sensitive is acknowledged by the microprocessor only if the interrupt pin is active (A switch being depressed is equivalent to Boolean 0 and this makes the pin active)

Timers
Timers are a crucial part of embedded systems and they provide a clock for initiating events. It measures the time taken between events or pulses. The highest frequency available is from the crystal frequency on the microcontroller and the various frequencies available is determined by the prescaller (frequency divider). The crystal clock frequency available on the M16C is 16MHz. Timers can be set as event counters:[2] Counting the external number of pulses Transition of input pin Overflow from other timers: This functionality allows timers to be cascaded

Timers are able to generate interrupts for functions that require a precise timing mechanism (e.g. a real time clock) and have interrupt vectors in the vector table containing addresses for the routine to be serviced. The M16C timers have the following control registers most of which are given in the appendix:[2] Mode Register: this controls the operating mode of the timer. Interrupt control register: this is for when an event has occurred. One shot start register: this enables the use of a single counter. Trigger select register: this is used to select the trigger source to count events when the timer is in event counter mode.

Laboratory Procedure and Code Dissection


Tutorial 1&2:
The above tutorials introduced the software IAR embedded workbench which is an integrated development environment and also how to program an M16C microcontroller. Before starting the software, a hardware check was conducted to ensure the e8a emulator was connected to the microcontroller and the other end connected to the computer. The emulator was used in the erase flash and connect mode The first task was to the hello world project which involved printing hello world on to the I/O terminal in the IAR workbench. A new project was created using the tool chain M16C. In the project settings writable constraints were selected and the microcontroller selected was the M30626FJP. In the Library configurations the full DLIB was used. The e8a emulator was used as the debugger In the new project a C file was added. The code simply stated printf (Hello World) thus printing it to the console. The next project was called the Fibonacci series. The C file was available in class called utilities.c which printed out the Fibonacci series to the console.

Tutorial (Hardware):
The hardware tutorial enabled to understand the key aspects in microcontroller operation that supplemented the lecture slides. The development board supplied is a Renesas R0K33062PS001BE starter kit. The board is based around an M16C M30626FJPGP in a 100 pin package and a number of peripheral devices, including user LEDs, switches, a potentiometer and an LCD display [2]. The M30626FJPGP has a number of units in a single chip and is shown in the figure below. These include: RAM and ROM to store instructions and data CPU to execute logic operations Peripheral units : timers, ADC, I/O ports etc.

1. Tutorial 3: Basic port I/0 Operations and Display Driving


The objective of this tutorial was to manipulate the functionality of the I/O ports on the micro-controller to produce a visual output (Flashing LEDs and LCD Display). The tasks undertaken in the tutorial along with the strategy undertaken and the dissection of the code used is examined below: Problem Statement: To flash a single LED on the microcontroller during intervals of approximately a second without the aid of timers. Strategy: Two variables called f and clock were initialized these variables were used to control the timing for the flashing mechanism. The port direction registers for the LEDs were set to output mode which is indicated by the statement PD4=0xFF. (Ox is used to represent Hexadecimal values and FF in binary is 11111111). The microcontroller has 4 LEDs and the port connections were accessed using the p4_X statement (X is the LED port number that requires to be accessed). Initially all ports were switched off - 'P4=0xFF. The LED flashing mechanism is a iterative process and in order to ensure continuity the while (1) statement was employed i.e. while the statement is in the bracket is non-zero (true)- which is always the statements listed within the loop is sequentially executed (This is a significant characteristic of C programming). This infinite loop is reiterated throughout the laboratory tutorials for programmes with varying complexities and is regularly referred to in the report. In the WHILE control loop the LED 0 p4_0 was set to the value of f which is initially set to zero and this turns on the LED. The next statement increments the variable clock by 1 every time control passes back to the beginning of the loop. The if statement controlled the variable f and when the expression in true - if (clock == 10000)- the value of f is alternated between 0 and 1; which subsequently switches the LED on and off for approximately a second (10000 was empirically approximated to be a second). The functionality is portrayed in the flow diagram in figure.
if (clock == 10000) clock = 0 if (f == 1) if (f == 0) f = 0 f = 1 p4_0 = f

1)

2)

while (1)

Problem Statement: Switch on a single LED on the microcontroller when a switch on the board is depressed and switch off when another switch is pressed. Strategy: The procedure adopted was similar to the previous task in tutorial 3. The LED port direction registers were set to output and all ports were switched off initially. The port direction register for the three switches were set to input PD8 = 0x00 and switch1 (sw1) and switch 2(sw2) were set to zero initially. These switches were accessed using the pins p8_2 && p8_3 respectively. If the switch pin is set to zero in the control statements then this corresponds to the switch being depressed on the board. The infinite loop used in the previous exercise was employed and control statements were used within the loop to ensure the specification was met: if switch1 was depressed the LED switches on; whereas if switch 2 was depressed the LED switches off. The algoritham is elaborated in the flow diagram shown in figure. if(p8_2 == 0) p4_0 = 0
if(p8_3 == 0) p4_0 = 1

3)

Problem statement: Display the string Hello World on the LCD module. Strategy: This is the first task that incorporates the LCD module integrated to the micro controller. The drivers file for the LCD was available from class and the functions used were InitialiseDisplay () and DisplayString (LCD_LINEX, char* string). The former switches on the LCD module and is usually stated in the main() function; the latter requires two arguments the line number X on the LCD that the string requires to be displayed and then the string itself (This function can be used in any location of the code). Therefore a string called Hello World was displayed in line1 of the LCD. Problem statement: Receive a string from the PC and verify the number of vowels and consonants in the string. Display the numbers on the LCD module. Strategy: The LCD module functions are elaborated in the previous tutorial. The problem was tackled in a sequential manner: String is received from the PC. This information was stored in the string char*test Two other strings were initialized: One containing the vowels in upper and lower cases char* sample = "aeiouAEIOU" and another string containing all the miscellaneous characters that cannot be classified as a consonant or a vowel char* sample1 = ".,/'?&(-};\\:%<>$!@1234567890#". Three integer variables that store the string length (strlen) of test (int length), sample (int sample_length) and sample1 (int sample1_length) were initialized. The next step in the procedure entailed filtering the spaces in the string test so that these dont get counted as consonants or vowels. This was performed by verifying every element of test (The elements were accessed using test[f] where f is incremented every time the control returns to the beginning of the loop.
for(f =0; f<length; f++){ if (test[f] == ' ') {x++;}}

4)

After the spaces were filtered, the next step involved comparing every element of the string sample1 with every element in test. This was achieved by looping (using a FOR loop) an element of sample with every element of test and incrementing the integer variable vowels every time the verification returns a non-zero value (true).
for (p =0; p < sample_length1; p++) { value1 = sample1[p]; for (m =0; m < length; m++){if(test[m] == value1){x++;} } }

The final step in the code proceeded to compare every element of the vowels character array sample to every element in the test string. The same procedure outlined previously was employed only this time test is checked for vowels.
for (i =0; i< sample_length; i++) { value = sample[i]; for (j =0; j < length; j++){if(test[j] == value){vowels++;} } } For all the above steps the elements of string test were accessed by expressions such as test[m], test[j] and test[f] where m,j and f are incremented when control returns to beginning of the loop. This

technique was also used to access elements of the strings sample and sample1. The next logical step was to conclude the number of consonants present in test which is simply length of string (vowels + x).
Consonants = (length - vowels)-x

Finally the information obtained on the number of consonants and vowels were stored into a character array using the sprintf function - vowels were stored in string1 and consonants in string 2 and then displayed on the LCD module using the functions aforementioned.
char*test For 0: strlen (test) If test[f] == ' x++ If test[f] == char* sample1

If test[f] == char* sample

Vowels++

Consonants = (length - vowels)-x

Tutorial 4: Interrupts
Interrupt is a primary characteristic of micro-controllers that introduces the ability to halt a running program and switch to another program. The tasks undertaken in the tutorial along with the strategy undertaken and the dissection of the code used is examined below: 1) Problem Statement: Turn on an LED when a switch is depressed and another LED when another switch is pressed. Only a single LED should be switched on at any given time. This has to be done without monitoring the pins directly and thus with the use of interrupts Strategy: The specification required that the LEDs should not be monitored directly. This is the first task in the tutorial where the interrupts vector table and control registers were introduced. Since the task is to switch LEDs on/off, the processor is performing nothing when no interrupt is called. The header file iom16c62p.h contains all the interrupt definitions for the hardware on the microcontroller. The header file which contains the programming interface for interrupts is intinsics.h; this library is included in programs where interrupts are crucial. A detailed elucidation of the functions is given below: #pragma vector = interrupt Informs the microprocessor which interrupt has been called. For switches 1&2 used for in the tutorials the interrupt hardware are given as INTO and INT1 respectively in the vector table. _interrupt void function (void): The interrupt routine (The set of instructions for the processor must execute for that particular interrupt) is encapsulated within this function. The processor executes the codes and then returns to its previous location. (For this problem the processor is idle after interrupt is serviced). _enable_interrupt (): Enables interrupt mode. Due to the simplicity of the program, no interrupt priorities were set. All interrupts have same priority. Interrupt control registers (attached to appendix) for both the hardware was programmed to service interrupt with the highest priority (Equal Priority at level 6):
INT0IC = 0x06; INT1IC = 0x06;

The interrupt service routine (ISR) for switch1 (INT0) was simple: turn on LED 0/turn off LED 1 and the ISR for switch2 (INT1 ) was vice-versa as requested by the specification.
__interrupt void sw_int0 (void) { p4_1 = 1; p4_0 = 0;

} _interrupt void sw_int1 (void) { p4_1 = 0; p4_0 = 1; }

ports were switched off - 'P4=0xFF

The while (1) loop ensures that the program runs infinitely while waiting for an interrupt. Initially all LED Switch 0 Interrupt Request Interrupt Vector Table INT0 Microprocessor Switch on LED0 Switch off LED 1

Interrupt Request Switch 0

Interrupt Vector Table INT1

Switch on LED1 Switch off LED 0

2) Problem Statement: Turn on an LED when a switch is depressed and turn off the LED when no switch has been pressed for a second. Strategy: The settings for the interrupts are identical to the previous tutorial which gives it a more rigorous treatment. This time only one switch was required according to the specification. The only dissimilarity is that there is a program running when no interrupt is requested. All the settings for the LED ports are identical to previous tutorial. The methodology is straightforward: Switch1 (INT0) requests an interrupt when it is pressed and the interrupt service routine switch on the LED and at the same time resets a timer.
__interrupt void sw_int0 (void) { counter = 0; p4_0 = 0; }

When there is not interrupt requested a program is running in the background. This set of instructions enclosed within the infinite loop: Increments the integer variable counter by 1: counter++. When the value of counter is 43250 (Approximately 1 sec) the LED is switched off and counter is reset: p4_0 = 1; counter =0;. This instruction is reiterated when control returns to the start of the loop and thus the LED is always switched off unless an interrupt is requested according to specification.

Switch 0 Interrupt Request Program to run when no interrupt is requested while (1) Microprocessor If no interrupt

Integer Counter is incremented and reset after 43250 LED stays switched off after one loop

Interrupt Vector Table INT0

Switch on LED 0

3) Problem Statement: Evaluate the number of times that switch one or switch two has been pressed and display the data on the LCD module. Strategy: Two integer variables called count and count1 were initialized. Also two character arrays to hold the data for the aforementioned variables were also initialized. The settings for the interrupts are identical to the previous tutorial 4:1 and makes use of two interrupt hardware (Switch1 &2). The functions used for the operation of the LCD module are the same as tutorial 3:3. The methodology is similar to the two previous tutorials: The interrupt service routine (ISR) for switch1 (INT0) ensures that the variable count is incremented every time INT 0 requests an interrupt (switch one is pressed). As the count is being incremented, the value is stored in string1 using sprint and displayed in LCD line 1.
count++; sprintf(string1,"sw1 %i",count); DisplayString(LCD_LINE1, string1);

The interrupt service routine (ISR) for switch2 (INT1) ensures that the variable count1 is incremented every time INT 1 requests an interrupt (switch two is pressed). As the count is being incremented, the value is stored in string2 using sprint and displayed in LCD line 2.
count1++; sprintf(string1,"sw1 %i",count1); DisplayString(LCD_LINE1, string2);

Switch 0 Interrupt Request Interrupt Vector Table INT0 Microprocessor

Interrupt Request Switch 0

Integer Count is incremented and value is displayed on Line 1

Interrupt Vector Table INT1 Integer Count1 is incremented and value is 9 displayed on Line 2

4) Problem Statement: Evaluate the number of times that switch one or switch two has been released after pressing and display it on the LCD module. Strategy: The technique employed to tackle this problem is similar to the previous tutorial. As per the specification requirements the variables count and count1 are only incremented when the corresponding switches are released. This was achieved by changing the settings of the control register for INT0IC and INT1IC to Ox16. This translates to 00010110 in the interrupt control register and stipulates that the interrupt is requested at the rising edge i.e. when the switch is released.
INT0IC = 0x16; INT1IC = 0x16;

Tutorial 5: Timers and ADC


The objective of this tutorial was to introduce the concept of timers in microcontrollers and frequency division. Until this tutorial the timing mechanism for an event was performed by an integer variable. Now the task is allocated to timers in the M16C62P. The tasks undertaken in the tutorial along with the strategy undertaken and the dissection of the code used is examined below: 1) Problem Statement: Flash an LED on/off with the aid of timers on the microcontroller. Strategy: This is the first task that incorporates timers available on the microcontroller. In this tutorial two timers were used due to the requirement for frequency division to increase the duration to a second. Timers, like hardware interrupts, have addresses in the vector table so that when the timing mechanism is completed, the processor can access the interrupt service routine for the timing interrupt. The settings in the control registers for the two timers are shown below and this is the primary setting for the remaining part of this tutorial. Timer0 was set to free running mode in the timer mode register: TA0MR =0x00 (00000000 corresponds to free running mode in the register). Timer 1, on the other hand, was set to even counter mode to count overflows of timer 0: TA0MR =0x01 (00000001 corresponds to event counter mode in the register). The Timer register for timer 0 was set to 6000 thus increasing the period to 1ms. This is because the input to timer 0 is the 16 MHz crystal clock available on the microcontroller. TRGSR = 0x02|(TRGSR &~0x03 sets the trigger source for timer1 which is the overflow in timer 0. 0x02 in the trigger input register selects TAO (timer 0) as the trigger source for Timer A1(timer 1) and corresponds to binary code 00000010. TA1 = 1000: Timer A1 counter register is set 1000 thus giving an output of 1sec. The interrupt request for Timer A1 in the interrupt vector table is given as TA1IC& 0x08. TABSR|= 0x03: This is the setting in the TABSR register and setting forces the timers to start counting again once the interrupts have been reset using TA1IC &= 0xF7. The settings for the LED Ports are the same as in Tutorial 1. Once the various control registers for the two timers were configured, the next step was to switch on/off an LED every second. This was achieved by using the simple logic statement, next LED level =! (Current LED level) and this line of code is executed every time an interrupt from Timer A1 is requested - if(TA1IC& 0x08) {p4_0 = !p4_0; TA1IC &= 0xF7;}

while (1)

If Timer A1 requests interrupt

LED =!LED

TA1MR Trigger TA0MR Overflow 10

2) Problem Statement: Design a real time clock in software which counts only minutes and seconds and should not start until the current time in minutes is send to the PC. The clock should send the time to the PC every 15seconds. Strategy: The control register settings for Timers A0 and A1 are identical to the previous tutorial. Two integer variables were initialised called minutes and seconds. Using the function scanf the user input data for minutes was extracted from the P.C into a character array called Minute -. scanf ("%s",Minutes) . Then using the function atoi the data was converted to an integer and stored in minutes. Once the extraction of required was complete the clock was initiated as per the specification and the mechanism is explained below: Firstly a check if the valid input has been entered was issued: if((minutes <1440)&&(minutes >=0)) .There are 1440 minutes in a day. If the data was not within the specified range then the message Invalid Input was printed. Once the first verification was complete, the second step confirms that an interrupt has been requested by Timer A1 and also if the variable seconds is less than 60.
if((TA1IC& 0x08)&&(seconds < 60))

If the above expression is non-zero then seconds is incremented by 15 and is printed on the console. The specification requires that the time should be printed every 15 seconds (seconds += 15) but should count continuously. In order to meet this requirement the register for Timer A1 was set to 15000 before an interrupt is requested - TA1 = 15000. The above remedy was seen as a shortcut to counting continuously. Once seconds reached 60, the variable was set to 0 and at the same time minutes was incremented by one prior to printing it to the console. This makes use of the sequential processing in C programming.

Scan User Input

If User input is between 0&1440

If Interrupt has been requested and seconds<60 TA1MR Trigger TA0MR Overflow

Seconds++ PRINT

If seconds = 60 Seconds = 0 Minutes++ PRINT

3) Problem Statement: Design a real time clock in software which counts only minutes and seconds and

should not start until the current time in minutes is send to the PC. The clock should send the time to the LCD module every 15seconds Strategy: The methodology is identical to the previous tutorial and instead of printing the data to the console, the integer data is transferred to a character array using sprintf and displayed on the LCD module. The display function replaces the printf function used in the previous tutorial.
sprintf(sample,"%i : %i",minutes,seconds); DisplayString(LCD_LINE1, sample);

11

4) Problem Statement: Monitor the current DC value output of the potentiometer and display it on the LCD module. Strategy: The settings for the control registers for the three ADC are shown below:
ADCON0 = 0xC8; ADCON1 = 0x20; ADCON2 = 0x00;

An integer variable called set was used to store the value of the ADC and display it on the screen.

Tutorial 6: Drivers
Problem Statement: Display Strings on the LCD module. Strings which are longer than eight characters should be able to be scrolled by the user and the scrolling should continue until a reset button is pressed. Along with the scrolling the screen should flash so that it is more prominent. Minimal resources should be used. Strategy: The specification requests that minimal resources should be used. Therefore only the LCD module was used and no timers were employed. Two functions were created called flash() and scroll(string). The function of flash() is to delay the characters on the screens and display a blank screen for a specific amount of time and thus rendering the user with the notion that the screen is flashing.
DisplayDelay(6000); DisplayString(LCD_LINE1," ");

The function of scroll (string) was to shift through the character array and display it on the LCD module. The timing for this shifting mechanism was just controlled by a integer variable. Once the end of the string has been reached, the mechanism loops back to the start of the string and reiterates the process. This processes was achieved by initialising a character pointer called scroll. An integer variable to evaluate the actual of the input string was also initialised.
char* scroll int length = strlen(input)

In order to avoid the use of timers, an integer variable called counter was incremented every time control was returned to the start of the loop. Once the value of counter reached an arbitrary value(1000), the logic becomes non-zero and counter is reset.
counter ++ if(counter == 1000) {}

Enclosed in the above loop was the scrolling mechanism; Initially the pointer scroll points to the start of the input string - char input[40] and then as the loop returns to the beginning, the pointer shifts one place and points to the remaining characters in input. This is reiterated until scroll is pointing to the last element in the string and then is looped back to the beginning of the string. The shifting function aforementioned was achieved by the addition of input to an integer variable that incremented during each loop.
scroll = (input + i); i += 1;

The LCD module settings are the same throughout all the tutorials.

12

Conclusion
The microcontroller laboratory sessions have created awareness about the necessity for microprocessors in smooth functionality of numerous appliances that require embedded systems. The primary task of a microprocessor in an embedded system is regulation according to measurements acquired. Measurements are vital to monitor and regulate household and industrial appliances: microprocessors can be programmed to react to a certain change in the measurement e.g. turning the heater on due to a decrease in temperature. The tutorials have been able to convey certain crucial concepts such as interrupts in a program, the use of timers to regulate a mechanism that requires timing and the use of several other peripherals. It also alerted me on how certain measurements taken e.g. a change in resistance from a strain gauge and converted using the inbuilt ADC to convey the data to the processor and make decisions or display the result on the screen. This session has prepared me to tackle more advanced microcontroller concepts and the knowledge acquired has been transferrable to other engineering projects undertaken during the year.

References
[1] www-verimag.imag.fr/~sifakis/Computer_ESdiscipline.pdf [2] Microprocessor Notes [3] Hardware Tutorial [4]http://www.renesas.eu/applications/industrial_equipment/lighting_building_maintenance/md/index.jsp

Appendix

Tutorial 3
Part 1
#include <stdio.h> #include "iom16c62p.h" void main(void) { int f = 0; //Variable called f and clock Initialised; int clock =0; PD4=0xFF; //Direction of LED ports set to output

P4=0xFF; //all led's turned off initially while(1) // infinitie loop { p4_0 = f; //LED 0 is set to value of f which is either 1 or 0. // LED zero set to f and LED one set to NOT(f) //Thus obtaining alternate flashing LED'S clock++; // Clock Increament if(clock == 10000)//Delay Until clock hits 10000 {clock = 0; //Reset if(f == 0){f = 1;} // else {f =0;} }}}

Part 2
13

#include <stdio.h> #include "iom16c62p.h" void main(void) { , PD8 = 0x00; //Set Direction of port 8 to Input p8_2 = 0x00; // Set all p8 ports to zero p8_3 = 0x00; PD4 = 0xFF; // Set all LED's to output P4=0xFF; while(1) //Run program forever { if(p8_2 == 0) //If switch 1 is depressed { p4_0 = 0; // LED switches on } else if (p8_3 == 0) // Switch 2 is pressed { p4_0 = 1;} // LED switches off } }

Part 3
#include<stdlib.h> #include<stdio.h> #include<string.h> #include "LCD.h" void main() { InitialiseDisplay();// Function to initialise the display char string1[15] = Hello World; // Character array with DisplayString(LCD_LINE1, string1); }

Part 4
#include<stdlib.h> #include<stdio.h> #include<string.h> #include "LCD.h" void main() { InitialiseDisplay(); int vowels =0; int consonants =0;int i =0; int j = 0;int p = 0;int f=0;int x = 0;int m = 0; //initialise all the variables char*test = "This code is for Tutorial 4 - Question 4."; //The string array that is required to be tested char* sample = "aeiouAEIOU"; // A string with the vowels (Lower and upper case) char* sample1 = ".,/'?&(-};\\:%<>$!@1234567890#";//Miscellaneous Characters int length = strlen(test);int sample_length = strlen(sample); int sample_length1 = strlen(sample1); //The String length of Sample,Sample1

14

and test char value; char value1 ; for(f =0; f<length; f++){ if (test[f] == ' ') {x++;}} //The above loop checks for spaces and filters them out for (p =0; p < sample_length1; p++){ value1 =sample1[p]; for (m =0; m < length; m++){if(test[m] == value1){x++;} } } //The above loop checks for any miscellaneous characters and adds 1 onto x if the Boolean is true for (i =0; i< sample_length; i++) { value = sample[i]; for (j =0; j < length; j++){if(test[j] == value){vowels++;} } } //The above loop checks for any vowel characters and adds 1 onto vowels if the Boolean is true consonants = (length - vowels)-x; // logic! char string1[30]; // Character array to hold the information char string2[30]; sprintf(string1,"Vowel %d",vowels); //Sprintf places the integer into the address of the character sprintf(string2,"Cons %d",consonants); DisplayString(LCD_LINE1, string1); DisplayString(LCD_LINE2, string2); }//Displays vowels in line 1 and consonants in line 2

Tutorial 4
Part 1
#include <stdio.h> #include <intrinsics.h> #include "iom16c62p.h" #pragma vector = INT0 //Interrupt hardware set to switch 1 __interrupt void sw_int0 (void) //Sets interrupt routine for the above interrupt { p4_1 = 1; //LED 0 goes on and LED 1 goes off p4_0 = 0; } #pragma vector = INT1//Interrupt hardware set to switch 2 __interrupt void sw_int1(void) //Sets interrupt routine for the above interrupt { p4_1 = 0; p4_0 = 1; }//LED 1 goes on and LED 0 goes off void main(void) {PD4=0xFF; //Direction of LED ports set to output P4=0xFF; //all led's turned off initially INT0IC = 0x06; //The control register for switch 1 is set INT1IC = 0x06; //The control register for switch 2 is set __enable_interrupt();//Enable interrupts

15

while(1); //Loop and wait }

Part 2
#include <stdio.h> #include <intrinsics.h> #include "iom16c62p.h" #pragma vector = INT0//Interrupt hardware set to switch 1 __interrupt void sw_int0 (void) //Sets interrupt routine for the above interrupt { counter = 0; p4_0 = 0; //counter is set to zero and LED 0 is turned on } void main(void) { unsigned int counter =0; //counter initialised PD4=0xFF; //Direction of LED ports set to output P4=0xFF; //all led's turned off initially //The control register for switch 1 is set INT0IC = 0x06; //The control register for switch 2 is set __enable_interrupt(); // Loop and wait for interrupt from sw1 or sw2 while(1){ counter++; //After ISR is processed the counter starts counting then if (counter ==43250) switches of LED until interrupt is requested { p4_0 = 1; counter =0; } //counter is initialised when switch 1 is pressed

Part 3
#include <stdio.h> #include <intrinsics.h> #include "iom16c62p.h" #include "LCD.h" int count = 0; int count1 = 0; char string1[7]; char string2[7]; //Initialise all variables #pragma vector = INT0 //Interrupt hardware set to switch 1 __interrupt void sw_int0 (void) //Interrupt routine for switch 1 { count++; //Add one onto count every time switch 1 is pressed sprintf(string1,"sw1 %i",count); //Writes count data into string1 DisplayString(LCD_LINE1, string1); } //Display String in line1 #pragma vector = INT1// Interrupt vector set for switch 2 __interrupt void sw_int1(void) //Interrupt routine for switch 1 { count1++; //Add one onto count1 every time switch 2 is pressed sprintf(string2,"sw2 %i",count1); //Writes count1 data into string2 DisplayString(LCD_LINE2, string2); //Display in line 2 } void main(void) { InitialiseDisplay(); //The control register for switch 1 is set INT0IC = 0x06; //Enable interrupt vector which has the highest priority

16

//The control register for switch 2 is set INT1IC = 0x06; //Enable interrupt vector which has the highest priority __enable_interrupt(); Loop and wait for interrupt while(1); }

Part 4
#include <stdio.h> #include <intrinsics.h> #include "iom16c62p.h" #include "LCD.h" unsigned int count = 0; unsigned int count1 = 0; char string1[7]; //Initialising all variables char string2[7]; #pragma vector = INT0//Interrupt vector set for switch 1 __interrupt void sw_int0 (void) //Interrupt routine for { count++; sprintf(string1,"sw1 %d",count); DisplayString(LCD_LINE1, string1);} #pragma vector = INT1//Interrupt vector set for switch 2 __interrupt void sw_int1(void) { sprintf(string2,"sw2 %d",count1); count1++; DisplayString(LCD_LINE2, string2);} void main(void) { InitialiseDisplay(); /* Set INT0 interrupt control reg */ INT0IC = 0x16; /* Set INT1 interrupt control reg */ INT1IC = 0x16; __enable_interrupt(); /* Loop and wait for interrupt from sw1 or sw2 */ while(1);}

Tutorial 5
Part 1
#include <stdio.h> #include <intrinsics.h> #include "iom16c62p.h" #include <stdlib.h> void main() { TA0MR =0x00; /*Set timer for free running mode*/ TA0 = 6000; /* Counts upto 6000 every 1ms at 6MHz*/ TA1MR = 0x01; /*Setting Timer to event mode so that once timer 0 hits 6000 timer 1 will register the count*/ TRGSR = 0x02|(TRGSR &~0x03);//setting trigger source for timer A1 which is the overflow in Timer A0. TA1 = 500;//Every time timer one counts upto 1000 a trigger occurs TABSR|= 0x03; // After resetting the interrupt start counting again. PD4 = 0XFF; P4 = 0XFF;

17

while(1) //Forever { if(TA1IC& 0x08) //If the interrupt has been requested { p4_0 = !p4_0; //Logic! TA1IC &= 0xF7;//reset the interrupt } }}

Part 2
//This is for counting up by 15 second #include <stdio.h> #include <intrinsics.h> #include "iom16c62p.h" #include <stdlib.h> void main() { TA0MR =0x00; /*Set timer for free running mode*/ TA0 = 6000; /* Counts upto 6000 every 1ms at 6MHz*/ TA1MR = 0x01; /*Setting Timer to event mode so that once timer 0 hits 6000 timer 1 will register the count*/ TRGSR = 0x02|(TRGSR &~0x03);//setting trigger source for timer A1 which is the overflow in Timer A0. TA1 = 15000;//Every time timer one counts up to 15000 a trigger occurs. //Specification request TABSR|= 0x03; // After resetting the interrupt start counting again. int minutes; int seconds; //All variables initialised char Minutes[5]; char string1[7]; printf(" Enter a number between 0 and 1440 \n");// there is 1440 minutes in day scanf("%s",Minutes); //Scan user input for minutes minutes = atoi(Minutes); //Convert array to integer while(1) // forever { if((minutes <1440)&&(minutes >=0)) //If user input is correct { if((TA1IC& 0x08)&&(seconds < 60)) //If interrupt has been requested and seconds is less than 60 { printf(" The time is %i : %i \n", minutes,seconds); seconds += 15; //Specification request TA1IC &= 0xF7; //Reset Interrupt if(seconds == 60){seconds =0; minutes++; if (minutes > 1439){minutes =0;}} //Adding one onto minutes after 60 seconds Logic!!

18

} } else if (minutes < 0) //Non valid input { printf("Please enter a valid input \n"); } } }

Part 3
#include <stdio.h> #include <intrinsics.h> #include "iom16c62p.h" #include <stdlib.h> #include "LCD.h"

void main() { InitialiseDisplay(); TA0MR =0x00; /*Set timer for free running mode*/ TA0 = 6000; /* Counts upto 6000 every 1ms at 6MHz*/ TA1MR = 0x01; /*Setting Timer to event mode so that once timer 0 hits 6000 timer 1 will register the count*/ TRGSR = 0x02|(TRGSR &~0x03);//setting trigger source for timer A1 which is the overflow in Timer A0. TA1 = 500;//Every time timer one counts upto 1000 a trigger occurs TABSR|= 0x03; // After resetting the interrupt start counting again. int minutes; //Minutes data int seconds; //Seconds data char Minutes[5]; //Character array to hold minutes data char sample[128]; //Character array to hold the time information printf(" Enter a number between 0 and 1440 \n"); //1440 minutes a day scanf("%s",Minutes); // User needs to enter a minute to start the timer minutes = atoi(Minutes); // array to integer while(1) //forever { if((minutes <1440)&&(minutes >=0)) // if the user has entered correct input { if((TA1IC& 0x08)&&(seconds < 60)) //If interrupt has been requested { //Interrupt requested every second to count up //Transfer the data to a character array and display it in line 1. sprintf(sample,"%i : %i",minutes,seconds); DisplayString(LCD_LINE1, sample); seconds += 15;

19

TA1IC &= 0xF7; //Reset the interrupt if(seconds == 60){seconds =0; minutes++; if (minutes > 1439){minutes =0;}} } } else if (minutes < 0) //Invalid Input { printf("Please enter a valid input \n"); } }}

Part 4
#include #include #include #include #include #include "LCD.h" "iom16c62p.h" <stdio.h> <intrinsics.h> <math.h> <stdio.h>

void main(void) { //initialize variables int set = 0; char Line1[5]; //presets ADCON0 = 0xC8; ADCON1 = 0x20; ADCON2 = 0x00; InitialiseDisplay();

while(1) { //only execute if set and ADO are not equal i.e. there is a change in value if (set != AD0) //ADO contains the value for Potentiometer { //reset check set = AD0; //display on LCD sprintf(Line1,"%03i",set); DisplayString(LCD_LINE1, Line1); } } }

Tutorial 6
#include <stdlib.h>

20

#include #include #include #include #include #include

<stdio.h> "LCD.h" "iom16c62p.h" <string.h> <math.h> "intrinsics.h"

void flash(void) //Specification requests for flashing LCD { DisplayDelay(6000); //Delays the display by a certain time DisplayString(LCD_LINE1," ");//Displays blank during the delay } void scroll(char input[40]) //Scroll Function { char* scroll;// Pointer to scroll through the input string int i = 0; //Initialise all variables unsigned int counter = 0; int length = strlen(input); //Actual length of input scroll = malloc(length*sizeof(char)); //Dynamic memory allocation if (length == 8) //If Length is equal to 8 it can be displayed { DisplayString(LCD_LINE1,input); //Display the string just as it is } else if (length > 8) //Not able to display without scrolling { do { counter ++; // Manual Counter. Specification asks to use minimal resources if(counter == 1000) //Adjustable time { counter = 0;//Reset Counter scroll = (input + i); //Scroll points to the character array DisplayString(LCD_LINE1,scroll); //Display the data that the pointer is pointing to which is input +(i) flash();//Flashing LCD i += 1; if(i == (length-1)) //Loop back to the start of the string { i = 0; } }

}while(1);//Continuous loop } }

21

void main() { InitialiseDisplay();//Display Initialise char user[40]; //Character array for user to enter data fgets(user,40,stdin); int ln = strlen(user) - 1; user[ln] = ' ';//Once the character array is finished the pointer starts pointing to an address. //Therefore the space eradicates this problem

scroll(user);//Calling the scroll Function }

22

23

You might also like