;********************************************************************* ; File: 16F877_Toggle LED.ASM ; Author: Wil ; Date: 2016.08.16 ; ; Purpose: Toggling 3 LEDS every half second (exact 500.000us) in the ; sequence green, yellow, red, green ... ; Remarks: Code is only testet in MPLAB-SIM (MPLAB 8.92) ;********************************************************************* ;Hardware: PIC16F877 ; Xtal 4MHz ; 3 LEDs green, yellow, red connected to PORTB,RB6:RB7 ; ;********************************************************************* ;SUPPRESSED WARNINGS: errorlevel -207 errorlevel -302 ;"Register in operand not in bank 0. Ensure .." ;MCU-CONFIGURATION LIST p=16f877 ; list directive to define processor #include ; processor specific variable definitions __CONFIG _CP_OFF & _CPD_OFF & _LVP_OFF & _HS_OSC & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _WRT_ENABLE_ON & _DEBUG_OFF ;********************************************************************* ;--VARIABLES, RAM ALLOCATION CBLOCK 0x20 tmpW ;ISR tmpSTATUS cntISR ;decrement in ISR Flags ;Flagregister shdwPORT ;make all changes in this register ENDC ; ;--LABLES & CONSTANTS LED_TICK equ .0 ;Flags, bit 0 LED_PORT equ PORTB GRN equ RB5 YLW equ RB6 RED equ RB7 ;********************************************************************* ORG 0x000 GOTO Init ;********************************************************************* ORG 0x0004 ;processor interrupt vector ISR: ;Interrupt Service Routine, occurs each 4ms movwf tmpW ;copy W to temp register, could be in any bank swapf STATUS,W ;swap status to be saved into W bcf STATUS,RP0 ;change to bank 0, regardless of current bank movwf tmpSTATUS ;save status to bank 0 register bcf INTCON,T0IE ;b5=0 disable TMR0 Overflow Interrupt bcf INTCON,T0IF ;b2=0 clear TMR0 overflow flag ; ISR_Adjust: GOTO $+1 ;4cycles to adjust ISR-Interval to GOTO $+1 ;4000 working cycles (4ms @ 4MHz) movlw d'7' ;preset TMR0 movwf TMR0 ; ISR_LED_Tick: ;sets flag "LED_TICK" each 500ms = 1 decfsz cntISR,f ;Z=1? then cntISR=0 GOTO ISR_otherCode ;no, movlw .125 ;Yes, set value again (occurs each 1/2 sec) movwf cntISR ;preset register with 125 bsf Flags,LED_TICK ;b0=1 is cleared in Main, after toggling the LED ; ISR_otherCode: ; ISR_End: SWAPF tmpSTATUS,w ;swap tmpSTATUS into W, sets bank to original state movwf STATUS ;move W into STATUS register swapf tmpW,f ;swap W_TEMP swapf tmpW,w ;swap W_TEMP into W bsf INTCON,T0IE ;b5=0 TMR0 Overflow Interrupt ENABLED RETFIE ;********************************************************************* Init: clrf PORTB ;bank0 clear output latches banksel TRISB ;bank1 data direction register clrf TRISB ;b7:0 are now digital I/O -> outputs ; ;--TIMER0 ; banksel OPTION_REG ;bank1 S.23 ; b7=0 weak pull-up enabled, b6=0 unused ; b5=0 TMR0 clock source fosc/4 b4=0 unused ; b3=0bit Prescaler assigned to TMR0 b2:0=011 Prescaler value=16:1 movlw b'00000011' movwf OPTION_REG banksel 0 ;back to bank0 ; ;--REGISTER PRESET clrf shdwPORT bsf shdwPORT,GRN-.1 ;starts with bit 4 (no LED) clrf Flags movlw .125 ;Preset counter movwf cntISR ;decrements by each interrupt clrf TMR0 ; ;--INTERRUPT clrf INTCON ; b7=1 interrupts globally enabled b6=0 unused ; b5=1 TMR0 overflow inter. enabled b4:3=00 (unused) ; b2=0 TMR0 overflow flag is cleared b1:0=00 unused bsf INTCON,TMR0IE ;bs=1 TMR0 overflow inter. enabled bsf INTCON,GIE ;b7=1 interr. globally enabled ;********************************************************************* Main: ; LEDs are not toggled if Flags,0=0 (jumps to the label "Main_OtherCode" ; RLF-> left shifting, moves carry flag into b0 and moves b7 out to carry. ; if all H-Bits shifted out, we have to preset shdwPORT,4=1 to do the ; prepare the next rlf to start again with the green LED. ; It's often useful to do the bitoperation first in a shadow register. btfss Flags,LED_TICK ;b0=1? GOTO Main_OtherCode ;NO bcf STATUS,C ;Yes rlf shdwPORT,f ;Toggle in shadow register btfsc STATUS,C ;C=1 then b7=0 LED sequence finished bsf shdwPORT,GRN ;b7=0, set bit GRN-1 (bit 4) movf shdwPORT,w ;copy shadow register through WREG movwf LED_PORT ;to PORTB bcf Flags,LED_TICK ;clear flag, active LED is ON for 500ms ; Main_OtherCode: ;insert here other code GOTO Main ;********************************************************************* END