MCB2300 Programming Exercises V3a Exercises for the MCB2300 ARM processor board All programs should be developed and simulated using the u-Vision development system and simulator/debugger. It is essential you become very familiar with these software tools. Useful notes: You can re-use the same project for all these exercises by replacing the 'C' files. Remove the previous 'C' file and add the new 'C' file. Removing a file from a project does not delete the file! Remember the assembler file “startup.s” must be in your project. This is normally added automatically when you create your project. Enable the option "Periodic Window Update" from the view menu when you simulate your programs. Layout your program neatly – look at the layout in the example programs and read the C style guide for further guidance. Beware of 0 and O! The number zero is 0 and the letter 'oh' is ‘O’. Learn how to use the simulator effectively. It will save you a lot of time in the long run! Use the facility to view the peripheral devices of the microcontroller when you test your programs. Q1 Write a program to produce a binary count on 8 LEDs connected to bits 0 - 7 on PORT 2 as follows :- Declare and initialise a variable to zero, initialise the port bits for output. In an endless loop ( i.e. use a while(1) loop) output the variable to the port and increment the variable. Start a Debug session and display Port2 using the peripherals menu. Execute your program one 'C' statement at a time using the step over command. Use the debug watch facility to watch the value of the variable change as the program is executed. Q2 Create a program that will initialise Port2 bits 0 - 7 to outputs. Then in an endless loop perform the sequence of bit manipulations shown below. Your program should use bit masking operations. Here is an outline of the program in pseudo-code and with the first two bit manipulations done for you. //initialise port 2 for output //set all outputs to 0 while(1) { FIO2PIN |= 0x04; // set bit 2 on (0x04 = 00000100) FIO2PIN &= ~0x04; // set bit 2 off //set port2 bit 1 on //set port2 bit 1 off //set port2 bit 4 on //set port2 bit 6 and bit 7 on //set port2 bit 4 off //set port2 bit 6 and bit 7 off } Notes: Use the bitwise-OR ( | ) and bitwise-AND (&) to set and clear the bits. Remember bits are numbered starting at bit 0 through to bit 7 Use the Debugger/Simulator to display Port2 and step through the program to verify the output on the port pins. (Use the step over command to step through each line of the 'C' program Q3 Copy, rename then modify the C source file for Q1 to include, within the while loop, a call to a delay function to reduce the update rate of the LEDs. The delay function should use a software loop to generate a short delay of about 0.5 seconds using a software loop. You will need to write the delay function and add it to your program and call it from the main function. Step through the program using the stepping commands. Note the different operation of the step into, step over and step out commands. Alan Goude Sheffield Hallam University. Feb 2009 1 533578100 MCB2300 Programming Exercises V3a The function must be declared near the top of your program as follows:void delay(void); The actual function definition, shown below, should be added after the main function. void delay(void ) { int counter; for(counter = 0; counter < A_BIG_NUMBER; counter++) { ; //do nothing } } Note: You should choose a suitable value for A_BIG_NUMBER. (Use the step_over command to step through the main function. Use step_into to step into the delay function and then step through the delay function using step_over. After a few iterations of the 'for' loop in the delay function use step_out to return back to the main function. Set up a watch on the variables used in your program. Step through the program again noting the changes in the variables in the watch window. Reset the program and now run the program. Note: Unless the "Periodic Window Update" is selected from the View menu the watched variables do not change. Normally the uVision windows are only updated when the program is stopped. (Note if a running program is interrupted and reset and then a step command is used the program will start stepping into the code of the startup.s assembly language file. To avoid this, place the cursor on the opening brace of the main function and use the run to cursor command. Experiment with breakpoints:- Place a breakpoint at a point in your program where you want execution to stop. Reset the program and select 'run'. Note that the program halts when it encounters the breakpoint. Remove the breakpoint when it is no longer required. Q4 This exercise is to count logic pulses on a single input bit using a Polling technique. (The MCB2300 target board has a pushbutton switch marked INT0 that is wired to Port2 bit 10 and generates a logic 1 normally and a logic 0 when pressed.) Write a program that configures Port2 bit 10 as an input and bits 0-7 as outputs. The program should initialise a variable to zero and for every press of the pushbutton the program should increment the variable and output the variable to the bottom 8 bits of Port2. When simulating this program you will provide the logic inputs by clicking the mouse over the simulated Port2 bit10 pin. A tick in the corresponding box of the port display indicates a logic 1 otherwise the value is taken as 0. Q5 Investigate the operation of the additional Port registers FIOxSET, FIOxCLR and FIOxMASK by consulting the relevant documentation. Select on of the previous program you have developed and rewrite it to make use of these additional Port registers. Alan Goude Sheffield Hallam University. Feb 2009 2 533578100 MCB2300 Programming Exercises V3a Q6 Using the knowledge gained to date a simple sequencer such as a washing machine programme can be implemented. PORT2 is connected to the following hardware :Inputs : bit 0 = the start switch bit 1 = upper water level switch (1 = FULL, 0 = not full) bit 2 = thermostat ( set to 1 when the required temperature is reached) bit 3 = lower water level switch (1 = EMPTY , 0 = not empty) Outputs : bit 4 = valve to allow cold water in( 1 = open value) bit 5 = heater to heat up water (1 = heater on) bit 6 = motor for agitating washing(1 = motor on) bit 7 = pump to empty out the water. (1 = pump on) Write a out in pseudo code the washing machine sequence based on the description below. The machine is activated by turning on the start switch, all outputs are initially off (i.e. 0) and it is assumed that the machine is empty of water. The machine should open the valve and fill the machine, heat the water to the required temperature then agitate the washing for a predetermined time (use a short delay here for testing purposes) then empty out the water. Finally the machine should wait until the start is switch de-activated. Q7 Write a program to continuously outputs the following pattern on port2 bits 0-7. (Hint; use << shift left operator e.g. x = x << 1;) 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000 00000001 etc. after the 8th step the 1 starts from bit 0 again (This pattern is called a "walking one"). Add a delay so that the pattern can be easily observed. Now make the '1' walk to the right and then combine the two to produce a pattern where the '1' alternates continuously first to the left then back to the right. Q8 Copy the program you wrote for Q3, rename and modify it to produce a printout of the variable in decimal and hexadecimal format to the serial port using the C function printf(). (See the notes at the end of these exercises on the printf() function). NOTE: The output of the printf function uses the UART and this must be initialised before any serial I/O can be used:Serial_init(); Place the above function call before the start of the while loop wher other initialisations take place. Notes: The printf function has been configured in the Keil 'C' compiler to send its output to the serial port. The Serial port output can be viewed whilst debugging by selecting Serial Window 2 from the View menu of u-Vision. Identify the files created by the build process and investigate & view the listing file (*.lst) and map file(*.map). You will need to modify the project options to enable the files to be generated. See the listing tab in the Target options dialogue. Can you find the code sizes and data sizes for your program? Look at the end of the map file. Alan Goude Sheffield Hallam University. Feb 2009 3 533578100 MCB2300 Programming Exercises V3a Q9. [Note: The Keil MCB2300 development board has a potentiometer connected to ADC channels 0. The potentiometer generates a voltage from 0 to +3.3 volts. The ADC input voltages can also be simulated in the uVision debugger] Using the program samples provide by the lecturer write a program that continuously reads channel 0 of the LPC2368 microcontroller and prints out the raw 10 bit value to the Serial Port using the C printf() standard library function using the UART of the Infineon167. Assume that the input to the ADC channel is from a temperature sensor which generates 0 to 3.3 volts for the temperature range 0 ºC to 100 ºC . Modify the program to print out the temperature in degrees centigrade. Calculate the resolution of your temperature value and print it out to an appropriate number of decimal places. Remember the ADC is 10-bit and the ADC reference voltages are 0 and 3.3volts. Q10 Copy the "walking ones" Q7 and modify it so that the delay is determined by the analogue input on ADC channel 0. This will enable the speed of the flashing LED sequence to be modified while the program is executing by turning the potentiometer connected to ADC channel 0. Q11 Write a program to output a continuous sine wave on the analogue output. The analogue output cane be vied in the simulator using the logic analyser from the view menu. Use the set up button in the top right hand corner of the logic analyser window to add a new signal AOUT and set the max and min voltages as shown below. You will need to include the <math.h> system header file to be able to use the standard trig. function sin(). What determines the frequency of the sine wave and how accurately is the sine wave produced? Alan Goude Sheffield Hallam University. Feb 2009 4 533578100 MCB2300 Programming Exercises V3a Q12 Replace the software delay function used in one of your previous exercises with one that uses a hardware timer. You will need to select which timer to use, select a suitable prescaler value and to calculate the value that needs to be loaded into the timer/counter to generate a 1 second delay. Note: some counters can be programmed to count up or down, others are fixed to count up. After the timer has been initialised and started, the timer overflow flag should be polled to detect when it changes from logic 0 to logic 1 indicating the timing period has elapsed. Q13 a)Download the FIQ interrupt example(FIQ.zip) from the Blackboard site and execute the program in simulation and on the target MCB2300 hardware. Ensure you understand the operation of the program and its constituent parts namely; the setting up of the switch input to provide the external interrupt; the enabling of the FIQ interrupt through the VIC, the role of the vector table( in the file LPC2300.s) and the FIQ handler which is called when the FIQ interrupt is generated. Alter the program to cause an interrupt on the rising edge of the interrupt i.e on the release of the pushbutton. (Change this back to falling edge before starting Q14) b)Using the FIQ example and the walking ones program from Q7 as a starting point create a program that either shifts repeatedly to the left or the right depending of the value of a direction variable (declare the variable globally and initialise the variable to 0). If the value is 1 the program should shift repeatedly to the right and to the left if the value of the variable is 0. Test the program. Now change the initial value of the direction variable to 1 and test the program again. Now add in an FIQ interrupt from the pushbutton(Port2 bit10) that toggles the value of the variable in the FIQ handler so as to change the direction of the walking one at each successive press of the pushbutton. Note that the variable that is to determine the direction must be declared as a global variable because it is accessed in both the main program and the FIQ handler. Furthermore it should also be declared volatile so that the compiler is aware that the variable can change externally to the execution of the main program i.e. in the FIQ handler. E.g. volatile int direction = 0; Q14 Investigate "printing" information to the LCD. Look at the LCD example project (Blinky.zip) and the LCD.C and LDC.H files that provide the functions to access the LCD. Now write a program that prints a text message to the LCD. Try printing on the second line of the LCD and in the middle of the line (see the set_cursor() function). Modify the program to print the value of a variable in decimal on the LCD. This will require converting the variable to its ASCII character representation using the sprintf() function and then printing out the characters using the lcd_print() function. Example sprintf(lcd_buf, "%d", x);//convert x to ASCII lcd_print(lcd_buf); // print to LCD where the variable x is an integer to be printed in decimal(hence the %d in the sprintf format string) and lcd_buf is an array of char declared big enough to hold the characters of the number + 1 extra character (for the end of string NULL character). E.g. char lcd_buf[17]; // LCD buffer big enough for one line of characters on the LCD Alan Goude Sheffield Hallam University. Feb 2009 5 533578100 MCB2300 Programming Exercises V3a Q15 Using a program similar to Q8 develop a program that produces a count on the LCD. Using a hardware timer modify the program to increment the count every hundreth of a second. Now modify the program to display on the LCD minutes, seconds and hundreths in the following format: MM:SS:HH. Remember to initialise the time to zero at the start of the program. Add an FIQ interrupt to reset the time back to zero when the pushbutton(Port2 bit 10) is pressed. Now convert your program into a reaction timer program or a stopwatch. Alan Goude Sheffield Hallam University. Feb 2009 6 533578100 MCB2300 Programming Exercises V3a Additional Notes: The printf() function - general format:- printf("format_string", variable_list); Format string must contain a formatter for each variable in the list. Commonly used formatters: %d - print an int in decimal %u - print an unsigned int in decimal %x - print an int or unsigned int in hexadecimal %c - print a char as its ASCII character %f - print a float in floating point format. The format string can contain other text which is simple output as it appears in the string examples: printf("The result is %d\n", x); printf("The values are %d %d and %d", a, b, c); printf("%7.2f %u \n", temperature, setpoint); The formatter can also indicate many other features when outputting values such as the total maximum number of character places to print and whether to print leading zeroes. For floating point values the number of digits after the decimal point can also be specified. Look up the printf() function for these extra features in a suitable text. Serial port configuration To configure the serial port and set the baud rate to 9600 you must: 1. Add the files serial.c and retarget.cc in your ptoject 2. #include "stdio.h" at the beginning of your 'C' source file 3. Call the function Serial_init(); at the beginning of your main function before using any standard library I/O function such as printf(). Data sheets, User Guides & other information See the module Blackboard site for links to the uVision software and relevant datasheets Use the on-line help in u-Vision . Alan Goude Sheffield Hallam University. Feb 2009 7 533578100