A first attempt to flash the LEDsFirst of all we need to know how to switch the LEDs, which are connected to both ports A and B, on and off. To begin with we must select ports A and B to be outputs. This is done by writing 089H to the 8255's control register. Or better said we write 10001001B to it, which is exactly the same value, but this time we can more clearly see what bits are set to "1", and what bits are set to "0". If you compare this pattern with the bit-map of the control register on the previous page, you'll see that ports A and B are both selected to be outputs, while the entire port C is selected as inputs. This suits our purpose very well, as we have connected 8 push buttons to port C (we won't be using these in lesson 1 though). Because most TTL outputs can drive more current when low, we have connected the LEDs with their cathodes to the I/O ports (through a series resistor), and their anodes to the +5V rail. This means that a LED is ON when the output is "0". It goes without saying that the LED will be OFF when the output is "1", being the only other option left. Type the next program in your favourite text editor, save it, press the Boot button on Sitcom and assemble it using the DOS instruction SBASM LESSON1A. Or you can download all example programs of lesson 1 from the lesson1.zip file. |
;------------------------------------------------------------------------ ; ; LESSON1A.ASM ; ; This program will light all LEDs connected to an odd bit number on ; ports A and B. ; ;------------------------------------------------------------------------ .CR 8085 The processor we're using .CP 1,9600,N,8,1 SITCOM is connected to COM1 .TF COM1:,INT Send generated code to COM1 ;------------------------------------------------------------------------ ; ; Constants declarations ; ;------------------------------------------------------------------------ PORTA .EQ 000H Port A on the 8255 PORTB .EQ 001H Port B on the 8255 PORTC .EQ 002H Port C on the 8255 CONTROL .EQ 003H Control register of the 8255 ;------------------------------------------------------------------------ ; ; Light all odd LEDs ; ;------------------------------------------------------------------------ START MVI A,10001001B Select outputs for Ports A and B OUT CONTROL of the 8255, Port C are inputs MVI A,10101010B Load the accumulator with bit pattern OUT PORTA Output the bit pattern to port A OUT PORTB Output the bit pattern to port B .4EVER JMP .4EVER The processor can't do "nothing" |
What have we done here? We've seen most of the program before. Remember that lines beginning with a semicolon (;) are simply comments, intended for human eyes only. Sitcom will never ever see any of them, as they are discarded by the assembler. The first 3 lines of code tell the assembler that we're using an 8085 processer, and we want the generated code sent to Comm port 1 at 9600 baud. Remember that you'll have to adapt these lines if your sitcom is connected to a different Comm port. We have seen the next 4 lines of code too. These lines tell the assembler to use the numbers 0, 1, 2 and 3 whenever it encounters the names PORTA, PORTB, PORTC and CONTROL respectively.
At the line with the label START we see the first real instruction for the processor.
By the way, this instruction is put at address 00000H in our program memory.
But what is that JMP .4EVER thing doing there? You'll have to know that a microprocessor is a real workaholic, it just can't sit still. Therefore we have to tell it to run around in circles if we have nothing else for it to do. You will only see something like this in example programs, because in real life a microprocessor is controlling some automated system. Such a system will constantly need to be controlled, for as long as it is switched on. Feel free to experiment a little with this program, creating other light patterns on the LEDs. You may even try to show a different pattern on the LEDs of port A and B. If you want to do that you'll need an other MVI instruction just after the OUT PORTA instruction. But the LEDs are not flashing? Now what? |
;------------------------------------------------------------------------ ; ; LESSON1B.ASM ; ; This program will flash all LEDs together on ports A and B (or doesn't ; it?). ; ;------------------------------------------------------------------------ .CR 8085 The processor we're using .CP 1,9600,N,8,1 SITCOM is connected to COM1 .TF COM1:,INT Send generated code to COM1 ;------------------------------------------------------------------------ ; ; Constants declarations ; ;------------------------------------------------------------------------ PORTA .EQ 000H Port A on the 8255 PORTB .EQ 001H Port B on the 8255 PORTC .EQ 002H Port C on the 8255 CONTROL .EQ 003H Control register of the 8255 ;------------------------------------------------------------------------ ; ; Flash the LEDs ; ;------------------------------------------------------------------------ START MVI A,10001001B Select outputs for Ports A and B OUT CONTROL of the 8255, Port C are inputs MVI A,00000000B Load the accumulator with bit pattern FLASH OUT PORTA Output the bit pattern to port A OUT PORTB Output the bit pattern to port B CMA Complement all bits in the Accu JMP FLASH Repeat for ever |
Change the program to reflect the program above and assemble it. Now the LEDs are flashing.
Wait a minute!
My LEDs are constantly on, they are not flashing at all!
I don't see nothing wrong in this program.
Do you?
Then why don't my LEDs flash?
|
A waste of time
How do we slow down the processor?
We can't stop it temporarily, for it can't do just "nothing" (at least not with our current knowledge).
The only thing we can do is make the processor do some useless things that only consume some time.
|
MVI C,255 Load register C with maximum number DELAY DCR C Decrement register C (subtract 1) JNZ DELAY Jump back while C is not 0 yet |
Let's see how much time we've wasted with this loop?
According to the instruction table a MVI instruction takes 7 clock pulses to execute, a DCR instruction takes 4 clock pulses and a JNZ instruction takes 10 clock pulses (when the condition is true).
Only the DCR and JNZ instructions will be repeated 255 times.
The MVI instruction is only executed once.
Wow! We've counted down from 255 to 0 in about 1.2 mili seconds!
Thus it is hardly enough to last half a second.
|
MVI C,250 Load register C with loop counter DELAY NOP Waste 250 * 4 clock pulses NOP Another 1000 clock pulses wasted NOP And yet another 1000 down the drain NOP Do I have to repeat myself again? DCR C This also lasts a 1000 clock pulses JNZ DELAY This one lasts 250 * 10 clock pulses! |
The loop in the program fragment above lasts a total of 7500 clock pulses. Multiplied with 0.333 micro seconds this will take approximately 2.5 mili seconds.
This is a lot longer than the 11.333 micro seconds it takes when no delay loop is implemented.
But it still is not long enough to obtain a flashing rate of 1Hz.
Adding more NOP instructions will add 4 * 250 * 0.333 = 333 micro seconds per NOP, which is still not really an option if we want a delay of 0.5 seconds.
|
MVI B,200 Load outer loop counter DELAY1 MVI C,250 Load inner loop counter DELAY2 NOP Begin of inner loop NOP NOP NOP DCR C Decrement inner loop counter JNZ DELAY2 Repeat until loop counter = 0 DCR B Decrement outer loop counter JNZ DELAY1 Repeat until loop counter = 0 |
The inner loop is the same as the loop in our previous example. The line containing label DELAY1 loads the inner loop counter, while the next lines until the first JNZ instruction are the actual inner loop. We know from the previous description that this loop takes about 2.5 mili seconds to execute. So executing this inner loop a total of 200 times will waste about half a second of our life. That is exactly what we're doing here. The outer loop counter B is initialized to 200, and then the inner loop is started. After finishing this inner loop the outer loop counter is decremented and we'll start all over again if the counter is not 0 yet (happens 200 times). With this knowledge we can write the new complete program which flashes all LEDs at a rate of 1Hz. |
;------------------------------------------------------------------------ ; ; LESSON1C.ASM ; ; This program will flash all LEDs together on ports A and B at 1 Hz ; ;------------------------------------------------------------------------ .CR 8085 The processor we're using .CP 1,9600,N,8,1 SITCOM is connected to COM1 .TF COM1:,INT Send generated code to COM1 ;------------------------------------------------------------------------ ; ; Constants declarations ; ;------------------------------------------------------------------------ PORTA .EQ 000H Port A on the 8255 PORTB .EQ 001H Port B on the 8255 PORTC .EQ 002H Port C on the 8255 CONTROL .EQ 003H Control register of the 8255 ;------------------------------------------------------------------------ ; ; Flash the LEDs ; ;------------------------------------------------------------------------ START MVI A,10001001B Select outputs for Ports A and B OUT CONTROL of the 8255, Port C are inputs MVI A,00000000B Load the accumulator with bit pattern FLASH OUT PORTA Output the bit pattern to port A OUT PORTB Output the bit pattern to port B MVI B,200 Load outer loop counter DELAY1 MVI C,250 Load inner loop counter DELAY2 NOP Begin of inner loop NOP NOP NOP DCR C Decrement inner loop counter JNZ DELAY2 Repeat until loop counter = 0 DCR B Decrement outer loop counter JNZ DELAY1 Repeat until loop counter = 0 CMA Complement all bits in the Accu JMP FLASH Repeat for ever |
Now we have covered all the secrets about the FLASH1D program we have seen before.
You can now experiment a little with this program.
You may wish to flash other patterns on the LEDs, or you may change the flashing frequency or the duty cycle (the ratio between LEDs on and LEDs off time).
This concludes the first Sitcom lesson. Lesson 2 will show some more flashing LED tricks. I hope to meet you there. |
Continue with Lesson 2 - Some more flashing LEDs |
[Home] [Latest News] [Essentials] [Hardware] [The Build] [Programs] [Projects] [Downloads] | |||