Pseudocode for interrupt-drive UART Routine on PIC12F752, serving to receive lift fan commands as the DOG TREAT for the ME218C project. Hardware RA0: output, Signal to Lift Fan RA1: output, LED, GREEN – Lift Fan Status RA2: output, LED, RED – Receive Status RA4: output, Reserved for TX RA5: input, RX TIMER1: Rx LED Timer (26ms max, using 26ms) TIMER2: Baud rate bit timer (26ms max, using 104us) Inits List the PIC12F752 model for the assembler Include p12F752.inc Choose configuration bits Code Protection OFF Brownout Detect Enabled Power Up Timer Enabled Select Internal Oscillator Variable definitions File memory locations: starting in share RAM at 0x070 WREG_TEMP, STATUS_TEMP, PCLATH_TEMP, Comm Registers Byte: RecvShiftCounter Byte: RecvShiftRegister Byte: RecvDataRegister Byte: RecvStatus containing the following: Bit: RecvStarting (0) Bit: RecvDataReady (1) Bit: RecvFramingErr (2) Bit: RecvActive (3) Variable: FanSpeed Defines BitZero:BitFive numbers BitZeroHi:BitFiveHi ALL_BITS_HI equals 8 bits of ones OneBitTime, HalfBitTime ADDRESS_MASK, FullShiftCount MSB set location 0 in program memory as instruction to go to Main set location 4 in program memory as instruction to go to ISR set location 5 in program memory as start of rest of code Label: Main Change to OSCCON oscillator controller register Change oscillator to 8MHz Call InitGPIO Call InitRxIOC Call InitRxLEDTimer Call InitTimer2 for timing the bit time Clear RecvStarting Clear RecvFramingErr Clear RecvDataReady Clear RecvShiftCounter enable global interrupts Run Loop Label: Run Do two no-ops and then goto run to make a nice loop while waiting for interrupts Label: HUAD Go to current PC address, i.e. huddle up and die if everything goes wrong Interrupt Service Routine Label ISR: Use standard push sequence to save WREG, STATUS, and PCLATH If IOCIF set (service interrupts for interrupts on change) If RX interrupt is active Program Timer2 to fire interrupt ½ bit time Enable Timer2 Set RecvStarting bit in RecvStatus Set RecvActive bit in RecvStatus Set RecvShiftCounter to 10 Clear IOCAF bit associated with RX Disable IOC on RX Endif IOC on RX Process other IOC interrupts as needed Endif (IOCF set) if TMR2 interrupt is active if RecvStarting set (doing start bit) clear RecvStarting if RX is low (we got good start bit) program Timer2 to fire interrupt after 1 bit time Decrement RecvShiftCounter else ( RX is high, so bad start bit) program IOC Negative on RX and enable interrupt Clear RecvActive bit in RecvStatus endif (RX is low) else (Doing data bit) decrement RecvShiftCounter if RecvShiftCounter not 0 shift RecvShiftRegister 1 position right Copy state of RX to MSB of RecvShiftRegister else copy RecvShiftRegister to RecvDataRegister if RX is low (bad stop bit) set RecvFramingErr endif (RX is low) Clear RecvActive bit in RecvStatus set RecvDataReady to 1 Set LastFanCmd equal to RecvDataRegister If framing error not equal to 1 Turn on Rx LED Pulse by calling TurnOnRxLED subroutine if LastFanCmd message equal to 0xFF write RA0 and RA1 high else write RA0 and RA1 low endif disable TMR2 interrupt clear RecvActive bit on RecvStatus lower RA2 transmit active LEDs program IOC Negative on RX and enable interrupt endif (RecvShiftCounter not 0 ) endif (RecvStarting set) clear TMR2IF endif (TMR2 interrupt ) If Timer1 interrupt is active Lower RA4 to turn off RxLED Disable Timer1 with TMR1ON bits of T1CON Clear TMR1IF in PIR1 Endif Interrupt Subroutines TurnOnRxLED change to bank 0 with TMR1L and TMR1H clear HI 8 bits in TMR1H clear LO 8 bits in TMR1L Enable Timer1 with TMR1ON bits of T1CON change to bank with LATA Raise RA4 to turn on RxLED return Initialization Routines Note – Set up Pins initialized to the following: RA0: output, Signal to Lift Fan RA1: output, LED, GREEN – Lift Fan Status RA2: output, LED, RED – Receive Status RA4: output, Reserved for TX RA5: input, RX Label InitGPIO: Go to bank containing PortA Enable PORTA Go to bank containing PortA Data Latch clear latch Go to bank containing ANSELA clear ANSELA to enable digital I/O Go to bank containing TRISA Prep WREG to set RA<4,2:0> as outputs and set RA<5> as inputs move WREG into TRISA switch to bank containing LATA Set pins RA4,2:0 to be low to start outputs low Write to the latch return Label InitRxIOC: (to set up RA5 to receive message) change to bank containing INCON edit interrupt control register to turn on interrupt on change set pin RA5to interrupt on falling edges change to bank containing IOCAN load up 0x20 for RA5 Return Label InitRxLEDTimer Set Timer1 prescale to 1:8 in T1CKPS bits of T1CON Set TMR1H and TMR1L to zero to reset timer Enable peripheral by setting TMR1GIE in PIE1 Label InitTimer2 switch to bank containing PIE1 in PIE1, timer2 interrupt switch to bank with T2CON prescale of 1:1 & post-scale of 1:1 to achieve 9600 baud, timer off move value from WREG into T2CON move to bank containing PR2 move starting value of PR2 to WREG write to PR2 reg value of (250) Return end to tell assembler we’re done