You are on page 1of 9

Programming a Digital Display Unit

A1: Programming a Digital Display Unit


Please read document "Ten basic rules for assignments A1, A2, and A3" (on MOLE). This lab script must be read prior to attending the lab session. Preparation time should be about 7 hours. You need to attend the lab session that you were allocated to and sign the attendance sheet in order for your report to get assessed. Report submission deadlines: Students allocated to group 1: Monday 05.03.2012, at 10:00 am. Students allocated to group 2: Monday 12.03.2012, at 10:00 am. Students allocated to group 3: Monday 27.02.2012, at 10:00 am.

Submission via Turnitin in MOLE. Hardcopy submissions will be discarded. Every student needs to submit her/his own original report. Do not include the entire source code in your report. Instead you should provide - where requested - your own fragments of code. If you define new helper functions or global variables, these must be included too. The report length is restricted to 4 pages (any additional pages will be discarded). The report should have one section per exercise. No introduction is needed. Objectives Implement software routines in C for displaying information on a digital led array, Learn to use digital I/O interfaces, Understand issues related to digital communication, addressing and data manipulation. Background Materials Laboratory script Programming examples Interfacing routines documentation C language documentation Assessment For this assignment you will need to complete all exercises listed in this script. Icon indicates that you need to demonstrate something to the session advisor. You need to write a report in which you answer the questions from this lab script, only the text in boldface needs to be addressed! If you do not succeed in completing an exercise, comment on your partial solution and/or on the problems you encountered.

P. Eastwood & R. Gross, 2012-02-8

Programming a Digital Display Unit

1. Introduction
The aim of this lab is to let you develop code for a digital display unit that is interfaced with a PC via an interfacing device, which provides digital I/O as well as A/D and D/A functionality. This lab experiment includes the following components Display unit with 2 rows of 11 led arrays (7x5) PC (USB) interfacing device providing digital I/O functionality Networked PC In addition, you will have access to a C/C++ compiler and to a complete IO library i.e. a set of high-level functions that cover all the common operations of the data acquisition device (for example reading and writing data from/to a digital IO port), which can be used to develop your own code. In particular, the code developed for this uses the library function cbDOut to write a byte to one of the two digital output ports used to control the display unit. The full description of this function is given in the Appendix. A simplified block diagram of the experimental system is shown in Figure 1.

Figure 1 Block diagram of experimental system

Port A and Port B are 8 bit I/O ports provided by the USB interfacing device. In the current configuration Port B (DB0 to DB6 bits) is used to address a particular column of 7 LEDs while Port A (DA0 to DA6 bits) contains the seven bit code that defines the ON/OFF configuration of the LEDs. In addition, the most significant bit (MSB) of Port B (DB7) is used to strobe the address i.e. it has to be set High then Low for the address to become valid.

P. Eastwood & R. Gross, 2012-02-8

Programming a Digital Display Unit

Getting started
You should login on the computer first using your network username and password. In order to login on the workstation, leave the username as it is (uos) and type in the password: real. Exercise 1: Compile and run the program 15 minutes

The source code that is provided is in the file display.c. Before compiling and running the program you need to copy the project files in your own working directory as follows: Download usb-digital.zip from MOLE Double click on it to extract the archive Copy the folder usb-digital to the local hard disk, for example in MyDocuments Open MyDocuments, double-click on usb-digital then double-click on display To compile and run the example, do the following: Double-click on display.dsw. This will open the display.dsw project in the Visual C++ development environment. Make sure that the workspace view is enabled (Alt+0). In the workspace view window select the File View tab and click on the display.c. This will open the source file for your program. To compile the file use CTRL+F7 or click on the icon in the toolbar. in the toolbar.

To compile and link the program use F7 or click on the icon To run the program use CTRL+F5 or click on the icon

in the toolbar.

The program will turn on some LEDs on the display unit. Press any key to exit the program. In your report, mention the address value and the 7-bit number used to encode the position of the active LEDs on the board.

2. Source code
This section contains a brief overview of the source code for the display software. Understanding how the existing code works will help you solve the exercises. Pre-processor directives The source code of any C program is analysed first by the pre-processor before it is compiled. In our case, the program includes the following #include pre-processor directives /* Include files */
P. Eastwood & R. Gross, 2012-02-8

Programming a Digital Display Unit #include <windows.h> #include <stdio.h> #include <conio.h> #include "cbw.h" These directives instruct the pre-processor to include the contents of the respective filenames into the current file before attempting to compile the program. In particular, the statement #include "cbw.h" instructs the pre-processor to include all function definitions (prototypes) which support the common operations of the data acquisition device. This is followed by a set of #define directives which are used to define the USB device number and an address which is reserved to send commands to the display unit - such as to turn off all LEDs. /* USB device parameters */ #define BOARD_NUM_0 0 /* Display parameters */ #define Command_Addr 0x7f / Global variables The following section of the code defines a number of global variables. char Display_Buffer [110]; This is a memory array of 110 bytes which can be used as a buffer to store the image of the display LEDs' configuration. char key; This is used to store the code of the key pressed by the user. /***** ASCII Character Lookup Table *****/ char Char_Table[91*6]= { 0,0,0,0,0,0, The Char_Table is a look-up array of 546 bytes (91x6) which contains the binary codes for the ASCII characters. Each character is defined as 5 columns of 7 LEDs plus one column (with all LEDs OFF) for space, hence 6 bytes per character. Functions The program contains a number of functions, some of which actually do something and some of which you need to write during this lab. Write_LED_Data() This function can be used to control individual columns of LEDs. The function cbDOut is used to write the address in Port B and LEDs configuration data in Port A. In order to make the address active, the bit DB7 has to be set to High and then Low.
P. Eastwood & R. Gross, 2012-02-8

// USB device number 0 //Reserved Address for Display commands

Programming a Digital Display Unit

void Write_LED_Data(unsigned short Led_Address, unsigned short Led_Data, unsigned short Board_Num) { cbDOut(Board_Num,FIRSTPORTA,Led_Data); Led_Address = Led_Address | 0x80; cbDOut(Board_Num,FIRSTPORTB,Led_Address); Led_Address = Led_Address & 0x7f; cbDOut(Board_Num,FIRSTPORTB,Led_Address); } Exercise 2: Analyse the function Write_LED_Data() 10 minutes

Read the specification of the function cbDOut in the Appendix. Understand how the function Write_LED_Data works. In your report, explain in detail how the function manipulates bit DB7 in Port B. Explain why only bit DB7 changes.

Clear-Display() This function can be used to clear the display (set all LEDs off). The Command_Addr variable is a pre-specified number that signals the display unit that the Led_Data variable should be treated as a command. In this example Led_Data=0 corresponds to a command to turn of all the LEDs. /************* Clear Display ************/ void Clear_Display (unsigned short Board_Num) { Write_LED_Data (Command_Addr,0,Board_Num); }
/**************************************************/

Message_to_Buffer() This function converts a text string into a string of LED character codes that are then stored in the memory buffer. The Char_Table holds the codes of the ASCII characters in order of their ASCII number where the ASCII code of the first character (Space) is 0x20 (hexadecimal value). It follows that the index of the first of the six column codes for a character in the lookup table can be obtained by subtracting 0x20 of the actual ASCII character value and then multiplying by 6.
/**********Copy ASCII Message String to Display Buffer ***********/ unsigned short Message_to_Buffer(char *String,unsigned short Buffer_Addr) { unsigned short CharLen = (strlen(String)); unsigned short i;

P. Eastwood & R. Gross, 2012-02-8

Programming a Digital Display Unit


unsigned short d; unsigned short c; for ( i=0; i<(CharLen); i++) // Number of Characters to display { d = (String[i]-0x20)*6; // Index first column data of Character for (c=0; c<6; c++) // 5 columns per character + space { Display_Buffer[Buffer_Addr] = Char_Table[c+d]; //Load Buffer Buffer_Addr++; // Next Buffer Address } } return Buffer_Addr; } /*******************************************************/

Shift_Buffer_Left() This function shifts the content of the memory buffer to the left. Moreover, it is supposed to send the content to the LED display. You will need to implement the function Buffer_to_Display(). The function Shift-Buffer-Right() does the same job in the opposite direction. /*********** Shift Display Buffer Left ************/ void Shift_Buffer_Left(unsigned short number) { unsigned short a,b; for(a=0; a<number; a++) { b=0; while(b<109) { Display_Buffer[b] = Display_Buffer[b+1]; b++; } Display_Buffer[109] = 0; Buffer_to_Display(); } } /********************************************/ main() The body of the main function contains two statements that are used to configure the digital ports as output ports. /* Configure Board 0 for Digital I/O as Output */ cbDConfigPort(BOARD_NUM_0,FIRSTPORTA,DIGITALOUT); cbDConfigPort(BOARD_NUM_0 ,FIRSTPORTB,DIGITALOUT); The function then clears the display, writes one column of data to the display, and then waits for a key to be pressed to exit.
P. Eastwood & R. Gross, 2012-02-8

Programming a Digital Display Unit Clear_Display (BOARD_NUM_0); // Issue Clear Command Write_LED_Data(0,1,0); while (!kbhit){}; Exercise 3: Implement Buffer_to_Display() 10 minutes Function description: The function should display the content of the buffer on the LED array. Function prototype: void Buffer_to_Display() Arguments: There are no function arguments. The function can access directly the global Display _Buffer variable.

Include the source code for this function in your lab report (possibly numbering the lines). Explain in detail how your code works.

Exercise 4: Implement Clear_Display_Buffer() Function description: The function should set to zero (space) the display buffer. Function prototype: void Clear_Display_Buffer()

5 minutes

Arguments: There are no function arguments. The function can access directly the global Display_Buffer variable.

Include the source code for this function in your lab report (possibly numbering the lines). Explain in detail how your code works.

Exercise 5: Scroll text on the digital display

30 minutes

Implement function Scroll_Message() that displays and continuously scrolls your name across the LED array. Ideally, initially the LED array is blank (all LEDs off). Then the text moves gradually in at one end of the array, scrolls further towards the other end until it finally moves out. This process should be repeated indefinitely. Show your fully or partially working system to the demonstrator.

P. Eastwood & R. Gross, 2012-02-8

Programming a Digital Display Unit Include the source code for this function in your lab report (possibly numbering the lines). Explain in detail how your code works.

Exercise 6: Program a cellular automaton

30 minutes

A cellular automaton is a grid in which every element (cell) has a discrete state. The state of each cell is determined from the states of all or some of its 8 surrounding cells, according to some fixed set of rules. Figure 2 shows a cell in black and its 8 neighbours in white.

Figure 2 Cellular automaton (neighbourhood model)

The Rule 110 automaton makes use of binary states, in other words, of 0 and 1. It can be generated as follows: The states of the cells in the first line are fixed. All the cells have state 0, except the rightmost cell, which has state 1, as shown in Figure 3. 0 0 ... 0 0 1
Figure 3

For line i=2, 3, 4, ..., the state of each cell is determined from the states of its 3 upper neighbours (line i-1, see also Figure 2), according to the rules given in Table 1. For edge cells, the state of the inexistent neighbour is taken as 0. Pattern of Upper Neighbours 111 110 101 100 011 010 001 000 State of Cell 0 1 1 0 1 1 1 0 Table 1

Generate a Rule 110 automaton of 55 lines of 14 cells each and display it on the LED matrix display panel. The states 0 and 1 should correspond to an LED being ON or OFF respectively (be careful: its counterintuitive!). Show your fully or partially working system to the demonstrator. Include the source code for this function in your lab report (possibly numbering the lines). Explain in detail how your code works.

P. Eastwood & R. Gross, 2012-02-8

Programming a Digital Display Unit

Appendix
cbDOut()
Writes a byte to a digital output port. If the port type is not AUXPORT, you must use cbDConfigPort() to configure the port for output first. If the port type is AUXPORT, you may need to use cbDConfigPort() to configure the port for output first. Check the board specific information in the Universal Library User's Guide (available on our web site at www.mccdaq.com/PDFmanuals/sm-ul-user-guide.pdf) to determine if AUXPORT should be configured for your hardware. Function prototype: C/C++:
int cbDOut(int BoardNum, int PortNum, unsigned short DataValue)

Visual Basic:
function cbDOut(ByVal BoardNum&, ByVal PortNum&, ByVal DataValue%) As Long

Delphi: Function cbDOut(BoardNum:Integer; PortNum:Integer; DataValue:Word):Integer; Arguments: BoardNum The number associated with the board when it was installed with the InstaCal configuration program. BoardNum may be 0 to 99. PortNum There are three general types of digital ports - ports that are programmable as input or output, ports that are fixed input or output and ports for which each bit may be programmed as input or output. For the first of these types, set PortNum to FIRSTPORTA. For the latter two types, set PortNum to AUXPORT. Some boards have both types of digital ports (for example the DAS1600 Series). Set PortNum to either FIRSTPORTA or AUXPORT depending on the digital port you want to set. Table 6-1 on page 98 shows which ports are in which 82C55 and 8536 digital chips. The CIO-DIO196 has eight 82C55 chips the most on a single board. The CIO-INT32 has two 8536 chips the most on a single board. DataValue Digital input value to be written. Error code or 0 if no errors.

Returns: Notes:

The size of the ports varies. If it is an eight bit port then the output value should be in the range 0 255. If it is a four bit port the value should be in the range 0 15. Refer to the example programs and the board-specific information in the Universal Library User's Guide for clarification of valid PortNum values.

P. Eastwood & R. Gross, 2012-02-8