Anda di halaman 1dari 11

; ROCKET1.ASM ; by Tom Consi ; 3/25/97 ; rev.

3/30/97 ; submitted to Circuit Cellar Ink 6/25/98 ; ; Software to accompany the article ; Smart Rockets: A Data Acquisition System for Model Rockets ; by Tom Consi and Jim Bales ; ; Software operates in 2 modes: ; Mode A - read 8912 A/D values at 1KHz, store in serial flash memory chip. ; Mode B - recall values from serial flash memory and transmit the ; ASCII decimal converted A/D values to a host computer via the USART (SCI ). ; ; 32 byte RAM buffer on the PIC is used to store 1 flash memory sector s worth of A/D values. ; ; On power-up or RESET: ; PIC resources initialized: digital I/O, A/D converter, SPI, SCI, Timer 0 . ; RAM areas set-up to hold SCI messages. ; XICOR X25F128 serial flash memory initialized, see Xicor data sheet for details. ; Wait 10msec for serial flash chip to stabilize. ; High->Low transition (held for 2uS) on CS ; to wake-up serial flash from low-power mode. ; ; After initialization green LED is turned on to indicate that system ; is armed and waiting for a trigger signal. ; RB0 is used to trigger the system and is polled endlessly. ; RB0 normally high, when RB0 = 0 the system is triggered and either mode A or B is executed. ; ; Program then reads RB1 to determine mode. ; Red LED is on and green LED is off during execution of either mode. ; ; Mode A, RB1 = 0: Read and store A/D values ; A/D converter is read at 1 KHz, raw values stored in RAM buffer. ; When buffer full the buffer contents are transmitted to the serial flash chip ; via the SPI during a single A/D inter-conversion interval (1mS). ; Writing the buffer values to the serial flash occurs during the ; following buffer-fill interval (32mS). ; Input terminates when the 8912th A/D value is read. ; When input terminated, the final sector (sector #255) is written ; to the serial flash memory, a total of 256 sectors written. ; For debugging purposes the following data acquired termination message i s sent via the SCI: ; "XIn<CR><LF>" ; Red LED turned off, green LED turned on. ; Program loops back to poll RB0. ; ; Mode B, RB1 = 1: Recall and convert A/D values and transmit them via the SCI. ; Each raw A/D value stored in the serial flash is read via the SPI, ; converted to a 3byte ASCII decimal number and ; transmitted via the SCI at 9600 BAUD. ; Stops reading the serial flash when 8192th value is read (sector #255). ; Each converted value is output in the following format:

; <MSByte><MidByte><LSByte><CR><LF> ; Data output termination message is then sent: ; "XOut<CR><LF>" ; Red LED turned off, green LED turned on. ; Program loops back to poll RB0. ; ; LED indicators: ;Green LED (RB6) ; System armed and waiting for trigger signal. ;Red LED (RB7) ; System either acquiring data or transmitting data (in either mode A or B ). ; ; Debugging indicators ; RB2->1 = Initialization code executed. ; RB3 toggles on SCI transmit character, Mode B. ; RB4 toggles on SPI byte transfer. ; RB5 toggles on A/D conversion. ; ; Summary of PIC resources used: ; RA0, analog input from the accelerometer. ; RB0, input, trigger input. ; RB1, input, mode select pin. ; RB2-5, outputs for debugging ; RB6, output for Green LED, high = LED ON ; RB7, output for Red LED, high = LED ON ; SS (RC0), Slave select output to serial flash memory chip. ; SCK (RC3), SPI serial clock to serial flash. ; SDI (RC4), SPI serial data in from serial flash. ; SDO (RC5), SPI serial data out to serial flash. ; TX (RC6), SCI serial transmit. ; RX (RC7), SCI serial receive. ; TMR0, A/D sampling rate timer ; ; PIC operates at 4MHz ; ; processor 16C73 include "P16CXX.INC" ; Include file from the PICSTART 16C development system. ; ; ; Custom equates BUFFER_SIZE equ D'32' ; 32 character RAM buffer SECTOR_SIZE equ D'32' ; 32 byte serial flash sector size ; ; Note - make the following NUMBER constants 1 less than the number desired. ; I ve set the system to record 8192 bytes of data (256 - 32 byte sectors). ; The Xicor X25F128 chip can hold up to 16384 bytes (512 - 32 byte sectors). SECTOR_HI_NUMBER equ 00 ; MSByte of number of se rial flash sectors SECTOR_LO_NUMBER equ 0FF ; LSByte of number of serial fla sh sectors DATA_BYTES_HI_NUMBER equ 1F ; MSByte of number of data bytes DATA_BYTES_LO_NUMBER equ 0FF ; LSByte of number of data bytes ; CON_TIME equ D'125' ; Data sampling rate in timer tics BAUDX equ D'25' ; Baud rate register (SPBRG) for: ; 9600 BAUD, 4MHz Fosc, BRGH = 1 ; .156% BAUD rate error

SS equ 00 ; Slave select bit for SPI delay equ D'13' ; Power-up delay time in .768msec units ; TERM_CHAR equ 0FF ; Message termination character C_RETURN equ 0D ; ASCII carriage return <CR> L_FEED equ 0A ; ASCII line feed <LF> ; ; Serial flash memory commands PREN equ 06 ; Set program enable latch (enab le prog.) PRDI equ 04 ; Reset program enable latch (di sable prog.) RSDR equ 05 ; Read status register PRSR equ 01 ; Program status register READ equ 03 ; Read serial flash starting at selected addr. PROGRAM equ 02 ; Program serial flash starting at selec ted addr. ; ; ; RAM variables org 0020 ad_counter res 1 ; A/D converter value counter del_1_counter res 1 ; Power-up delay counter 1 del_2_counter res 1 ; Power-up delay counter 2 sef_hi_addr res 1 ; serial flash high address sef_lo_addr res 1 ; serial flash low address sector_hi_counter res 1 ; MSByte serial flash sector counter sector_lo_counter res 1 ; LSByte serial flash sector cou nter buf_full_flag res 1 ; RAM buffer full flag ; bit 0 = 0, buff er not full ; bit 1 = 1, buffer full con_holder res 1 ; Sample interval holder raw_holder res 1 ; Holds raw A/D value for ASCII con. hundreds res 1 ; Holds ASCII hundreds of con. A /D tens res 1 ; Holds ASCII tens of co n. A/D ones res 1 ; Holds ASCII ones of co n. A/D end_asc_mes res 3 ; Holds <CR><LF> and $FF din_term_mes res 6 ; Data acquired termination mess age dout_term_mes res 7 ; Data output termination messag e ram_buffer res BUFFER_SIZE ; RAM character buffer ; ; org 0000 ; Load RESET interrupt vector goto start org 0004 ; Load Timer 0 interrupt vector goto a_to_d ; org 0005 ; Start of code start ; Initialize A/D converter (Port A) bsf STATUS,RP0 ; Select bank 1

movlw ef = Vdd movwf bcf movlw t channel 0

B'00000100' ADCON1 STATUS,RP0 B'11000001' ; Bank 0

; RA0,1,3 = analog in, R

; A/D clock = Frc, selec

movwf ADCON0 ; A/D module is on ; ; Initialize Port B clrf PORTB ; clear Port B bsf STATUS,RP0 ; Select bank 1 movlw B'00000011' ; RB0,1 inputs, RB2-7 ou tputs movwf TRISB bcf STATUS,RP0 ; Bank 0 ; ; Initialize Port C movlw B'00000001' ; RC0 (SS) is high movwf PORTC bsf STATUS,RP0 ; Bank 1 movlw B'10010110' ; RC0,3,5,6 - outputs movwf TRISC ; RC1,2,4,7 - inputs bcf STATUS,RP0 ; Bank 0 ; ; Inititalize sync serial port (SPI) for SPI operation movlw B'00010000' ; CPOL = 1, clock = OSC/4 movwf SSPCON bsf SSPCON,SSPEN ; Enable SPI ; ; Initialize USART (SCI) bsf STATUS,RP0 ; Bank 1 movlw BAUDX ; BAUD rate = 9600 movwf SPBRG bsf TXSTA,BRGH ; High BAUD rate select bsf TXSTA,TXEN ; Enable transmitter bcf STATUS,RP0 ; Bank 0 bsf RCSTA,CREN ; Enable continuous receive bsf RCSTA,SPEN ; Enable serial port ; ; Initialize Timer 0 ; Prescale = 8, 1 tic == 8uS, 1 kHz -> 1000 uS = 125 tics clrwdt bsf STATUS,RP0 ; Point to bank 1 movlw B'00000010' ; Prescale = 8 movwf OPTION_REG bcf STATUS,RP0 ; Bank 0 ; Process conversion time to load into Timer 0 movlw CON_TIME movwf con_holder movlw 2 ; Lose 2 tics on timer l oad subwf con_holder,F comf con_holder,F ; Timer counting up, complement ; ; Fill message areas movlw C_RETURN ; ASCII A/D value message movwf end_asc_mes movlw L_FEED movwf end_asc_mes+1 movlw TERM_CHAR

movwf ; movlw ion message movwf movlw movwf movlw movwf movlw movwf movlw movwf movlw movwf ; movlw n message movwf movlw movwf movlw movwf movlw movwf movlw movwf movlw movwf movlw movwf

end_asc_mes+2 'X' din_term_mes 'I' din_term_mes+1 'n' din_term_mes+2 C_RETURN din_term_mes+3 L_FEED din_term_mes+4 TERM_CHAR din_term_mes+5 'X' dout_term_mes 'O' dout_term_mes+1 'u' dout_term_mes+2 't' dout_term_mes+3 C_RETURN dout_term_mes+4 L_FEED dout_term_mes+5 TERM_CHAR dout_term_mes+6 ; Data output terminatio ; Data acquired terminat

; ; Software delay for about 10msec ; to allow serial flash memory chip to stabilize. movlw delay movwf del_1_counter clrf del_2_counter deloop decfsz del_2_counter,F ;Inner loop takes ~.768msec goto deloop decfsz del_1_counter,F goto deloop ; ; Make High->Low transition on CS to wake-up serial flash ; memory from low-power mode on power-up. bcf PORTC,SS ; Select serial flash nop ; 2uS delay for the hell of it nop bsf PORTC,SS ; Deselect serial flash ; bsf complete ; ; bsf PORTB,6 rmed and waiting for trigger signal. poll_l btfsc PORTB,0 goto poll_l ng ; Green LED ON, system a ; Poll for trigger ; No trigger, keep polli PORTB,2 ; Debug, initialization

; clrf sector 0 clrf sef_lo_addr ; ; ; Check Mode pin RB1, 0 = Mode A, 1 = Mode B btfsc PORTB,1 goto mode_b ; bcf PORTB,6 ; Green LED OFF, system has been triggered. bsf PORTB,7 ; Red LED ON, enter mode A ; ; Intialize serial flash sector counters movlw SECTOR_HI_NUMBER movwf sector_hi_counter movlw SECTOR_LO_NUMBER movwf sector_lo_counter ; ; Enable timer 0 interrupt movf con_holder,W ; Load time delay into t imer 0 movwf TMR0 movlw B'10100000' ; Enable TMR0, and all i nts movwf INTCON ; ; Point to top of RAM buffer nxt_sct movlw BUFFER_SIZE movwf ad_counter movlw ram_buffer+BUFFER_SIZE-1 movwf FSR clrf buf_full_flag ; Clear buffer full flag ; ; Data acquisition loops, fills buffer and serial flash sectors ; until all data acquired. b_loop btfss buf_full_flag,0 ; Is buffer full? goto b_loop ; No, keep a-loopin! ; ; Store characters in RAM buffer in serial flash ; Point to top of RAM buffer movlw BUFFER_SIZE movwf ad_counter movlw ram_buffer+BUFFER_SIZE-1 movwf FSR ; ; Initialize serial flash to be programmed bcf PORTC,SS ; Select serial flash movlw PREN ; Transmit program enabl e instruction call spi_xfr bsf PORTC,SS ; Deselect serial flash ; ; Transmit program inst. and sector address to serial flash bcf PORTC,SS ; Select serial flash movlw PROGRAM ; Send PROGRAM instruction call spi_xfr movf sef_hi_addr,W ; Send serial flash sect sef_hi_addr ; Point to serial flash

or address call movf call spi_xfr sef_lo_addr,W spi_xfr

; ; Send data to serial flash tx_sef movf INDF,W ; Get raw A/D value from RAM buffer call spi_xfr decf FSR,F ; Move to next byte in b uffer decfsz ad_counter,F ; Check for end of buffe r goto tx_sef ; Not finished with buff er, get more data bsf PORTC,SS ; Finished sending data deselect serial flash ; ; Increment serial flash sector start address movlw SECTOR_SIZE addwf sef_lo_addr,F btfsc STATUS,C incf sef_hi_addr,F ; ; Decrement sector counters, test to see if must terminate movf sector_lo_counter,F ; Check if low b yte = 0 btfsc STATUS,Z goto dec_msb ; It's 0, check hi byte decf sector_lo_counter,F ; Not 0, decreme nt lo byte goto nxt_sct ; Continue acqui sition ; dec_msb movf sector_hi_counter,F ; Check if hi by te = 0 btfsc STATUS,Z goto termaq ; It's 0 , terminate data acquisition decf sector_lo_counter,F ; Not 0, decrement both counters decf sector_hi_counter,F goto nxt_sct ; Contin ue acquisition ; ; Data acquisition terminated, disable interrupts termaq bcf INTCON,GIE ; movlw din_term_mes ; Point to data acquired termination message. movwf FSR call tx_mes ; Transmit data acquired termination message.. ; ; Test to see if RB0 is high again. rbloop btfss PORTB,0 goto rbloop bcf PORTB,7 ; Red LED OFF, exit mode A

bsf goto

PORTB,6 poll_l

; Green LED ON ; RB0 low, go wait for t

rigger signal. ; ; ; ******* MODE B ******* ; mode_b bcf PORTB,6 ; Green LED OFF bsf PORTB,7 ; Red LED ON, enter Mode B ; ; Intialize serial flash memory sector counters ; In Mode B using sector counters to count total number of data bytes movlw DATA_BYTES_HI_NUMBER movwf sector_hi_counter movlw DATA_BYTES_LO_NUMBER movwf sector_lo_counter ; ; Set-up serial flash to transmit data to PIC. bcf PORTC,SS ; Select serial flash movlw READ ; Transmit READ instruct ion call spi_xfr movf sef_hi_addr,W ; Transmit sector addres s call spi_xfr movf sef_lo_addr,W call spi_xfr ; ; Read an A/D raw value from serial flash, transmit via SCI get_sef call spi_xfr ; Get a data byte from s erial flash call asci_con ; Convert value to decim al ASCII movlw hundreds ; Point to A/D ASCII mes sage movwf FSR call tx_mes ; Transmit A/D value ; movlw '0' ; Clear hundreds, tens and ones movwf hundreds movwf tens movwf ones ; ; Decrement data counters, test to see if must terminate movf sector_lo_counter,F ; Check if low b yte = 0 btfsc STATUS,Z goto dec_msb2 ; It's 0, check hi byte decf sector_lo_counter,F ; Not 0, decreme nt lo byte goto get_sef ; Continue readi ng serial flash ; dec_msb2 movf sector_hi_counter,F ; Check if hi byte = 0 btfsc STATUS,Z goto end_sef ; It's 0, terminate read ing serial flash decf sector_lo_counter,F ; Not 0, decreme

nt both counters ; Continue readi ng serial flash ; end_sef bsf PORTC,SS ; Deselect seria l flash ; movlw dout_term_mes ; Point to data output termination message movwf FSR call tx_mes ; Transmit data output termination message ; ; Test to see if RB0 is high again rbloop2 btfss PORTB,0 goto rbloop2 bcf PORTB,7 ; Red LED OFF, exit Mode B bsf PORTB,6 ; Green LED ON goto poll_l ; RB0 high, go wait for trigger. ; ; ; *** End of "main" subroutines follow *** ; ; ; a_to_d, Timer 0 interrupt routine ; Does A/D conversion and stores value in RAM buffer ; Enter with buffer position in FSR and byte count in ad_counter ; Return with FSR and ad_counter decremented and ; buf_full_flag set accordingly. a_to_d movf con_holder,W ; Re load Timer 0 movwf TMR0 ; bsf ADCON0,GO_DONE ; Start A/D conversion pol_ad btfsc ADCON0,GO_DONE ; Test if A/D conversion finished goto pol_ad ; Not done, poll A/D movf ADRES,W ; Save A/D value in buffer movwf INDF ; movlw B'00100000' ; Debug, toggle RB5 on A/D conversion xorwf PORTB,F ; decf FSR,F ; Move to next b yte in RAM buffer decfsz ad_counter,F ; Check for end of buffe r goto go_ret ; Buffer not full bsf buf_full_flag,0 ; Buffer full, s et bit 0 of buf_full_flag go_ret bcf INTCON,T0IF ; Clear Timer 0 flag retfie ; ; ; spi_xfr, Routine to send/receive bytes via SPI decf goto sector_hi_counter,F get_sef

; Enter with byte to send in W ; Exit with received byte in W spi_xfr movwf SSPBUF ; Send byte s_loop bsf STATUS,RP0 ; Bank 1 btfss SSPSTAT,BF ; Data received/xmit com plete? goto s_loop ; No, go poll bcf STATUS,RP0 ; Bank 0 ; movlw B'00010000' ; Debug, toggle RB4, co mpleted SPI xorwf PORTB,F ; movf SSPBUF,W ; Received byte -> W return ; ; ; tx_mes ; Transmit ASCII message via SCI ; Enter with pointer to message in FSR, return with nothing ; Outputs terminates when encounter termination character ($FF). tx_mes bsf STATUS,RP0 ; Bank 1 x_poll btfss TXSTA,TRMT ; Finished transmitting previous byte? goto x_poll ; No, go poll bcf STATUS,RP0 ; Bank 0 ; btfsc INDF,7 ; Test for termi nation character goto endmes ; Termination ch ar, message over ; movf INDF,W ; Get char movwf TXREG ; Send char ; movlw B'00001000' ; Debug, toggle RB3 on transmitted byte xorwf PORTB,F ; incf FSR,F ; Point to next char goto tx_mes ; endmes return ; ; ; asci_con ; Convert binary data byte to 3 decimal ASCII bytes ; Enter with value to convert in W and ; hundreds, tens and ones RAM holders cleared. ; Exit with converted value in RAM (hundreds, tens, ones) asci_con movwf raw_holder movlw D'100' ; Convert hundreds go_huns subwf raw_holder,F btfss STATUS,C goto cont_10 ; Finished converting 10 0's incf hundreds,F goto go_huns

; cont_10 go_tens

addwf movlw subwf btfss goto incf goto addwf addwf return

raw_holder,F D'10' raw_holder,F STATUS,C cont_1 tens,F go_tens raw_holder,W ones,F

; Convert tens

; Finished converting 10's

; cont_1 ; ; ; ROCKET1.ASM

; Ones done

end 06/25/98

Anda mungkin juga menyukai