; CC5X Version 3.1I, Copyright (c) B Knudsen Data ; C compiler for the PICmicro family ; ************ 12. Sep 2004 14:12 ************* processor 16F877A radix DEC INDF EQU 0x00 PCL EQU 0x02 STATUS EQU 0x03 FSR EQU 0x04 PORTA EQU 0x05 TRISA EQU 0x85 PORTB EQU 0x06 TRISB EQU 0x86 PCLATH EQU 0x0A Carry EQU 0 Zero_ EQU 2 RP0 EQU 5 RP1 EQU 6 IRP EQU 7 GIE EQU 7 PORTC EQU 0x07 PORTD EQU 0x08 RCSTA EQU 0x18 TXREG EQU 0x19 RCREG EQU 0x1A TRISC EQU 0x87 TRISD EQU 0x88 TXSTA EQU 0x98 SPBRG EQU 0x99 EEDATA EQU 0x10C EEADR EQU 0x10D EEDATH EQU 0x10E EEADRH EQU 0x10F EECON2 EQU 0x18D PEIE EQU 6 TXIF EQU 4 RCIF EQU 5 EEIF EQU 4 RCIE EQU 5 RD EQU 0 WR EQU 1 WREN EQU 2 EEPGD EQU 7 data_byte_in EQU 0x40 cursor_position EQU 0x41 LCD_Width EQU 0x42 LCD_Lines EQU 0x43 EL1 EQU 0x44 EL2 EQU 0x45 CP1 EQU 0x46 CP2 EQU 0x47 number_of_presses EQU 0x48 s1_save EQU 0x70 s2 EQU 0x20 s3 EQU 0x21 number_to_print EQU 0x22 m EQU 0x24 temp EQU 0x25 C1cnt EQU 0x2B C2tmp EQU 0x2C C3cnt EQU 0x2B C4tmp EQU 0x2C C5rem EQU 0x2E i EQU 0 c EQU 0x2D d EQU 0x2B incoming_string EQU 0x2B x EQU 0x2C x_2 EQU 0x2B y EQU 0x2D z EQU 0x2E e_address EQU 0x2B e_data EQU 0x2B e_address_2 EQU 0x2C temp_GIE EQU 0 nate EQU 0x3B x_3 EQU 0x3B nate_2 EQU 0x2B my_byte EQU 0x2C i_2 EQU 0x2E k EQU 0x2F m_2 EQU 0x30 temp_2 EQU 0x31 high_byte EQU 0x32 low_byte EQU 0x33 C6cnt EQU 0x3B C7tmp EQU 0x3C C8cnt EQU 0x3B C9tmp EQU 0x3C C10rem EQU 0x3E ci EQU 0x3B GOTO main ; FILE D:\Pics\code\16F877A\PIC-MT-USB\LCD-Example.c ;/* ; 9-12-04 ; Copyright Spark Fun Electronics© 2004 ; ; Example code for the PIC-MT-USB written for the 16F877A @ 20MHz ; ; Takes serial data from the USB<->RS232 IC and displays it on LCD ; Turns on and off the backlight when the user presses Button 1 and reports back to computer ; Flashes Bi-Color LED when user presses buttons 1 and 2 ; Counts and displays the number of times Button 2 is pressed - stores the count onto internal EEPROM ; ; Thanks to Olimex for providing the original C test code for the PIC-MT-C w/ 16F873 ; ;*/ ;#define Clock_20MHz ;#define Baud_9600 ; ;#include "\Pics\c\16F877A.h" // device dependent interrupt definitions ;#include "\Pics\c\int16CXX.H" ; ;#pragma config|= 0x3F32 //HS Oscilator, Power-Up Timer, Write Protect Off ; ;//Hardware port definitions ;//================================================= ;#define Serial_In_BB PORTA.2 ;#define Serial_Out_BB PORTA.1 ; ;#define RS PORTD.0 ;#define R_W PORTD.1 ;#define E PORTD.2 ; ;#define BL_Control PORTD.3 ; ;#define D4 PORTD.4 ;#define D5 PORTD.5 ;#define D6 PORTD.6 ;#define D7 PORTD.7 ; ;#define BUTTON1 PORTB.5 ;#define BUTTON2 PORTB.4 ; ;#define LED1 PORTB.2 ;#define LED2 PORTB.1 ;//================================================= ; ;//Constant definitions ;//================================================= ;#define FALSE 0 ;#define TRUE 1 ; ;#define CLR_DISP 0b.0000.0001 //Clear display ; ;#define CUR_HOME 0b.0000.0010 //Move cursor home and clear screen memory ;#define CUR_RIGHT 0b.0001.0100 //Move cursor one to right ;#define CUR_LEFT 0b.0001.0000 //Move cursor one to left ; ;#define SCROLL_RIGHT 0b.0001.1100 //Scroll entire screen right one space ;#define SCROLL_LEFT 0b.0001.1000 //Scroll entire screen left one space ; ;#define DISP_ON 0b.0000.1100 //Turn visible LCD on ;#define DISP_OFF 0b.0000.1000 //Turn visible LCD off ; ;#define UNDERLINE_ON 0b.0000.1110 //Turn on underlined cursor ;#define UNDERLINE_OFF 0b.0000.1100 //Turn off underlined cursor ; ;#define BLINKCUR_ON 0b.0000.1101 //Turn on blinking box cursor ;#define BLINKCUR_OFF 0b.0000.1100 //Turn off blinking box cursor ; ;#define DUALCUR_ON 0b.0000.1111 //Turn on blinking box and underline cursor ;#define DUALCUR_OFF 0b.0000.1100 //Turn off blinking box and underine cursor ; ;#define SET_CURSOR 0b.1000.0000 //SET_CURSOR + X : Sets cursor position to X ; ;#define ENTRY_INC 0b.0000.0110 // ;#define DD_RAM_ADDR 0b.1000.0000 // ;#define DD_RAM_ADDR2 0b.1100.0000 // ;#define CG_RAM_ADDR 0b.0100.0000 // ;//================================================= ; ;//Global variable declarations ;//================================================= ;uns8 data_byte_in; ;uns8 cursor_position; ; ;uns8 LCD_Width; ;uns8 LCD_Lines; ; ;uns8 EL1, EL2; ;uns8 CP1, CP2; ; ;int16 number_of_presses; ;//================================================= ; ;//Interrupt Vectors ;//================================================= ;#pragma origin 4 ORG 0x0004 ;interrupt serverX( void) ;{ serverX ; int_save_registers MOVWF s1_save SWAPF STATUS,W BCF 0x03,RP0 BCF 0x03,RP1 MOVWF s2 MOVF PCLATH,W MOVWF s3 CLRF PCLATH ; //char sv_FSR = FSR; // save FSR if required ; ; if(RCIF) //If we have received something from the computer store it in the RX_Array array BTFSS 0x0C,RCIF GOTO m001 ; { ; data_byte_in = RCREG; MOVF RCREG,W MOVWF data_byte_in ; ; //There is no clearing of the interrupt flag, it's done automatically ; } ; ; //FSR = sv_FSR; // restore FSR if saved ; int_restore_registers m001 MOVF s3,W MOVWF PCLATH SWAPF s2,W MOVWF STATUS SWAPF s1_save,1 SWAPF s1_save,W ;} RETFIE ;//================================================= ; ;//Function declarations ;//================================================= ;void boot_up(void); ;void delay_ms(uns16); ; ;void init_lcd(void); ;void send_char(uns8); ;void send_cmd(uns8); ;void send_string(const char* incoming_string); ;void LCD_wait(void); ; ;uns8 onboard_eeread(uns8 e_address); ;void onboard_eewrite(uns8 e_data, uns8 e_address); ; ;void putc(uns8 nate); ;uns8 getc(void); ;uns8 bin2Hex(char x); ;void printf(const char *nate, int16 my_byte); ; ;//================================================= ; ;void main(void) ;{ _const1 MOVWF ci MOVLW .0 BSF 0x03,RP1 MOVWF EEADRH BCF 0x03,RP1 RRF ci,W ANDLW .127 ADDLW .54 BSF 0x03,RP1 MOVWF EEADR BTFSC 0x03,Carry INCF EEADRH,1 BSF 0x03,RP0 BSF 0x18C,EEPGD BSF 0x18C,RD NOP NOP BCF 0x03,RP0 BCF 0x03,RP1 BTFSC ci,0 GOTO m002 BSF 0x03,RP1 MOVF EEDATA,W ANDLW .127 BCF 0x03,RP1 RETURN m002 BSF 0x03,RP1 RLF EEDATA,W RLF EEDATH,W BCF 0x03,RP1 RETURN DW 0x3AC2 DW 0x3A74 DW 0x376F DW 0x18A0 DW 0x500 DW 0x2C8D DW 0x3AEF DW 0x3820 DW 0x32F2 DW 0x39F3 DW 0x3265 DW 0x3120 DW 0x3A75 DW 0x37F4 DW 0x106E DW 0x3AEE DW 0x316D DW 0x3965 DW 0x18A0 DW 0x2100 DW 0x3A75 DW 0x37F4 DW 0x106E DW 0x1D32 DW 0x20 DW 0x68A DW 0x37D9 DW 0x1075 DW 0x3970 DW 0x39E5 DW 0x32F3 DW 0x1064 DW 0x3AE2 DW 0x3A74 DW 0x376F DW 0x3720 DW 0x36F5 DW 0x32E2 DW 0x1072 DW 0x1032 DW 0x1000 DW 0x34F4 DW 0x32ED DW 0x73 DW 0x1020 DW 0x3853 DW 0x3961 DW 0x236B DW 0x3775 DW 0x31AE DW 0x36EF DW 0x1000 DW 0x2A4D DW 0x2AAD DW 0x2153 DW 0x22A0 DW 0x30F8 DW 0x386D DW 0x32EC DW 0x0 main ; boot_up(); //Initialize PIC ports and LCD interface BCF 0x03,RP0 BCF 0x03,RP1 CALL boot_up ; ; while(1) ; { ; //Check to see if anything new has happened ; if (data_byte_in != 0) BCF 0x03,RP0 m003 MOVF data_byte_in,1 BTFSC 0x03,Zero_ GOTO m005 ; { ; send_char(data_byte_in); MOVF data_byte_in,W CALL send_char ; putc(data_byte_in); MOVF data_byte_in,W CALL putc ; ; data_byte_in = 0; CLRF data_byte_in ; ; cursor_position++; INCF cursor_position,1 ; ; //When the cursor gets to the end of one line, it must ; //advance to the next visual line ; //=============================================================== ; if (cursor_position == EL1) //End of line 1 MOVF cursor_position,W XORWF EL1,W BTFSS 0x03,Zero_ GOTO m004 ; { ; cursor_position = 64; //Beginning of line 2 MOVLW .64 MOVWF cursor_position ; send_cmd(CP2); MOVF CP2,W CALL send_cmd ; } ; else if (cursor_position == EL2) //End of line 2 GOTO m005 m004 MOVF cursor_position,W XORWF EL2,W BTFSS 0x03,Zero_ GOTO m005 ; { ; cursor_position = 0; //Return to line 1 CLRF cursor_position ; send_cmd(CP1); MOVF CP1,W CALL send_cmd ; } ; //=============================================================== ; ; } ; ; if(BUTTON1 == 0) //If user presses button one, turn on or off the back light m005 BTFSC PORTB,5 GOTO m006 ; { ; LED1 = 1; BSF PORTB,2 ; delay_ms(250); //Wait for user to get their finger off the button! MOVLW .250 MOVWF x_2 CLRF x_2+1 CALL delay_ms ; LED1 = 0; BCF PORTB,2 ; ; send_cmd(CLR_DISP); MOVLW .1 CALL send_cmd ; send_string("Button 1"); //Sends a string to the LCD CLRF incoming_string CALL send_string ; ; BL_Control ^= 1; MOVLW .8 XORWF PORTD,1 ; ; printf("\n\rYou pressed button number 1", 0); //Sends a string to the computer MOVLW .9 MOVWF nate_2 CLRF my_byte CLRF my_byte+1 CALL printf ; } ; ; if(BUTTON2 == 0) m006 BTFSC PORTB,4 GOTO m003 ; { ; LED2 = 1; BSF PORTB,1 ; delay_ms(250); //Wait for user to get their finger off the button! MOVLW .250 MOVWF x_2 CLRF x_2+1 CALL delay_ms ; LED2 = 0; BCF PORTB,1 ; ; send_cmd(CLR_DISP); MOVLW .1 CALL send_cmd ; send_string("Button 2: "); //Sends a string to the LCD MOVLW .39 MOVWF incoming_string CALL send_string ; ; //Reading and writing to the PIC's onboard EEPROM ; //=============================================================== ; ; number_of_presses.high8 = onboard_eeread(0); //Read data from EEPROM position 0 MOVLW .0 CALL onboard_eeread MOVWF number_of_presses+1 ; number_of_presses.low8 = onboard_eeread(1); MOVLW .1 CALL onboard_eeread MOVWF number_of_presses ; ; number_of_presses++; INCF number_of_presses,1 BTFSC 0x03,Zero_ INCF number_of_presses+1,1 ; ; onboard_eewrite(number_of_presses.high8, 0); //Write data to EEPROM position 0 MOVF number_of_presses+1,W MOVWF e_data MOVLW .0 CALL onboard_eewrite ; onboard_eewrite(number_of_presses.low8, 1); MOVF number_of_presses,W MOVWF e_data MOVLW .1 CALL onboard_eewrite ; ; //=============================================================== ; ; //This prints 16-bit decimal numbers to the LCD ; //=============================================================== ; ; int16 number_to_print; ; number_to_print = number_of_presses; MOVF number_of_presses,W MOVWF number_to_print MOVF number_of_presses+1,W MOVWF number_to_print+1 ; ; uns8 m, temp; ; uns8 decimal_output[5]; ; ; //Divide number by a series of 10s ; for(m = 4 ; number_to_print > 0 ; m--) MOVLW .4 MOVWF m m007 BTFSC number_to_print+1,7 GOTO m014 MOVF number_to_print,W IORWF number_to_print+1,W BTFSC 0x03,Zero_ GOTO m014 ; { ; temp = number_to_print % (uns16)10; MOVF number_to_print,W MOVWF C2tmp MOVF number_to_print+1,W MOVWF C2tmp+1 CLRF temp MOVLW .16 MOVWF C1cnt m008 RLF C2tmp,1 RLF C2tmp+1,1 RLF temp,1 BTFSC 0x03,Carry GOTO m009 MOVLW .10 SUBWF temp,W BTFSS 0x03,Carry GOTO m010 m009 MOVLW .10 SUBWF temp,1 m010 DECFSZ C1cnt,1 GOTO m008 ; decimal_output[m] = temp; MOVLW .38 ADDWF m,W MOVWF FSR BCF 0x03,IRP MOVF temp,W MOVWF INDF ; number_to_print = number_to_print / (uns16)10; MOVF number_to_print,W MOVWF C4tmp MOVF number_to_print+1,W MOVWF C4tmp+1 CLRF C5rem MOVLW .16 MOVWF C3cnt m011 RLF C4tmp,1 RLF C4tmp+1,1 RLF C5rem,1 BTFSC 0x03,Carry GOTO m012 MOVLW .10 SUBWF C5rem,W BTFSS 0x03,Carry GOTO m013 m012 MOVLW .10 SUBWF C5rem,1 BSF 0x03,Carry m013 RLF number_to_print,1 RLF number_to_print+1,1 DECFSZ C3cnt,1 GOTO m011 ; } DECF m,1 GOTO m007 ; ; printf("\n\rYou pressed button number 2 ", 0); //Sends a string to the computer m014 MOVLW .50 MOVWF nate_2 CLRF my_byte CLRF my_byte+1 CALL printf ; ; for(m++ ; m < 5 ; m++) INCF m,1 m015 MOVLW .5 SUBWF m,W BTFSC 0x03,Carry GOTO m016 ; { ; putc(bin2Hex(decimal_output[m])); MOVLW .38 ADDWF m,W MOVWF FSR BCF 0x03,IRP MOVF INDF,W CALL bin2Hex CALL putc ; send_char(bin2Hex(decimal_output[m])); MOVLW .38 ADDWF m,W MOVWF FSR BCF 0x03,IRP MOVF INDF,W CALL bin2Hex CALL send_char ; } INCF m,1 GOTO m015 ; ; printf(" times", 0); m016 MOVLW .81 MOVWF nate_2 CLRF my_byte CLRF my_byte+1 CALL printf ; ; //=============================================================== ; ; ; } ; ; }//End infinite loop GOTO m003 ; ; ;}//End Main ; ;//Initializes the various ports and interrupts ;//Also inits the LCD ;void boot_up(void) ;{ boot_up ; //Setup Ports ; PORTA = 0b.0000.0000; CLRF PORTA ; TRISA = 0b.0000.0000; //0 = Output, 1 = Input BSF 0x03,RP0 CLRF TRISA ; ; PORTB = 0b.0000.0000; BCF 0x03,RP0 CLRF PORTB ; TRISB = 0b.0011.0000; //0 = Output, 1 = Input (RB5 = Button1) (RB4 = Button2) MOVLW .48 BSF 0x03,RP0 MOVWF TRISB ; ; PORTC = 0b.0000.0000; BCF 0x03,RP0 CLRF PORTC ; TRISC = 0b.1000.0000; //0 = Output, 1 = Input (RC7 = UART RX) MOVLW .128 BSF 0x03,RP0 MOVWF TRISC ; ; PORTD = 0b.0000.0000; BCF 0x03,RP0 CLRF PORTD ; TRISD = 0b.0000.0000; //0 = Output, 1 = Input BSF 0x03,RP0 CLRF TRISD ; ; //Sets up the UART for serial comm ; //============================================================= ; SPBRG = 129; //20MHz for 9600 inital communication baud rate MOVLW .129 MOVWF SPBRG ; //SPBRG = 25; //4MHz for 9600 inital communication baud rate - Not yet tested ; TXSTA = 0b.0010.0100; //8-bit asych mode, high speed uart enabled MOVLW .36 MOVWF TXSTA ; RCSTA = 0b.1001.0000; //Serial port enable, 8-bit asych continous receive mode MOVLW .144 BCF 0x03,RP0 MOVWF RCSTA ; //============================================================= ; ; //Init LCD ; init_lcd(); CALL init_lcd ; ; //Setup interrupts for incoming RX ; data_byte_in = 0; CLRF data_byte_in ; RCIE = 1; //Enable the UART RX interrupt BSF 0x03,RP0 BSF 0x8C,RCIE ; PEIE = 1; //Enable Peripheral Ints BSF 0x0B,PEIE ; GIE = 1; BSF 0x0B,GIE ;} RETURN ; ;//Initializes the 4-bit parallel interface to the HD44780 ;void init_lcd(void) ;{ init_lcd ; ; RS = 0; BCF PORTD,0 ; R_W = 0; BCF PORTD,1 ; ; //Tell the LCD we are using 4bit data communication ; delay_ms(750); MOVLW .238 MOVWF x_2 MOVLW .2 MOVWF x_2+1 CALL delay_ms ; PORTD = 0b.0011.0000; MOVLW .48 MOVWF PORTD ; E = 1; E = 0; BSF PORTD,2 BCF PORTD,2 ; ; delay_ms(200); MOVLW .200 MOVWF x_2 CLRF x_2+1 CALL delay_ms ; PORTD = 0b.0011.0000; MOVLW .48 MOVWF PORTD ; E = 1; E = 0; BSF PORTD,2 BCF PORTD,2 ; ; delay_ms(200); MOVLW .200 MOVWF x_2 CLRF x_2+1 CALL delay_ms ; PORTD = 0b.0011.0000; MOVLW .48 MOVWF PORTD ; E = 1; E = 0; BSF PORTD,2 BCF PORTD,2 ; ; delay_ms(20); MOVLW .20 MOVWF x_2 CLRF x_2+1 CALL delay_ms ; PORTD = 0b.0010.0000; MOVLW .32 MOVWF PORTD ; E = 1; E = 0; BSF PORTD,2 BCF PORTD,2 ; ; send_cmd(DISP_ON); MOVLW .12 CALL send_cmd ; send_cmd(CLR_DISP); MOVLW .1 CALL send_cmd ; //LCD Init Complete ; ; send_string(" SparkFun.com"); MOVLW .88 MOVWF incoming_string CALL send_string ; send_cmd(SET_CURSOR + 64); MOVLW .192 CALL send_cmd ; send_string(" MT-USB Example"); MOVLW .103 MOVWF incoming_string CALL send_string ; ; //Retrieve last Backlight state ; /* ; Backlight_Setting = onboard_eeread(0); ; if (Backlight_Setting > 1) Backlight_Setting = 1; //Default ; onboard_eewrite(Backlight_Setting, 0); //Record to spot 0 ; BL_Control = Backlight_Setting; //Turn on/off the backlight ; */ ; BL_Control = 1; //Turn on Backlight BSF PORTD,3 ; ; LCD_Lines = 2; MOVLW .2 MOVWF LCD_Lines ; LCD_Width = 16; MOVLW .16 MOVWF LCD_Width ; ; //Set end lines ; EL1 = LCD_Width; MOVWF EL1 ; EL2 = 64 + LCD_Width; MOVLW .64 ADDWF LCD_Width,W MOVWF EL2 ; ; //Set cursor positions ; CP1 = 0b.1000.0000 | 0; MOVLW .128 MOVWF CP1 ; CP2 = 0b.1000.0000 | 64; MOVLW .192 MOVWF CP2 ; ; delay_ms(750); MOVLW .238 MOVWF x_2 MOVLW .2 MOVWF x_2+1 CALL delay_ms ; send_cmd(CLR_DISP); MOVLW .1 CALL send_cmd ; ; cursor_position = 0; CLRF cursor_position ;} RETURN ; ;//Checks the busy flag and waits until LCD is ready for next command ;void LCD_wait(void) ;{ LCD_wait ; bit i = 1; BSF 0x2E,i ; ; TRISD = 0b.1111.0000; //0 = Output, 1 = Input MOVLW .240 BSF 0x03,RP0 MOVWF TRISD ; ; R_W = 1; //Tell LCD to output status BCF 0x03,RP0 BSF PORTD,1 ; RS = 0; BCF PORTD,0 ; ; while(i == 1) m017 BTFSS 0x2E,i GOTO m018 ; { ; E = 1; BSF PORTD,2 ; i = D7; //Read data bit 7 - Busy Flag BCF 0x2E,i BTFSC PORTD,7 BSF 0x2E,i ; E = 0; BCF PORTD,2 ; ; E = 1; E = 0; //Toggle E to get the second four bits of the status byte - but we don't care BSF PORTD,2 BCF PORTD,2 ; } GOTO m017 ; ; TRISD = 0b.0000.0000; //0 = Output, 1 = Input m018 BSF 0x03,RP0 CLRF TRISD ;} BCF 0x03,RP0 RETURN ; ;//Sends an ASCII character to the LCD ;void send_char(uns8 c) ;{ send_char MOVWF c ; LCD_wait(); CALL LCD_wait ; ; R_W = 0; //set LCD to write BCF PORTD,1 ; RS = 1; //set LCD to data mode BSF PORTD,0 ; ; PORTD.7 = c.7; BTFSS c,7 BCF PORTD,7 BTFSC c,7 BSF PORTD,7 ; PORTD.6 = c.6; BTFSS c,6 BCF PORTD,6 BTFSC c,6 BSF PORTD,6 ; PORTD.5 = c.5; BTFSS c,5 BCF PORTD,5 BTFSC c,5 BSF PORTD,5 ; PORTD.4 = c.4; BTFSS c,4 BCF PORTD,4 BTFSC c,4 BSF PORTD,4 ; E = 1; E = 0; //Toggle the Enable Pin BSF PORTD,2 BCF PORTD,2 ; ; PORTD.7 = c.3; BTFSS c,3 BCF PORTD,7 BTFSC c,3 BSF PORTD,7 ; PORTD.6 = c.2; BTFSS c,2 BCF PORTD,6 BTFSC c,2 BSF PORTD,6 ; PORTD.5 = c.1; BTFSS c,1 BCF PORTD,5 BTFSC c,1 BSF PORTD,5 ; PORTD.4 = c.0; BTFSS c,0 BCF PORTD,4 BTFSC c,0 BSF PORTD,4 ; E = 1; E = 0; BSF PORTD,2 BCF PORTD,2 ;} RETURN ; ;//Sends an LCD command ;void send_cmd(uns8 d) ;{ send_cmd MOVWF d ; LCD_wait(); CALL LCD_wait ; ; R_W = 0; //set LCD to write BCF PORTD,1 ; ; PORTD.7 = d.7; BTFSS d,7 BCF PORTD,7 BTFSC d,7 BSF PORTD,7 ; PORTD.6 = d.6; BTFSS d,6 BCF PORTD,6 BTFSC d,6 BSF PORTD,6 ; PORTD.5 = d.5; BTFSS d,5 BCF PORTD,5 BTFSC d,5 BSF PORTD,5 ; PORTD.4 = d.4; BTFSS d,4 BCF PORTD,4 BTFSC d,4 BSF PORTD,4 ; E = 1; E = 0; BSF PORTD,2 BCF PORTD,2 ; ; PORTD.7 = d.3; BTFSS d,3 BCF PORTD,7 BTFSC d,3 BSF PORTD,7 ; PORTD.6 = d.2; BTFSS d,2 BCF PORTD,6 BTFSC d,2 BSF PORTD,6 ; PORTD.5 = d.1; BTFSS d,1 BCF PORTD,5 BTFSC d,1 BSF PORTD,5 ; PORTD.4 = d.0; BTFSS d,0 BCF PORTD,4 BTFSC d,0 BSF PORTD,4 ; E = 1; E = 0; BSF PORTD,2 BCF PORTD,2 ;} RETURN ; ;//Sends a given string to the LCD. Will start printing from ;//current cursor position. ;void send_string(const char *incoming_string) ;{ send_string ; uns8 x; ; ; for(x = 0 ; incoming_string[x] != '\0' ; x++) CLRF x m019 MOVF x,W ADDWF incoming_string,W CALL _const1 XORLW .0 BTFSC 0x03,Zero_ GOTO m020 ; send_char(incoming_string[x]); MOVF x,W ADDWF incoming_string,W CALL _const1 CALL send_char INCF x,1 GOTO m019 ;} m020 RETURN ; ;//General short delay ;void delay_ms(uns16 x) ;{ delay_ms ; uns8 y, z; ; //Clocks out to 1.00ms per 1ms ; //9.99 ms per 10ms ; for ( ; x > 0 ; x--) m021 MOVF x_2,W IORWF x_2+1,W BTFSC 0x03,Zero_ GOTO m026 ; for ( y = 0 ; y < 4 ; y++) CLRF y m022 MOVLW .4 SUBWF y,W BTFSC 0x03,Carry GOTO m025 ; for ( z = 0 ; z < 176 ; z++); CLRF z m023 MOVLW .176 SUBWF z,W BTFSC 0x03,Carry GOTO m024 INCF z,1 GOTO m023 m024 INCF y,1 GOTO m022 m025 DECF x_2,1 INCF x_2,W BTFSC 0x03,Zero_ DECF x_2+1,1 GOTO m021 ;} m026 RETURN ; ;//Reads e_data from the onboard eeprom at e_address ;uns8 onboard_eeread(uns8 e_address) ;{ onboard_eeread MOVWF e_address ; EEPGD = 0; //Read from EEPROM memory and not program memory BSF 0x03,RP0 BSF 0x03,RP1 BCF 0x18C,EEPGD ; EEADR = e_address; //Set the address to read BCF 0x03,RP0 BCF 0x03,RP1 BSF 0x03,RP1 MOVWF EEADR ; RD = 1; //Read it BSF 0x03,RP0 BSF 0x18C,RD ; ; return(EEDATA); //Read that EEPROM value BCF 0x03,RP0 MOVF EEDATA,W BCF 0x03,RP1 RETURN ;} ; ;//Write e_data to the onboard eeprom at e_address ;void onboard_eewrite(uns8 e_data, uns8 e_address) ;{ onboard_eewrite MOVWF e_address_2 ; bit temp_GIE = GIE; BCF 0x2D,temp_GIE BTFSC 0x0B,GIE BSF 0x2D,temp_GIE ; ; EEPGD = 0; //Read from EEPROM memory and not program memory BSF 0x03,RP0 BSF 0x03,RP1 BCF 0x18C,EEPGD ; ; EEIF = 0; //Clear the write completion intr flag BCF 0x03,RP0 BCF 0x03,RP1 BCF 0x0D,EEIF ; EEADR = e_address; //Set the address BSF 0x03,RP1 MOVWF EEADR ; EEDATA = e_data; //Give it the data BCF 0x03,RP1 MOVF e_data,W BSF 0x03,RP1 MOVWF EEDATA ; WREN = 1; //Enable EE Writes BSF 0x03,RP0 BSF 0x18C,WREN ; GIE = 0; //Disable Intrs BCF 0x0B,GIE ; ; //Specific EEPROM write steps ; EECON2 = 0x55; MOVLW .85 MOVWF EECON2 ; EECON2 = 0xAA; MOVLW .170 MOVWF EECON2 ; WR = 1; BSF 0x18C,WR ; //Specific EEPROM write steps ; ; while(WR == 1); //Wait for write to complete m027 BTFSC 0x18C,WR GOTO m027 ; WREN = 0; //Disable EEPROM Writes BCF 0x18C,WREN ; ; GIE = temp_GIE; //Set GIE to its original state BCF 0x03,RP0 BCF 0x03,RP1 BTFSS 0x2D,temp_GIE BCF 0x0B,GIE BTFSC 0x2D,temp_GIE BSF 0x0B,GIE ;} RETURN ; ;//The following are printf routines and UART control for sending serial characters and strings to the computer ;//============================================================= ; ;//Sends nate to the Transmit Register ;void putc(uns8 nate) ;{ putc MOVWF nate ; while(TXIF == 0); m028 BTFSS 0x0C,TXIF GOTO m028 ; TXREG = nate; MOVF nate,W MOVWF TXREG ;} RETURN ; ;uns8 getc(void) ;{ getc ; while(RCIF == 0); BCF 0x03,RP0 BCF 0x03,RP1 m029 BTFSS 0x0C,RCIF GOTO m029 ; return (RCREG); MOVF RCREG,W RETURN ;} ; ;//Returns ASCII Decimal and Hex values ;uns8 bin2Hex(char x) ;{ bin2Hex MOVWF x_3 ; skip(x); MOVLW .2 MOVWF PCLATH MOVF x_3,W ADDWF PCL,1 ; #pragma return[16] = "0123456789ABCDEF" RETLW .48 RETLW .49 RETLW .50 RETLW .51 RETLW .52 RETLW .53 RETLW .54 RETLW .55 RETLW .56 RETLW .57 RETLW .65 RETLW .66 RETLW .67 RETLW .68 RETLW .69 RETLW .70 ;} ; ;//Prints a string including variables ;void printf(const char *nate, int16 my_byte) ;{ printf ; ; uns8 i, k, m, temp; ; uns8 high_byte = 0, low_byte = 0; CLRF high_byte CLRF low_byte ; uns8 y, z; ; ; uns8 decimal_output[5]; ; ; for(i = 0 ; ; i++) CLRF i_2 ; { ; k = nate[i]; m030 MOVF i_2,W ADDWF nate_2,W CALL _const1 MOVWF k ; ; if (k == '\0') MOVF k,1 BTFSC 0x03,Zero_ ; break; GOTO m053 ; ; else if (k == '%') //Print var XORLW .37 BTFSS 0x03,Zero_ GOTO m051 ; { ; i++; INCF i_2,1 ; k = nate[i]; MOVF i_2,W ADDWF nate_2,W CALL _const1 MOVWF k ; ; if (k == '\0') MOVF k,1 BTFSC 0x03,Zero_ ; break; GOTO m053 ; else if (k == '\\') //Print special characters XORLW .92 BTFSS 0x03,Zero_ GOTO m031 ; { ; i++; INCF i_2,1 ; k = nate[i]; MOVF i_2,W ADDWF nate_2,W CALL _const1 MOVWF k ; ; putc(k); CALL putc ; ; ; } //End Special Characters ; else if (k == 'b') //Print Binary GOTO m052 m031 MOVF k,W XORLW .98 BTFSS 0x03,Zero_ GOTO m036 ; { ; for( m = 0 ; m < 8 ; m++ ) CLRF m_2 m032 MOVLW .8 SUBWF m_2,W BTFSC 0x03,Carry GOTO m052 ; { ; if (my_byte.7 == 1) putc('1'); BTFSS my_byte,7 GOTO m033 MOVLW .49 CALL putc ; if (my_byte.7 == 0) putc('0'); m033 BTFSC my_byte,7 GOTO m034 MOVLW .48 CALL putc ; if (m == 3) putc(' '); m034 MOVF m_2,W XORLW .3 BTFSS 0x03,Zero_ GOTO m035 MOVLW .32 CALL putc ; ; my_byte = my_byte << 1; m035 BCF 0x03,Carry RLF my_byte,1 RLF my_byte+1,1 ; } INCF m_2,1 GOTO m032 ; } //End Binary ; else if (k == 'd') //Print Decimal m036 MOVF k,W XORLW .100 BTFSS 0x03,Zero_ GOTO m047 ; { ; //Print negative sign and take 2's compliment ; /* ; if(my_byte < 0) ; { ; putc('-'); ; my_byte ^= 0xFFFF; ; my_byte++; ; } ; */ ; ; if (my_byte == 0) MOVF my_byte,W IORWF my_byte+1,W BTFSS 0x03,Zero_ GOTO m037 ; putc('0'); MOVLW .48 CALL putc ; else GOTO m052 ; { ; //Divide number by a series of 10s ; for(m = 4 ; my_byte > 0 ; m--) m037 MOVLW .4 MOVWF m_2 m038 BTFSC my_byte+1,7 GOTO m045 MOVF my_byte,W IORWF my_byte+1,W BTFSC 0x03,Zero_ GOTO m045 ; { ; temp = my_byte % (uns16)10; MOVF my_byte,W MOVWF C7tmp MOVF my_byte+1,W MOVWF C7tmp+1 CLRF temp_2 MOVLW .16 MOVWF C6cnt m039 RLF C7tmp,1 RLF C7tmp+1,1 RLF temp_2,1 BTFSC 0x03,Carry GOTO m040 MOVLW .10 SUBWF temp_2,W BTFSS 0x03,Carry GOTO m041 m040 MOVLW .10 SUBWF temp_2,1 m041 DECFSZ C6cnt,1 GOTO m039 ; decimal_output[m] = temp; MOVLW .54 ADDWF m_2,W MOVWF FSR BCF 0x03,IRP MOVF temp_2,W MOVWF INDF ; my_byte = my_byte / (uns16)10; MOVF my_byte,W MOVWF C9tmp MOVF my_byte+1,W MOVWF C9tmp+1 CLRF C10rem MOVLW .16 MOVWF C8cnt m042 RLF C9tmp,1 RLF C9tmp+1,1 RLF C10rem,1 BTFSC 0x03,Carry GOTO m043 MOVLW .10 SUBWF C10rem,W BTFSS 0x03,Carry GOTO m044 m043 MOVLW .10 SUBWF C10rem,1 BSF 0x03,Carry m044 RLF my_byte,1 RLF my_byte+1,1 DECFSZ C8cnt,1 GOTO m042 ; } DECF m_2,1 GOTO m038 ; ; for(m++ ; m < 5 ; m++) m045 INCF m_2,1 m046 MOVLW .5 SUBWF m_2,W BTFSC 0x03,Carry GOTO m052 ; putc(bin2Hex(decimal_output[m])); MOVLW .54 ADDWF m_2,W MOVWF FSR BCF 0x03,IRP MOVF INDF,W CALL bin2Hex CALL putc INCF m_2,1 GOTO m046 ; } ; ; } //End Decimal ; else if (k == 'h') //Print Hex m047 MOVF k,W XORLW .104 BTFSS 0x03,Zero_ GOTO m049 ; { ; //New trick 3-15-04 ; putc('0'); MOVLW .48 CALL putc ; putc('x'); MOVLW .120 CALL putc ; ; if(my_byte > 0x00FF) BTFSC my_byte+1,7 GOTO m048 MOVF my_byte+1,1 BTFSC 0x03,Zero_ GOTO m048 ; { ; putc(bin2Hex(my_byte.high8 >> 4)); SWAPF my_byte+1,W ANDLW .15 CALL bin2Hex CALL putc ; putc(bin2Hex(my_byte.high8 & 0b.0000.1111)); MOVLW .15 ANDWF my_byte+1,W CALL bin2Hex CALL putc ; } ; ; putc(bin2Hex(my_byte.low8 >> 4)); m048 SWAPF my_byte,W ANDLW .15 CALL bin2Hex CALL putc ; putc(bin2Hex(my_byte.low8 & 0b.0000.1111)); MOVLW .15 ANDWF my_byte,W CALL bin2Hex CALL putc ; ; } //End Hex ; else if (k == 'f') //Print Float GOTO m052 m049 MOVF k,W XORLW .102 BTFSS 0x03,Zero_ GOTO m050 ; { ; putc('!'); MOVLW .33 CALL putc ; } //End Float ; else if (k == 'u') //Print Direct Character GOTO m052 m050 MOVF k,W XORLW .117 BTFSS 0x03,Zero_ GOTO m052 ; { ; //All ascii characters below 20 are special and screwy characters ; //if(my_byte > 20) ; putc(my_byte); MOVF my_byte,W CALL putc ; } //End Direct ; ; } //End Special Chars ; ; else GOTO m052 ; putc(k); m051 MOVF k,W CALL putc ; } m052 INCF i_2,1 GOTO m030 m053 RETURN ORG 0x2007 DATA 3F32H END ; *** KEY INFO *** ; 0x0004 P0 19 word(s) 0 % : serverX ; 0x015B P0 31 word(s) 1 % : boot_up ; 0x0233 P0 24 word(s) 1 % : delay_ms ; 0x017A P0 69 word(s) 3 % : init_lcd ; 0x01D4 P0 41 word(s) 2 % : send_char ; 0x01FD P0 40 word(s) 1 % : send_cmd ; 0x0225 P0 14 word(s) 0 % : send_string ; 0x01BF P0 21 word(s) 1 % : LCD_wait ; 0x024B P0 14 word(s) 0 % : onboard_eeread ; 0x0259 P0 34 word(s) 1 % : onboard_eewrite ; 0x027B P0 6 word(s) 0 % : putc ; 0x0281 P0 6 word(s) 0 % : getc ; 0x0287 P0 21 word(s) 1 % : bin2Hex ; 0x029C P0 192 word(s) 9 % : printf ; 0x00AE P0 173 word(s) 8 % : main ; 0x0017 P0 91 word(s) 4 % : _const1 ; RAM usage: 43 bytes (33 local), 325 bytes free ; Maximum call level: 5 (+1 for interrupt) ; Codepage 0 has 857 word(s) : 41 % ; Codepage 1 has 0 word(s) : 0 % ; Codepage 2 has 0 word(s) : 0 % ; Codepage 3 has 0 word(s) : 0 % ; Total of 797 code words (9 %)