You are on page 1of 6

;********************************************************************** ; * ; Filename: USB_Code_test.asm * ; Date: 15th April 2006 * ; File Version: 1.

0 * ; * ; Author: Ian Stedman * ; Company: * ; * ; * ;********************************************************************** ; * ; Files required: * ; * ; * ; * ;********************************************************************** ; * ; Notes: * ; A simple program to test the PIC16F877 to FTDI USB interface. * ; It sends 'walking bit codes that are used to verify that there * ; Are no stuck bits or solder shorts between pins. ; * ; * ;********************************************************************** list p=16f877 #include <p16f877.inc> ; list directive to define processor ; processor specific variable definitions

__CONFIG _LVP_OFF & _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_OFF & _HS_OS C & _WRT_ENABLE_ON & _DEBUG_OFF & _CPD_OFF ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. ;***** VARIABLE DEFINITIONS w_temp EQU 0x40 status_temp EQU 0x42 adcresult EQU 0x44 usbdatarx EQU 0x46 usbdatatx EQU 0x48 count EQU 0x50 temp EQU 0x52 time EQU 0x54 READBIT EQU 0 WRITEBIT EQU 1 TXFULL EQU 2 B RXFULL EQU 3 B INPORT EQU 255 OUTPORT EQU 0 uts

; variable used for context saving ; variable used for context saving ; ADC conversion result ; Byte received from USB port ; Byte to send via USB

; PORT C Read bit to USB ; PORT C Write bit to USB ; PORT C TX Full input from US ; PORT C RX Full input from US ; Sets an I/O port as all inputs ; Seta an I/O port as all outp

;********************************************************************** ORG 0x000 ; processor reset vector clrf PCLATH ; ensure page bits are cleared

goto ORG movwf movf movwf

main 0x004 w_temp STATUS,w status_temp

; go to beginning of program ; ; ; ; interrupt vector location save off current W register contents move status register into W register save off contents of STATUS register

; isr code can go here or be located as a call subroutine elsewhere movf movwf ents swapf w_temp,f swapf w_temp,w retfie ; restore pre-isr W register contents ; return from interrupt status_temp,w STATUS ; retrieve copy of STATUS register ; restore pre-isr STATUS register cont

main mainloop

picinit usbrecv call display movlw 20 movwf time call delay ; Start of the test code. The idea is to turn on each data bit individually, giv ing 32 codes for the 8 bit interface movlw h'00' movwf usbdatatx call usbsend movlw h'01' movwf usbdatatx call usbsend movlw h'02' movwf usbdatatx call usbsend movlw h'03' movwf usbdatatx call usbsend movlw h'04' movwf usbdatatx call usbsend movlw h'05' movwf usbdatatx call usbsend movlw h'06' movwf usbdatatx call usbsend movlw h'07' movwf usbdatatx call usbsend movlw h'08' movwf usbdatatx call usbsend movlw h'09' movwf usbdatatx call usbsend movlw h'0A'

call call

movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw movwf call movlw

usbdatatx usbsend h'0B' usbdatatx usbsend h'0C' usbdatatx usbsend h'0D' usbdatatx usbsend h'0E' usbdatatx usbsend h'0F' usbdatatx usbsend h'10' usbdatatx usbsend h'20' usbdatatx usbsend h'30' usbdatatx usbsend h'40' usbdatatx usbsend h'50' usbdatatx usbsend h'60' usbdatatx usbsend h'70' usbdatatx usbsend h'80' usbdatatx usbsend h'90' usbdatatx usbsend h'A0' usbdatatx usbsend h'B0' usbdatatx usbsend h'C0' usbdatatx usbsend h'D0' usbdatatx usbsend h'E0' usbdatatx usbsend h'F0'

movwf call movlw movwf call

usbdatatx usbsend h'00' usbdatatx usbsend

goto ; remaining code goes here picinit

mainloop

banksel OPTION_REG movlw H'07' movwf OPTION_REG ock by 256 movlw movwf -7] outputs movwf movlw USB port) bcf rite) movlw movwf TRISC INPORT banksel TRISB OUTPORT TRISB movwf TRISA movlw H'0C'

; Set TMR0 to divide internal cl

;portb [7-0] outputs ;porta [7-0] outputs ;setup portc [2-3] inputs [0-1,4 ;setup portd as inputs for now (

movwf TRISD clrf ADCON1 ;left justified, all inputs a/d STATUS,RP0 ;bank 0 movlw H'FF' movwf PORTC ; Ensure Ouputs are 1 (no read/w clrf PORTB ; All LEDs off. clrf PORTA B'01000001' ;Fosc/8 [7-6], A/D ch0 [5-3], a/d on [0] ADCON0 bsf PORTC,6 ; Debug return

; At the moment a simple function to output the received USB value to the 8 LEDs on Port B display movf bcf movf movwf bsf bsf bsf return usbdatarx,W PORTC,7 usbdatarx,W PORTB PORTC,7 PORTC,6 PORTC,5 ; Recall received data ; Output it, job done!

; A function to check for data received from the USB interface and if present, r ead it. ; USB is on port D, RC0=READ, RC3=RX_Flag usbrecv btfsc PORTC,RXFULL ; See if RX_flag = 0 which indicates the re is data in the FIFO retlw 0 ; return 0 for no data ;If we got here there is data to read. Set PORT D = Input, READ=

High, wait, READ=Low then read port D banksel TRISD movlw INPORT movwf TRISD ; PORT D now input, safe to star t the read access. banksel PORTD bsf PORTC,READBIT nop nop bcf PORTC,READBIT ; READ now active LOW so READ po rt D nop nop movf PORTD,W movwf usbdatarx bsf PORTC,READBIT ; Set RD = hig return ; A function to send a byte of information via the USB interface. Checks the TXF flag prior to sending. ; USB is on port D, RC1=Write, RC2=TX_Flag ; The data to send will be in usbdatatx usbsend movf btfsc to transmit. retlw how???? ;If we get here we can transmit. Set PORT D = output, WRITE=High , Wait, WRITE=Low then Write Data, Write=High banksel TRISD movlw OUTPORT movwf TRISD ; PORT D now output banksel PORTD bsf PORTC,WRITEBIT ; Make sure WR is high before dat a output. movf usbdatatx,W movwf PORTD nop bcf PORTC,WRITEBIT ; Write now active nop bsf PORTC,WRITEBIT ; All done, WR = high. ; Now tristate the databus, set PORT D to input. banksel TRISD movlw INPORT movwf TRISD ; PORT D now input banksel PORTD ; Return to page 0 nop return ;******************************************************************* ; DELAY Subroutine. This routine provides a 1 second delay. Call for ; as long as you want by storing your desired delay in 'time' before ; calling. ; EXAMPLE ; movlw 10 ; The value here determines the time delay in seconds. ; movwf time ; Store the value. ; call delay ; call the delay routine. 0 ; Return with 0 if full PORTC,W PORTC,TXFULL ; Read in PORT C for debug ; See if TX_Flag = 0 which indicates OK

; delay call delay1 ; these lines make sure that the 1 second loop executes n times. decfsz time goto delay return ; When time is up, return from subroutine. delay1 ; The code here initialise the RTCC. bsf STATUS,RP0 movlw 0x07 ; For use by RTCC, prescaler was /256 or 0x07 movwf OPTION_REG ; ditto bcf STATUS,RP0 clrf TMR0 movlw 0x0e ; Delay time value for 1 second movwf count ; store the value movwf temp sloop ; What follows is the actual delay loop for 1 second. btfsc TMR0,5 ; Reset the RTCC, wait for TMR0 bit 5 to go hich goto jmp1 goto sloop jmp1 wlooplo clrf TMR0 ; RTCC is cleared so decrement the count & repeat. decfsz count goto sloop decfsz temp,F goto wlooplo return END ; directive 'end of program'

You might also like