In this lab only the 7 segment displays are of importance, the pre-written test program provided uses the input/output ports to make the second display count from 0 to 9 repeatedly. The program is loaded into the IDE and appropriate changes are made to set the IDE to ‘ROM Monitor Mode’ which means that the complied program is now to be executed on the external microprocessor via the serial link. Before looking at the program this is what I understand about the hardware:
The displays are both connected to the P0 input/output port with identical connections. i.e. if they are both enabled they will both show the same value. A 2 digit number can be shown on the displays by multiplexing; this involves rapidly switching between the 2 displays while changing the output in between switches. P0 is an 8-bit input/output port; the direction of the port is set by the 8-bit register PD0 this means that each bit can be set to input or output individually. In all cases a value of 1 in the direction register means output and a value of 0 means input. Each pin of the port goes through a buffer IC in order to power the Leeds on the display. Then the pins map onto the 7 segment in accordance to this table.
The 7 segment displays use a common anode attached to a transistor controlled by the P1 input/output port. The first 2 bits of this port each enable or disable one of the 7 segment displays respectively. The direction of P1 is set by the register PD1. When P1.0 is set to 0 the transistor attached to display 1 is opened effectively enabling display 1. The same is true for display 2, respectively.
Because the displays use a common anode the bit sequence sent to them to get the desired number is effectively inversed i.e. a 0 means turn the LED on and 1 means turn it off. The bit patterns to display each decimal number from 0-9 are pre defined in the program as a lookup table of 8 bit hex numbers:
unsigned char dis_code [10] = {0x0C0, 0x0F9, 0x0A4, 0x0B0, 0x99, 0x92, 0x82, 0x0F8, 0x80, 0x98};
The 0x prefix tells the complier that the number is a hex representation. These numbers can easily be converted into binary representation:
It should be noted that the binary value appears on the output port in reverse order i.e. in this representation the first bit is the DP. It can be clearly seen from this chart that the decimal point is always off for every number. If these values are checked against the table above they do produce the desired number on the display.
This declaration is the first line in the test program, the next part declares a delay function which simply runs through an empty loop a specified number of times to waste time. Then the program sets the direction of all ports to output:
PD0 = 0x0FF; (FF = 11111111 in binary so all bits are set at once)
PD1.0 = 1;
PD1.1 = 1;
Then it initialises the outputs by turning both displays off, setting all the segments to off and setting count to 0.
P0 = 0x0FF;
P1.0 = 1;
P1.1 = 1;
count = 0;
Now it starts the main loop where is sets display 1 to be off and display 0 to be on this seems unnecessary since this could be set before the loop since it does not change as the program runs. Next it selects a value from the look up table using the wrapped value of count and sends it to P0. Finally it waits for a few seconds and increases count by 1.
The briefing sheet asked me to change the delay section of the program which is a case of changing the value sent to the delay function, the result being obvious. Then I had to modify the program to use LED1 instead of LED2 which is a simple matter of inversing the values assigned to P1.0 and P1.1 i.e. change:
P1.1 = 1;
P1.0 = 0;
For
P1.1 = 1;
P1.0 = 0;
Finally I commented the code which I have attached to the back.
Conclusions
This laboratory was completely new to me as I had no background experience on this subject. By doing this experiment I have gained good experience about microcontrollers.
Appendix: Commented
#define Chip_3062x
#include "stdio.h"
#include "iom16c62.h"
/*
Define the lookup table for the LEDs in terms of bytes
*/
unsigned char dis_code [10] = {
0x0C0, 0x0F9, 0x0A4, 0x0B0, 0x99,
0x92, 0x82, 0x0F8, 0x80, 0x98};
int count;
// This is the meaning of hex lookup table:
// The seven segment codes are given by binary patterns .The latter part is labelled from G to A and the first decimal is represented by 0
// 0 = on and 1 = off
// the decimal is always off
//11000000 0
//11111001 1
//10100100 2
//10110000 3
//10011001 4
//10010010 5
//10000010 6
//11111000 7
//10000000 8
//10011000 9
/*
Delay function
*/
void wait (unsigned int delay){
while (delay !=0)
// The loop will continue until delay is equal to zero
delay--;
// decrement delay
//waste clock cycles
}
void main(void){
/*
Set the direction of all port 0 bits to output.
*/
PD0 = 0x0FF;
/*
Set the direction of the LED enable to output.
*/
PD1.0 = 1;
PD1.1 = 1;
/*
Set the port bits.
*/
// I have turned all the segments off
P0 = 0x0FF;
// disable both displays
P1.0 = 1;
P1.1 = 1;
//initilise count
count = 0;
// loop forever
while (1) {
// this line is not required since it already holds one
P1.1 = 1;
//This code would lit the first LED on the microcontroller
P1.0 = 0;
P0 = dis_code[count%10];
wait( 1000000 ); //this produces a delay of about 0.1 seconds
count++;
//increment count
}
}
Appendix: Commented
#define Chip_3062x
#include "stdio.h"
#include "iom16c62.h"
/*
Define the lookup table for the LEDs in terms of bytes
*/
unsigned char dis_code [10] = {
0x0C0, 0x0F9, 0x0A4, 0x0B0, 0x99,
0x92, 0x82, 0x0F8, 0x80, 0x98};
int count;
// This is the meaning of hex lookup table:
// The seven segment codes are given by binary patterns .The latter part is labelled from G to A and the first decimal is represented by 0
// 0 = on and 1 = off
// the decimal is always off
//11000000 0
//11111001 1
//10100100 2
//10110000 3
//10011001 4
//10010010 5
//10000010 6
//11111000 7
//10000000 8
//10011000 9
/*
Delay function
*/
void wait (unsigned int delay){
while (delay !=0)
// The loop will continue until delay is equal to zero
delay--;
// decrement delay
//waste clock cycles
}
void main(void){
/*
Set the direction of all port 0 bits to output.
*/
PD0 = 0x0FF;
/*
Set the direction of the LED enable to output.
*/
PD1.0 = 1;
PD1.1 = 1;
/*
Set the port bits.
*/
// I have turned all the segments off
P0 = 0x0FF;
// disable both displays
P1.0 = 1;
P1.1 = 1;
//initilise count
count = 0;
// loop forever
while (1) {
// this line is not required since it already holds one
P1.1 = 1;
//This code would lit the first LED on the microcontroller
P1.0 = 0;
P0 = dis_code[count%10];
wait( 1000000 ); //this produces a delay of about 0.1 seconds
count++;
//increment count
}
}