;on_off.asm ; ; ============================================================================= ; ; Turn on one of the LED's and make it blink ; First example program ; harkin, 02/01 ; ; ============================================================================== LIST P=16F877, R=DEC INCLUDE c:\MPLAB\p16f877.inc ; Definitions ; __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC ; Define start of vars ScratchPad EQU 0x20 mS_0 EQU ScratchPad+1 ; counters for the delay routine mS_1 EQU ScratchPad+2 ; Variables ; Start at some place in ram above the special registers (0x20 or higher) ScratchPad EQU 0x20 Counter EQU ScratchPad + 0 ; 8 bit counter ; Start of the Program ORG 3 goto Start ; start code at someplace higher than 0x04 ORG 0x50 Start ; Since A is bi-directional, we need to specify that the lower five bits (A4-A0) of ; A are output by putting zeros in those bits of TRISA. The upper three don't matter, but set ; them to be output also . TRISA is in bank 1, so switch to bank 1 and then back when ; done. Similarly, port D controls the LED's, so also set PORTD to put output. bsf STATUS, RP0 movlw b'00000000' movwf TRISA clrf TRISD ; A different way to clear all the bits. bcf STATUS, RP0 ; Port A, lines 0,1,2,3,4 control which output device is used. See page 8 ; in the Raven Board manual. The three colored LEDs, are selected by setting ; A0-A3 to 0x11 (this includes the latch) or 0x01 if the input isn't latched. ; If you are only going to use one of the circuits encoded by the multiplexor, it ; doesn't matter how you set the latch. However, if you are going to access multiple ; devices, you will need to set (one) the latch bit so that the changes are noted. On the other ; hand, if you are using A for other things that might affect the value of A0-A3, you need ; to set the value of A with the latch cleared (zero), so that value will stay in the ; multiplexor until you once again raise the latch bit and change the value of A0-A3. The ; most likely bug is to try to change from one device to another with the latch bit cleared. ; It remembers only the first value set at A0-A3 and won't change it until you set the bit ; and then possibly set it clear again. To say it more plainly, if the latch bit is cleared, ; you can't change the input to A unless to set the latch bit. You can either leave it set ; or you can clear it to latch the new input. movlw 0x11 movwf PORTA ; Now, the LED's can be controlled by setting RD0-RD2. RD0 controls green, RD1 controls ; yellow and RD2 controlss red; zero is on and one is off. To turn on only the red LED, ; set PORTD to b'xxxxx011' or 0x03. movlw 0x07 ; this turns all leds off movwf PORTD loop bcf PORTD,2 ; turn red on (011) ; OK, the red LED is on. Now use a timer to make it blink movlw 255 call mS_Delay bsf PORTD,2 ; turn it off (111) movlw 255 call mS_Delay goto loop ; ---------------------------------------------------------------- ; Routine to delay a specified number of milliseconds ; inputs - milliseconds to Delay (w), outputs - none ; This routine is designed to work for a 20 MHz clock, so ; each clock cycle takes 50 ns and each instruction takes 200 ns. ; Ignoring overhead in the loops, each inner loop is 250 x 17 nops, ; or about .85 ms. An input value of 255 generates a wait of ; 216.75 ms or a little less than 0.25 sec. Obviously, you could ; change the parameters to get some other timing. ; ------------------------------------------------------------------ mS_Delay movwf mS_0 mS_loop_0 ; outer delay loop movlw 250 movwf mS_1 mS_loop_1 ; inner delay loop fill (nop), 17 ; This generates 17 nops decfsz mS_1 goto mS_loop_1 clrwdt decfsz mS_0 goto mS_loop_0 return END