hockey22
March 3rd, 2009, 03:00 PM
I have an assignment for school and i'm not familiar with the HC11. The assignment is a traffic light with only red and green lights. When the north and south lights are green the east and west lights are red for 30 seconds and vice versa. This is supposed to be done in assembly and i need help!
rxbagain
March 4th, 2009, 11:20 PM
Here’s my code with some comments. In creating the program, the design is that the HC11 is 2Mhz and the lights will be controlled by PORTB of the HC11. The specific pins are as follows (positive logic):
PORTB PIN 0 = NORTH/SOUTH GREEN LIGHT
PORTB PIN 1 = NORTH/SOUTH RED LIGHT
PORTB PIN 2 = EAST/WEST GREEN LIGHT
PORTB PIN 3 = EAST/WEST RED LIGHT
PORTB EQU $1004 * Port B address
TMRTICK EQU 30000 * number of ticks before our timer interrupt is called
* when using a 2Mhz, this would give us 15ms interval
_30SECS EQU 2000 * to make a 30 secs delay, we increment a variable everytime TOC4ISR is called
* (when timer 4 compare has reached TMRTICK counts). using 15ms as we defined
* in TMRTICK, we can make 30secs by counting up to 2000 (2000 x 15ms = 30secs)
ORG $0000 * RAM data memory (variable storage 0x0000 - 0x00ff)
_count RMB 2 * these 2 bytes serve as the counter until _30SECS is reached
_tick RMB 1 * flag that will be set when our interrupt is called
_light RMB 1 * bit 0 serves as the flag for lights, 0 means north and south lights are green
* 1 means east and west lights are green
ORG $FF00 * ROM data memory (program storage 0xff00 - 0xffbf)
START
LDD #0 * initialize our variables to all 0s
STD _count
STAA _tick
STAA _light
LDS #$00FF * initialise stack to top of our RAM
LDD #TMRTICK * we set our timer 4 to trigger on the first TMRTICK tick
STD $101C * set it for the first trigger
LDAA #%00000100 * timer 4 for toggle setting
STAA $1020 * Timer Control Register 1 (TCTL1)
LDAA #%00010000 * timer 4 select bit
STAA $1023 * Timer Interrupt Flag enable (TFLG1)
STAA $1022 * Timer Interrupt Mask enable (TMSK1)
CLI * clear interrupt mask (enable interrupts)
BRA _LIGHT_TOGGLE * we just call _LIGHT_TOGGLE to initialize lights
LOOP
LDAA _tick * try to load _tick
BEQ LOOP * if it is 0 just jump to start of LOOP
CLR _tick * reset _tick
LDD _count * load our counter to D
ADDD #1 * add 1 (increment)
STD _count * and store it again
SUBD #_30SECS * try to subract _30SECS from D
BNE LOOP * if not 0, it means we dont have 30secs yet
STD _count * otherwise, we reset our counter (value of D holding 0)
_LIGHT_TOGGLE
LDAB #%00001001 * we default the light to be north/south as green
INC _light * we keep incrementing _light (even if overflow occurs)
LDAA #1 * we prepare A = 1
BITA _light * we AND the value of _light (_light & 1)
BEQ _LIGHT_IT * if (_light & 1) == 0, then we can go and apply our default lights
LDAB #%00000110 * otherwise, make east/west lights green
_LIGHT_IT
STAB PORTB * we now apply the new lights
BRA LOOP * and jump to the start of loop
* timer 4 output compare interrupt routine
TOC4ISR
LDD #TMRTICK * load D register with 15ms time
ADDD $101C * add to Timer 4 output compare
STD $101C * save sum back for next edge
LDX #$1000 * used in next instruction
BCLR $23,X $EF * clears interrupt flag
LDAA #1
STAA _tick * we set out _tick flag to 1 (yes)
RTI * ReTurn from Interrupt
ORG $FFFE * reset vector
FDB START * set to start of program
ORG $FFE2 * timer 4 output compare vector
FDB TOC4ISR * set to timer 4 output compare interrupt routine
For the timer, I got the interrupt function from this site (http://www.owlnet.rice.edu/~elec201/Book/6811_asm.html).
Hope it will help you :)