; ------------------------------------------------------------------ Title: "Demo Program for Education Board" ; Description: Demos the Education Board and also tests most of the devices on the board. ; Date Created: 10/10/00 ; Revision: A ; Platform: MPLAB 4.0 ; ------------------------------------------------------------------ LIST P=16F877, R=DEC INCLUDE c:\temp\p16F877.inc PAGE ; __CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC ; ------------------------------------------------------------------ ; Constants Defined ; ------------------------------------------------------------------ #define Var_Start 0x20 ; start of variable space #define RS 0x00 #define LONG_DELAY 0x01 ; long delay constant #define I2C_DELAY 0x0A ; delay for I2C routine #define HIGH_ADDRESS 0x03 ; high address for I2C #define CLK 0x03 #define DIN 0x03 SDA EQU 4 ; SDA bit for I2C SCL EQU 3 ; SCL bit for I2C ; Multiplexer Definitions ; ------------------------------------------------------------------ #define LATCH 0x10 ; Latch enable #define NO_CONN 0x00 ; No connection #define Three_LED 0x01 ; Three color LEDs enable #define LED_Bank 0x02 ; 8 bit LED bank enable #define Sev_Seg_1 0x03 ; 7 segment 1's digit enable #define Sev_Seg_2 0x04 ; 7 segment 10's digit enable #define Sev_Seg_3 0x05 ; 7 segment 100's digit enable #define Sev_Seg_4 0x06 ; 7 segment 1000's digit enable #define Sev_Seg_5 0x07 ; 7 segment 10000's digit enable #define Sev_Seg_6 0x08 ; 7 segment 100000's digit enable #define Alpha_Num_1 0x09 ; Alpha numeric display #1 enable #define Alpha_Num_2 0x0A ; Alpha numeric display #2 enable #define LCD_Enable 0x0B ; LCD enable line #define PB_Rotary 0x0C ; Push button and rotary encoder enable #define Keypad 0x0D ; Keypad enable #define Serial_Reg 0x0E ; Serial registers latch enable ; ------------------------------------------------------------------ ; Macro used with I2C routine and LCD routine to produce short delay ; ------------------------------------------------------------------ SHORT_DELAY macro fill (nop), 10 endm ; ------------------------------------------------------------------ ; Variables used by program ; ------------------------------------------------------------------ cblock Var_Start Byte_0 ; 24 bit count (LSB) Byte_1 ; ... Byte_2 ; ... (MSB) LED_Var_0 ; Holds segments for each digit (LSD) LED_Var_1 ; ... LED_Var_2 ; ... LED_Var_3 ; ... LED_Var_4 ; ... LED_Var_5 ; ... (MSD) mS_0 ; Count values for delay routine mS_1 ; ... Loop_Count ; Multiplex count bin_0 ; Temp storage for 24 bit count bin_1 ; ... bin_2 ; ... bcd_0 ; BCD conversion of the 24 bit count bcd_1 ; ... bcd_2 ; ... bcd_3 ; ... ii ; Temp var alpha_index ; Index into alpha numeric table alpha_index_2 ; ... Main_Loop_Count ; LED_State ; LED_Out ; LED_Blink_Var ; Count_0 ; Count values for LCD delay Count_1 ; ... LCD_Data ; LCD varibles LCD_Flag AD_Byte_0 ; 24 bit count AD_Byte_1 ; ... AD_Byte_2 ; ... TX_RS_232 ; RS-232 transmit value RX_RS_232 ; RS-232 receive buffer key_code ; key_shift ; key_add ; key_loop ; blank ; decimal ; alpha_all_on ; fast_delay ; first_pass ; Rot_Out ; wait_high ; address ; byte_data ; DEVADD ; REG_ADD ; CHIP_COMMAND ; DATAOUT ; DATAIN ; TXBUFF ; RXBUFF ; endc ; ------------------------------------------------------------------ ; Start of program ; ------------------------------------------------------------------ ORG 3 goto Mainline ; ------------------------------------------------------------------ ; Start of table data storage ; ------------------------------------------------------------------ LCD_Table addwf PCL retlw B'01000010' ; B retlw B'01001111' ; O retlw B'01000001' ; A retlw B'01010010' ; R retlw B'01000100' ; D retlw B'00100000' ; retlw B'01010100' ; T retlw B'01000101' ; E retlw B'01010011' ; S retlw B'01010100' ; T retlw B'00000000' ; EOS LED_Table andlw b'00001111' addwf PCL ; most sig bit is used for decimal point ; segment order = 'gfedcba' ; 0 = segment off, 1 = segment on retlw B'00111111' ; 7 seg LED 0 retlw B'00000110' ; 7 seg LED 1 retlw B'01011011' ; 7 seg LED 2 retlw B'01001111' ; 7 seg LED 3 retlw B'01100110' ; 7 seg LED 4 retlw B'01101101' ; 7 seg LED 5 retlw B'01111101' ; 7 seg LED 6 retlw B'00000111' ; 7 seg LED 7 retlw B'01111111' ; 7 seg LED 8 retlw B'01101111' ; 7 seg LED 9 retlw B'01110111' ; 7 seg LED A retlw B'01111100' ; 7 seg LED B retlw B'00111001' ; 7 seg LED C retlw B'01011110' ; 7 seg LED D retlw B'01111001' ; 7 seg LED E retlw B'01110001' ; 7 seg LED F Alpha_Num_Lower_Table addwf PCL ; 0 = segment off, 1 = segment on retlw B'10010001' ; A retlw B'10110100' ; B retlw B'00100001' ; C retlw B'10100100' ; D retlw B'00100001' ; E retlw B'00000001' ; F retlw B'10110001' ; G retlw B'10010001' ; H retlw B'00100100' ; I retlw B'10100000' ; J retlw B'00001001' ; K retlw B'00100001' ; L retlw B'10000101' ; M retlw B'10001001' ; N retlw B'10100001' ; O retlw B'00010001' ; P retlw B'10010000' ; Q retlw B'00011001' ; R retlw B'10110000' ; S retlw B'00000100' ; T retlw B'10100001' ; U retlw B'00000011' ; V retlw B'10100101' ; W retlw B'00001010' ; X retlw B'00000100' ; Y retlw B'00100010' ; Z Alpha_Num_Upper_Table addwf PCL ; 0 = segment off, 1 = segment on retlw B'11100011' ; A retlw B'11001001' ; B retlw B'01000011' ; C retlw B'11001001' ; D retlw B'01100011' ; E retlw B'01100011' ; F retlw B'01000011' ; G retlw B'10100011' ; H retlw B'01001001' ; I retlw B'10000001' ; J retlw B'00110011' ; K retlw B'00000011' ; L retlw B'11001011' ; M retlw B'10000111' ; N retlw B'11000011' ; O retlw B'11100011' ; P retlw B'11100011' ; Q retlw B'11100011' ; R retlw B'01100011' ; S retlw B'01001001' ; T retlw B'10000011' ; U retlw B'00010011' ; V retlw B'10001011' ; W retlw B'00010101' ; X retlw B'00010101' ; Y retlw B'01010001' ; Z Keypad_Table andlw b'00001111' addwf PCL retlw B'00000000' ; 0 retlw B'00000100' ; 1 retlw B'00000011' ; 2 retlw B'00000011' ; 3 retlw B'00000010' ; 4 retlw B'00000010' ; 5 retlw B'00000010' ; 6 retlw B'00000010' ; 7 retlw B'00000001' ; 8 retlw B'00000001' ; 9 retlw B'00000001' ; A retlw B'00000001' ; B retlw B'00000001' ; C retlw B'00000001' ; D retlw B'00000001' ; E retlw B'00000001' ; F ; ------------------------------------------------------------------ ; Main loop of program ; ------------------------------------------------------------------ Mainline call Initialize Loop_Forever call Dip_Switch call RS_232_Transmit call Update_Vars call Main_Loop goto Loop_Forever ;******************************************************** Main_Loop movlw 30 movwf Main_Loop_Count ML_Loop call Seven_Seg_LED call Alpha_Num call Dip_Update call LED_Blink decfsz Main_Loop_Count goto ML_Loop return ; ------------------------------------------------------------------ ; Inititialize the the PIC and external hardware ; ------------------------------------------------------------------ Initialize movlw 0x00 movwf PORTD movwf first_pass movlw 0xFF movwf Rot_Out movlw b'00010000' movwf PORTA movwf PORTC bsf STATUS, RP0 movlw b'11100000' movwf TRISA movlw 0xFF movwf TRISB movlw b'11010011' movwf TRISC movlw b'11010011' clrf TRISD bcf OPTION_REG, 7 bcf STATUS, RP0 bsf STATUS, RP0 movlw b'10001001' movwf ADCON1 bcf STATUS, RP0 movlw b'10101001' movwf ADCON0 bsf STATUS, RP0 movlw 129 movwf SPBRG bsf TXSTA, BRGH bcf TXSTA, SYNC bcf TXSTA, RX9 bcf PIE1, TXIE bcf PIE1, RCIE bcf STATUS, RP0 bsf RCSTA, SPEN movlw 65 movwf TX_RS_232 movlw 0x00 movwf Byte_0 movwf Byte_1 movwf Byte_2 movwf alpha_index movwf alpha_index_2 movwf LED_Blink_Var ; ------------------------------------------------------------------ ; Writes text to the LCD. After this, the data is only scrolled ; ------------------------------------------------------------------ call Init_LCD call Write_Text movlw b'10010100' ; Sets LCD Write Location for first line call LCD_Send ; call Write_Text movlw b'11001010' ; Sets LCD Write Location for last part of second line call LCD_Send ; call Write_Text movlw b'11011110' ; Sets LCD Write Location for first part of second line call LCD_Send ; call Write_Text return ; ------------------------------------------------------------------ ; Transmits a byte of data over the RS-232 interface ; ------------------------------------------------------------------ RS_232_Transmit bsf STATUS, RP0 bsf TXSTA, TXEN bcf STATUS, RP0 movf TX_RS_232, w movwf TXREG incf TX_RS_232 movf TX_RS_232, w addlw 165 btfss STATUS, Z return movlw 65 movwf TX_RS_232 return ; ------------------------------------------------------------------ ; Get reading from A/D converter ; ------------------------------------------------------------------ AD_Convert btfsc ADCON0, GO goto ADC_skip_1 bsf STATUS, RP0 movf ADRESL, w bcf STATUS, RP0 movwf AD_Byte_0 movf ADRESH, w movwf AD_Byte_1 bsf ADCON0, GO ADC_skip_1 movf AD_Byte_0, w movwf bin_0 movf AD_Byte_1, w movwf bin_1 clrf bin_2 return ; ------------------------------------------------------------------ ; Updates variables that change each pass through the main loop ; ------------------------------------------------------------------ Update_Vars movf PORTE, w andlw b'00000100' btfsc STATUS, Z goto I2C_Test btfsc first_pass, 0 incf Byte_0 ; add one to 24 bit count btfss STATUS, Z goto UV_Skip_0 incf Byte_1 btfss STATUS, Z goto UV_Skip_0 incf Byte_2 UV_Skip_0 clrf alpha_all_on clrf blank clrf decimal clrf fast_delay movf Byte_0, w movwf bin_0 movf Byte_1, w movwf bin_1 movf Byte_2, w movwf bin_2 clrf key_code call Get_Keypad movf key_code, w btfsc STATUS, Z goto UV_Skip_1 movwf bin_0 clrf bin_1 clrf bin_2 decf blank UV_Skip_1 movlw LATCH + PB_Rotary movwf PORTA SHORT_DELAY btfss PORTB, 4 goto A_D_Init btfss PORTB, 5 goto Rotary_Loop_Forever ;decf fast_delay btfss PORTB, 6 call AD_Convert btfsc PORTB, 7 goto UV_Skip_2 movlw 0x38 movwf bin_0 movlw 0x90 movwf bin_1 movlw 0x0D movwf bin_2 decf decimal decf alpha_all_on UV_Skip_2 call Update_7_seg_LED ;------------------------------------------------------------------------ btfss first_pass, 0 goto UV_Skip_3 incf alpha_index movf alpha_index, w addlw 230 btfsc STATUS, Z clrf alpha_index incf LED_Blink_Var decf alpha_index_2 movf alpha_index_2, w addlw 1 btfss STATUS, Z goto UV_Skip_3 movlw 25 movwf alpha_index_2 UV_Skip_3 ;------------------------------------------------------------------------ bcf LCD_Flag, LONG_DELAY bcf LCD_Flag, RS movlw b'00011100' call LCD_Send movlw 0xFF movwf first_pass return ; ------------------------------------------------------------------ ; Blinks the three color LEDs ; ------------------------------------------------------------------ LED_Blink movf LED_Blink_Var, w xorlw 0xFF movf alpha_all_on, f btfss STATUS, Z movlw 0x00 movwf PORTD movlw LATCH + Three_LED movwf PORTA call Delay return ;******************************************************** Dip_Update movlw LATCH + PB_Rotary movwf PORTA SHORT_DELAY movf RCREG, w xorlw 0xFF bsf RCSTA, CREN btfsc PORTB, 6 movf LED_Out, w movf alpha_all_on, f btfss STATUS, Z movlw 0x00 movwf PORTD movlw LATCH + LED_Bank movwf PORTA call Delay return ; ------------------------------------------------------------------ ; Reads the state of the DIP Switch. Uses bit banging for this ; ------------------------------------------------------------------ Dip_Switch movlw b'00000000' ; needed to control the clock line movwf SSPCON bcf PORTC, CLK movlw LATCH + Serial_Reg movwf PORTA movlw LATCH + NO_CONN movwf PORTA ;********************************************************* call Read_DIP_Bit ; reads the 8 individual switches call Read_DIP_Bit ; ... call Read_DIP_Bit ; ... call Read_DIP_Bit ; ... call Read_DIP_Bit ; ... call Read_DIP_Bit ; ... call Read_DIP_Bit ; ... call Read_DIP_Bit ; ... ;********************************************************* movf ii, w xorwf LED_State, w movwf LED_State movwf LED_Out return ;******************************************************** ; Reads the value of one of the eight individual switches ; ------------------------------------------------------------------ Read_DIP_Bit rlf ii, F bcf ii, 0 btfsc PORTB, DIN bsf ii, 0 bsf PORTC, CLK bcf PORTC, CLK return ; ------------------------------------------------------------------ ; Displays character on the Alphanumeric display ; ------------------------------------------------------------------ Alpha_Num movlw b'00110000' movwf SSPCON bcf PIR1, SSPIF movf alpha_index, w call Alpha_Num_Lower_Table xorlw 0xFF movf alpha_all_on, f btfss STATUS, Z movlw 0x00 movwf SSPBUF AN_Loop_0 btfss PIR1, SSPIF goto AN_Loop_0 movlw LATCH + Serial_Reg movwf PORTA movlw LATCH + NO_CONN movwf PORTA bcf PIR1, SSPIF movf alpha_index, w call Alpha_Num_Upper_Table xorlw 0xFF movf alpha_all_on, f btfss STATUS, Z movlw 0x01 movwf SSPBUF AN_Loop_1 btfss PIR1, SSPIF goto AN_Loop_1 movlw LATCH + Serial_Reg movwf PORTA movlw LATCH + NO_CONN movwf PORTA movlw LATCH + Alpha_Num_1 movwf PORTA call Delay ;;;;;;;;;;;;;;;;;;;;;;;; movlw b'00110000' movwf SSPCON bcf PIR1, SSPIF movf alpha_index_2, w call Alpha_Num_Lower_Table xorlw 0xFF movf alpha_all_on, f btfss STATUS, Z movlw 0x00 movwf SSPBUF AN_Loop_2 btfss PIR1, SSPIF goto AN_Loop_2 movlw LATCH + Serial_Reg movwf PORTA movlw LATCH + NO_CONN movwf PORTA bcf PIR1, SSPIF movf alpha_index_2, w call Alpha_Num_Upper_Table xorlw 0xFF movf alpha_all_on, f btfss STATUS, Z movlw 0x01 movwf SSPBUF AN_Loop_3 btfss PIR1, SSPIF goto AN_Loop_3 movlw LATCH + Serial_Reg movwf PORTA movlw LATCH + NO_CONN movwf PORTA movlw LATCH + Alpha_Num_2 movwf PORTA call Delay return ; ------------------------------------------------------------------ ; Displays a decimal number on the 7-seg LEDs ; ------------------------------------------------------------------ Update_7_seg_LED call b2bcd movf bcd_0, w call LED_Table movwf LED_Var_0 comf LED_Var_0 swapf bcd_0, w call LED_Table movwf LED_Var_1 comf LED_Var_1 movf bcd_1, w call LED_Table movwf LED_Var_2 comf LED_Var_2 swapf bcd_1, w call LED_Table movwf LED_Var_3 comf LED_Var_3 movf bcd_2, w call LED_Table movwf LED_Var_4 comf LED_Var_4 swapf bcd_2, w call LED_Table movwf LED_Var_5 comf LED_Var_5 movf decimal, f btfsc STATUS, Z goto U7_Skip bcf LED_Var_0, 7 bcf LED_Var_1, 7 bcf LED_Var_2, 7 bcf LED_Var_3, 7 bcf LED_Var_4, 7 bcf LED_Var_5, 7 U7_Skip return ; Handles the leading zero blanking of the 7-seg LEDs ; ------------------------------------------------------------------ Seven_Seg_LED movf blank, f btfsc STATUS, Z goto No_Blanking swapf bcd_2, w andlw b'00001111' btfss STATUS, Z Goto No_Blanking call Delay movf bcd_2, w andlw b'00001111' btfss STATUS, Z Goto Blank_Digit_5 call Delay swapf bcd_1, w andlw b'00001111' btfss STATUS, Z Goto Blank_Digit_4 call Delay movf bcd_1, w andlw b'00001111' btfss STATUS, Z Goto Blank_Digit_3 call Delay swapf bcd_0, w andlw b'00001111' btfss STATUS, Z Goto Blank_Digit_2 call Delay Goto Blank_Digit_1 No_Blanking movf LED_Var_5, w movwf PORTD movlw LATCH + Sev_Seg_6 movwf PORTA call Delay movlw LATCH + NO_CONN movwf PORTA Blank_Digit_5 movf LED_Var_4, w movwf PORTD movlw LATCH + Sev_Seg_5 movwf PORTA call Delay movlw LATCH + NO_CONN movwf PORTA Blank_Digit_4 movf LED_Var_3, w movwf PORTD movlw LATCH + Sev_Seg_4 movwf PORTA call Delay movlw LATCH + NO_CONN movwf PORTA Blank_Digit_3 movf LED_Var_2, w movwf PORTD movlw LATCH + Sev_Seg_3 movwf PORTA call Delay movlw LATCH + NO_CONN movwf PORTA Blank_Digit_2 movf LED_Var_1, w movwf PORTD movlw LATCH + Sev_Seg_2 movwf PORTA call Delay movlw LATCH + NO_CONN movwf PORTA Blank_Digit_1 movf LED_Var_0, w movwf PORTD movlw LATCH + Sev_Seg_1 movwf PORTA call Delay movlw LATCH + NO_CONN movwf PORTA return ; ------------------------------------------------------------------ ; Sends a byte of data to the LCD module ; ------------------------------------------------------------------ LCD_Send movwf LCD_Data swapf LCD_Data, w andlw b'00001111' call LCD_Toggle ; send high nibble call LCD_Delay movf LCD_Data, w andlw b'00001111' call LCD_Toggle ; send low nibble call LCD_Delay return ; Toggles the E signal line of the LCD module ; ------------------------------------------------------------------ LCD_Toggle btfsc LCD_Flag, RS iorlw b'10000000' movwf PORTD movlw LATCH + LCD_Enable movwf PORTA SHORT_DELAY movlw LATCH + NO_CONN movwf PORTA return LCD_Delay ; Delay a bit movlw 0x01 btfsc LCD_Flag, LONG_DELAY movlw 0x80 movwf Count_1 LD_Loop_1 movlw 0x00 movwf Count_0 LD_Loop_2 decfsz Count_0 goto LD_Loop_2 decfsz Count_1 goto LD_Loop_1 return ; ------------------------------------------------------------------ ; Inits the LCD module ; ------------------------------------------------------------------ Init_LCD bsf LCD_Flag, LONG_DELAY bcf LCD_Flag, RS movlw 0x08 movwf ii IL_Loop call LCD_Delay decfsz ii goto IL_Loop movlw b'00110011' call LCD_Send movlw b'00110010' call LCD_Send movlw b'00101000' call LCD_Send movlw b'00000001' call LCD_Send movlw b'00000110' call LCD_Send movlw b'00001100' call LCD_Send return ; ------------------------------------------------------------------ ; Writes text to the LCD module ; ------------------------------------------------------------------ Write_Text bcf LCD_Flag, LONG_DELAY bsf LCD_Flag, RS clrf ii WT_loop movf ii, w call LCD_Table addlw 0 btfsc STATUS, Z goto WT_skip call LCD_Send incf ii goto WT_loop WT_skip bsf LCD_Flag, LONG_DELAY bcf LCD_Flag, RS return ; ---------------------------------------------------------------- ; Delay routines ; ------------------------------------------------------------------ Delay movlw 1 movwf mS_0 movlw 50 movwf mS_1 btfsc fast_delay, 1 goto D_skip movlw 2 call mS_Delay return D_skip goto mS_loop_1 return ; ---------------------------------------------------------------- ; Routine to dealy a specified number of miliseconds ; inputs - milliseconds to Delay (w), outputs - none ; ------------------------------------------------------------------ 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 decfsz mS_1 goto mS_loop_1 clrwdt decfsz mS_0 goto mS_loop_0 return ; ---------------------------------------------------------------- ; Routine to convert a binary variable into a BCD value ; ------------------------------------------------------------------ b2bcd movlw d'24' movwf ii clrf bcd_0+0 clrf bcd_0+1 clrf bcd_0+2 clrf bcd_0+3 b2bcd1 rlf bin_0+0,f rlf bin_0+1,f rlf bin_0+2,f rlf bcd_0+0,f rlf bcd_0+1,f rlf bcd_0+2,f rlf bcd_0+3,f decfsz ii,f goto b2bcd2 retlw 0 b2bcd2 movlw bcd_0+0 movwf FSR call adjbcd incf FSR,f call adjbcd incf FSR,f call adjbcd incf FSR,f call adjbcd goto b2bcd1 adjbcd movlw h'33' addwf INDF,f btfsc INDF,3 andlw b'11110000' btfsc INDF,7 andlw b'00001111' subwf INDF,f return ; ---------------------------------------------------------------- ; Routine to interface to the 16 key keypad ; ------------------------------------------------------------------ Get_Keypad movlw b'10000000' movwf key_shift clrf key_add movlw 4 movwf key_loop GK_loop call Extract_Key andlw 0xFF btfsc STATUS, Z goto GK_skip addwf key_add, w movwf key_code return GK_skip movlw 4 addwf key_add, f bcf STATUS, C rrf key_shift, f decfsz key_loop goto GK_loop return Extract_Key movlw LATCH + Keypad movwf PORTA movf key_shift, w movwf PORTD SHORT_DELAY swapf PORTB, w movwf ii movlw LATCH + NO_CONN movwf PORTA movf ii, W xorlw 0x0F call Keypad_Table return ; ---------------------------------------------------------------- ; Routine to interface to the audio in and audio out jacks ; ------------------------------------------------------------------ A_D_Init bsf STATUS, RP0 movlw 0xFF ; PWM period movwf PR2 bcf STATUS, RP0 bsf STATUS, RP0 movlw b'00001001' ; Left justification & A/D input selection movwf ADCON1 bcf STATUS, RP0 movlw b'10101001' ; Select A/D clock speed & channel selection movwf ADCON0 movlw 0x04 ; PWM prescaler/timer 2 on movwf T2CON movlw 0x0C movwf CCP1CON ; Turn on PWM mode bsf ADCON0, GO ; Start A/D conversion A_D_Loop_Forever clrwdt btfsc ADCON0, GO goto A_D_Loop_Forever bsf STATUS, RP0 movf ADRESL, w ; get the 2 low bits of the conversion bcf STATUS, RP0 movwf ii movf ADRESH, w ; get the 8 high bits of the conversion bsf ADCON0, GO ; start A/D conversion bcf CCP1CON, 4 ; set the 2 low bits of the PWM duty cycle bcf CCP1CON, 5 ; btfsc ii, 6 ; bsf CCP1CON, 4 ; btfsc ii, 7 ; bsf CCP1CON, 5 ; movwf CCPR1L ; set the 8 high bits of the PWM duty cycle xorlw 0xFF movwf PORTD movlw LATCH + PB_Rotary movwf PORTA SHORT_DELAY btfss PORTB, 6 goto Mainline btfss PORTB, 7 goto Mainline movlw LATCH + LED_Bank ; enable 8 LEDs movwf PORTA ; wait_loop btfss PIR1, TMR2IF goto wait_loop bcf PIR1, TMR2IF goto A_D_Loop_Forever ; ---------------------------------------------------------------- ; Routine to interface with the rotary encoder ; ---------------------------------------------------------------- Rotary_Loop_Forever call Rotary_Read movlw LATCH + PB_Rotary ; Select rotary encoder and buttons movwf PORTA SHORT_DELAY btfss PORTB, 6 goto Mainline btfss PORTB, 7 goto Mainline movlw LATCH + LED_Bank movwf PORTA movlw 0x01 call mS_Delay goto Rotary_Loop_Forever ; Code to determine the rotation diection of the rotary encoder ; ------------------------------------------------------------------ Rotary_Read movlw LATCH + PB_Rotary ; Select rotary encoder movwf PORTA ; SHORT_DELAY movf PORTB, W ; Save PORTB data to variable movwf ii ; btfsc ii, 1 ; Line 1 low? goto skip_low ; Nope btfsc wait_high, 0 ; Line 1 has gone high since last low? goto skip ; Nope movlw 0xFB ; Turn on red LED for rotation right btfsc ii, 2 ; Line 2 low? movlw 0xFE ; Turn on green LED for rotation left movwf Rot_Out bsf wait_high, 0 ; Set wait_high flag goto skip skip_low bcf wait_high, 0 ; Line 1 went high, clear wait_high flag skip movf Rot_Out, W movwf PORTD ; Send to port movlw LATCH + Three_LED ; Select Tri LED's movwf PORTA ; movlw 0x01 ; Delay a bit call mS_Delay ; movf ii, W ; Send saved PORTB data to PORTD movwf PORTD ; return ; ---------------------------------------------------------------- ; Routine to interface with the two I2C devices (uses bit banging) ; ---------------------------------------------------------------- I2C_Test clrf byte_data clrf address movlw 100 call mS_Delay ; Tests the RTC/temp sensor I2C communications ; ------------------------------------------------------------------ Next_Byte_Loop movlw B'10011110' movwf DEVADD movlw 0x17 movwf CHIP_COMMAND movlw 0x00 movwf REG_ADD movf byte_data, W xorlw 0xff movwf ii movwf DATAOUT call I2Cout movlw I2C_DELAY call mS_Delay movlw B'10011110' movwf DEVADD movlw 0x17 movwf CHIP_COMMAND movlw 0x00 movwf REG_ADD call I2Cin movf DATAIN, W movwf PORTD xorwf ii, W btfss STATUS, Z goto I2C_Fail ; Tests the EEPROM I2C communications ; ------------------------------------------------------------------ movlw B'10100000' movwf DEVADD movlw HIGH_ADDRESS movwf CHIP_COMMAND movf address, W movwf REG_ADD movf byte_data, W xorlw 0xff movwf ii movwf DATAOUT call I2Cout movlw I2C_DELAY call mS_Delay movlw B'10100000' movwf DEVADD movlw HIGH_ADDRESS movwf CHIP_COMMAND movf address, W movwf REG_ADD call I2Cin movf DATAIN, W movwf PORTD ; Blinks LED if the I2C tests fail ; ------------------------------------------------------------------ I2C_Fail_Loop movlw LATCH + PB_Rotary ; Check if button was pressed movwf PORTA ; in order to return to mainline ; SHORT_DELAY ; ; btfss PORTB, 6 ; goto Mainline ; btfss PORTB, 7 ; goto Mainline ; movf DATAIN, W xorwf ii, W btfss STATUS, Z goto I2C_Fail ;************************************************* movlw 1 incf address incf byte_data btfsc STATUS, Z movwf byte_data movlw LATCH + LED_Bank movwf PORTA movlw 50 call mS_Delay goto Next_Byte_Loop I2C_Fail movlw LATCH + Three_LED movwf PORTA movlw 0x00 movwf PORTD movlw 0x10 call mS_Delay goto I2C_Fail_Loop ; Steps to send a I2C byte ; ------------------------------------------------------------------ I2Cout call Start movf DEVADD, W call TX movf CHIP_COMMAND, W call TX movf REG_ADD, W call TX movf DATAOUT, W call TX call Stop return ; Steps to receive a I2C byte ; ------------------------------------------------------------------ I2Cin call Start movf DEVADD, W call TX movf CHIP_COMMAND, W call TX movf REG_ADD, W call TX call ReStart movf DEVADD, W iorlw B'00000001' call TX bsf TXBUFF, 7 call RX movwf DATAIN call Stop return ; I2C Start command ; ------------------------------------------------------------------ Start movlw B'00111011' movwf SSPCON bcf PORTC, SDA bcf PORTC, SCL movlw TRISC movwf FSR ; I2C Restart command ; ------------------------------------------------------------------ ReStart bsf INDF, SDA bsf INDF, SCL delay bcf INDF, SDA SHORT_DELAY bcf INDF, SCL return ; I2C Stop command ; ------------------------------------------------------------------ Stop bcf INDF, SDA bsf INDF, SCL SHORT_DELAY bsf INDF, SDA return TX movwf TXBUFF bsf STATUS, C TX_1 rlf TXBUFF, F movf TXBUFF, F btfss STATUS, Z call BitOut btfss STATUS, Z goto TX_1 call BitIn movlw B'00000001' andwf RXBUFF, W return RX movlw B'00000001' movwf RXBUFF RX_1 rlf RXBUFF, F call BitIn btfss STATUS, C goto RX_1 rlf TXBUFF, F call BitOut movf RXBUFF, W return BitOut bcf INDF, SDA btfsc STATUS, C bsf INDF, SDA bsf INDF, SCL SHORT_DELAY bcf INDF, SCL bcf STATUS, C return BitIn bsf INDF, SDA bsf INDF, SCL bcf RXBUFF, 0 btfsc PORTC, SDA bsf RXBUFF, 0 bcf INDF, SCL return end