Rocket Code

Embed Size (px)

Citation preview

  • 7/29/2019 Rocket Code

    1/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 sectors worth ofA/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 Bis 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 flashchip; 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 is sent via the SCI:

    ; "XIn"; 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:

  • 7/29/2019 Rocket Code

    2/11

    ; ; Data output termination message is then sent:; "XOut"; 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 16C73include "P16CXX.INC" ; Include file from the PICSTART 16C development system.;;; Custom equatesBUFFER_SIZE equ D'32' ; 32 character RAM bufferSECTOR_SIZE equ D'32' ; 32 byte serial flash sector size;; Note - make the following NUMBER constants 1 less than the number desired.; Ive 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 sectorsSECTOR_LO_NUMBER equ 0FF ; LSByte of number of serial flash sectorsDATA_BYTES_HI_NUMBER equ 1F ; MSByte of number of data bytesDATA_BYTES_LO_NUMBER equ 0FF ; LSByte of number of data bytes;CON_TIME equ D'125' ; Data sampling rate in timer ticsBAUDX equ D'25' ; Baud rate register (SPBRG) for:

    ; 9600 BAUD, 4MHz Fosc, BRGH = 1; .156% BAUD rate error

  • 7/29/2019 Rocket Code

    3/11

    SS equ 00 ; Slave select bit for SPIdelay equ D'13' ; Power-up delay time in .768msec units;TERM_CHAR equ 0FF ; Message termination characterC_RETURN equ 0D ; ASCII carriage return L_FEED equ 0A ; ASCII line feed ;; Serial flash memory commandsPREN equ 06 ; Set program enable latch (enable prog.)PRDI equ 04 ; Reset program enable latch (disable prog.)RSDR equ 05 ; Read status registerPRSR equ 01 ; Program status registerREAD equ 03 ; Read serial flash starting atselected addr.PROGRAM equ 02 ; Program serial flash starting at selected addr.;;; RAM variablesorg 0020ad_counter res 1 ; A/D converter value counterdel_1_counter res 1 ; Power-up delay counter 1

    del_2_counter res 1 ; Power-up delay counter 2sef_hi_addr res 1 ; serial flash high addresssef_lo_addr res 1 ; serial flash low addresssector_hi_counter res 1 ; MSByte serial flash sector countersector_lo_counter res 1 ; LSByte serial flash sector counterbuf_full_flag res 1 ; RAM buffer full flag

    ; bit 0 = 0, buffer not full

    ; bit 1 = 1, buffer fullcon_holder res 1 ; Sample interval holderraw_holder res 1 ; Holds raw A/D value for ASCIIcon.

    hundreds res 1 ; Holds ASCII hundreds of con. A/Dtens res 1 ; Holds ASCII tens of con. A/Dones res 1 ; Holds ASCII ones of con. A/Dend_asc_mes res 3 ; Holds and $FFdin_term_mes res 6 ; Data acquired termination messagedout_term_mes res 7 ; Data output termination messageram_buffer res BUFFER_SIZE ; RAM character buffer;

    ;org 0000 ; Load RESET interrupt vectorgoto startorg 0004 ; Load Timer 0 interrupt vectorgoto a_to_d;org 0005 ; Start of codestart; Initialize A/D converter (Port A)

    bsf STATUS,RP0 ; Select bank 1

  • 7/29/2019 Rocket Code

    4/11

    movlw B'00000100' ; RA0,1,3 = analog in, Ref = Vdd

    movwf ADCON1bcf STATUS,RP0 ; Bank 0movlw B'11000001' ; A/D clock = Frc, selec

    t channel 0movwf ADCON0 ; A/D module is on

    ;; Initialize Port B

    clrf PORTB ; clear Port Bbsf STATUS,RP0 ; Select bank 1movlw B'00000011' ; RB0,1 inputs, RB2-7 ou

    tputsmovwf TRISBbcf STATUS,RP0 ; Bank 0

    ;; Initialize Port C

    movlw B'00000001' ; RC0 (SS) is highmovwf PORTC

    bsf STATUS,RP0 ; Bank 1movlw B'10010110' ; RC0,3,5,6 - outputsmovwf TRISC ; RC1,2,4,7 - inputsbcf STATUS,RP0 ; Bank 0

    ;

    ; Inititalize sync serial port (SPI) for SPI operationmovlw B'00010000' ; CPOL = 1, clock = OSC/4movwf SSPCONbsf SSPCON,SSPEN ; Enable SPI

    ;; Initialize USART (SCI)

    bsf STATUS,RP0 ; Bank 1movlw BAUDX ; BAUD rate = 9600movwf SPBRGbsf TXSTA,BRGH ; High BAUD rate selectbsf TXSTA,TXEN ; Enable transmitterbcf STATUS,RP0 ; Bank 0bsf 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

    clrwdtbsf STATUS,RP0 ; Point to bank 1

    movlw B'00000010' ; Prescale = 8movwf OPTION_REGbcf STATUS,RP0 ; Bank 0

    ; Process conversion time to load into Timer 0movlw CON_TIMEmovwf con_holdermovlw 2 ; Lose 2 tics on timer l

    oadsubwf con_holder,Fcomf con_holder,F ; Timer counting up, complement

    ;; Fill message areas

    movlw C_RETURN ; ASCII A/D value messagemovwf end_asc_mesmovlw L_FEEDmovwf end_asc_mes+1movlw TERM_CHAR

  • 7/29/2019 Rocket Code

    5/11

    movwf end_asc_mes+2;

    movlw 'X' ; Data acquired termination message

    movwf din_term_mesmovlw 'I'movwf din_term_mes+1movlw 'n'movwf din_term_mes+2movlw C_RETURNmovwf din_term_mes+3movlw L_FEEDmovwf din_term_mes+4movlw TERM_CHARmovwf din_term_mes+5

    ;movlw 'X' ; Data output terminatio

    n messagemovwf dout_term_mesmovlw 'O'movwf dout_term_mes+1movlw 'u'movwf dout_term_mes+2movlw 't'

    movwf dout_term_mes+3movlw C_RETURNmovwf dout_term_mes+4movlw L_FEEDmovwf dout_term_mes+5movlw TERM_CHARmovwf dout_term_mes+6

    ;; Software delay for about 10msec; to allow serial flash memory chip to stabilize.

    movlw delaymovwf del_1_counterclrf del_2_counter

    deloop decfsz del_2_counter,F ;Inner loop takes ~.768msecgoto deloopdecfsz del_1_counter,Fgoto 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 flashnop ; 2uS delay for the hell

    of itnopbsf PORTC,SS ; Deselect serial flash

    ;bsf PORTB,2 ; Debug, initialization

    complete;;

    bsf PORTB,6 ; Green LED ON, system armed and waiting for trigger signal.poll_l btfsc PORTB,0 ; Poll for trigger

    goto poll_l ; No trigger, keep polling

  • 7/29/2019 Rocket Code

    6/11

    ;clrf sef_hi_addr ; Point to serial flash

    sector 0clrf sef_lo_addr

    ;;; Check Mode pin RB1, 0 = Mode A, 1 = Mode B

    btfsc PORTB,1goto 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_NUMBERmovwf sector_hi_countermovlw SECTOR_LO_NUMBERmovwf sector_lo_counter

    ;; Enable timer 0 interrupt

    movf con_holder,W ; Load time delay into timer 0

    movwf TMR0movlw B'10100000' ; Enable TMR0, and all ints

    movwf INTCON;; Point to top of RAM buffernxt_sct movlw BUFFER_SIZE

    movwf ad_countermovlw ram_buffer+BUFFER_SIZE-1movwf FSRclrf 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_SIZEmovwf ad_countermovlw ram_buffer+BUFFER_SIZE-1movwf FSR

    ;; Initialize serial flash to be programmed

    bcf PORTC,SS ; Select serial flash

    movlw PREN ; Transmit program enable instruction

    call spi_xfrbsf PORTC,SS ; Deselect serial flash

    ;; Transmit program inst. and sector address to serial flash

    bcf PORTC,SS ; Select serial flashmovlw PROGRAM ; Send PROGRAM instructioncall spi_xfrmovf sef_hi_addr,W ; Send serial flash sect

  • 7/29/2019 Rocket Code

    7/11

    or addresscall spi_xfrmovf sef_lo_addr,Wcall spi_xfr

    ;; Send data to serial flashtx_sef movf INDF,W ; Get raw A/D value fromRAM buffer

    call spi_xfrdecf FSR,F ; Move to next byte in b

    ufferdecfsz ad_counter,F ; Check for end of buffe

    rgoto tx_sef ; Not finished with buff

    er, get more databsf PORTC,SS ; Finished sending data

    deselect serial flash;; Increment serial flash sector start address

    movlw SECTOR_SIZEaddwf sef_lo_addr,Fbtfsc STATUS,Cincf sef_hi_addr,F

    ;

    ; Decrement sector counters, test to see if must terminatemovf sector_lo_counter,F ; Check if low byte = 0

    btfsc STATUS,Zgoto dec_msb ; It's 0, check

    hi bytedecf sector_lo_counter,F ; Not 0, decreme

    nt lo bytegoto nxt_sct ; Continue acqui

    sition;dec_msb movf sector_hi_counter,F ; Check if hi byte = 0

    btfsc STATUS,Zgoto termaq ; It's 0, terminate data acquisition

    decf sector_lo_counter,F ; Not 0,decrement both counters

    decf sector_hi_counter,Fgoto nxt_sct ; Contin

    ue acquisition;; Data acquisition terminated, disable interruptstermaq bcf INTCON,GIE;

    movlw din_term_mes ; Point

    to data acquired termination message.movwf FSRcall tx_mes ; Transmit data

    acquired termination message..;; Test to see if RB0 is high again.rbloop btfss PORTB,0

    goto rbloopbcf PORTB,7 ; Red LED OFF, exit mode

    A

  • 7/29/2019 Rocket Code

    8/11

    bsf PORTB,6 ; Green LED ONgoto poll_l ; 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 ModeB;; Intialize serial flash memory sector counters; In Mode B using sector counters to count total number of data bytes

    movlw DATA_BYTES_HI_NUMBERmovwf sector_hi_countermovlw DATA_BYTES_LO_NUMBERmovwf sector_lo_counter

    ;; Set-up serial flash to transmit data to PIC.

    bcf PORTC,SS ; Select serial flashmovlw READ ; Transmit READ instruct

    ioncall spi_xfrmovf sef_hi_addr,W ; Transmit sector addres

    s call spi_xfrmovf sef_lo_addr,Wcall spi_xfr

    ;; Read an A/D raw value from serial flash, transmit via SCIget_sef call spi_xfr ; Get a data byte from serial flash

    call asci_con ; Convert value to decimal ASCII

    movlw hundreds ; Point to A/D ASCII message

    movwf FSR

    call tx_mes ; Transmit A/D value;movlw '0' ; Clear hundreds, tens and onesmovwf hundredsmovwf tensmovwf ones

    ;; Decrement data counters, test to see if must terminate

    movf sector_lo_counter,F ; Check if low byte = 0

    btfsc STATUS,Zgoto dec_msb2 ; It's 0, check

    hi byte

    decf sector_lo_counter,F ; Not 0, decrement lo byte

    goto get_sef ; Continue reading serial flash;dec_msb2 movf sector_hi_counter,F ; Check if hi byte = 0

    btfsc STATUS,Zgoto end_sef ; It's 0, terminate read

    ing serial flashdecf sector_lo_counter,F ; Not 0, decreme

  • 7/29/2019 Rocket Code

    9/11

    nt both countersdecf sector_hi_counter,Fgoto get_sef ; Continue readi

    ng serial flash;end_sef bsf PORTC,SS ; Deselect serial flash;

    movlw dout_term_mes ; Point to dataoutput termination message

    movwf FSRcall tx_mes ; Transmit data

    output termination message;; Test to see if RB0 is high againrbloop2 btfss PORTB,0

    goto rbloop2bcf PORTB,7 ; Red LED OFF, exit Mode Bbsf PORTB,6 ; Green LED ONgoto 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 Timer0

    movwf TMR0;

    bsf ADCON0,GO_DONE ; Start A/D conversionpol_ad btfsc ADCON0,GO_DONE ; Test if A/D conversion

    finished goto pol_ad ; Not done, pollA/D

    movf ADRES,W ; Save A/D valuein buffer

    movwf INDF;

    movlw B'00100000' ; Debug, toggleRB5 on A/D conversion

    xorwf PORTB,F;

    decf FSR,F ; Move to next byte in RAM buffer

    decfsz ad_counter,F ; Check for end of buffer

    goto go_ret ; Buffer not fullbsf buf_full_flag,0 ; Buffer full, s

    et bit 0 of buf_full_flaggo_ret bcf INTCON,T0IF ; Clear Timer 0 flag

    retfie;;; spi_xfr, Routine to send/receive bytes via SPI

  • 7/29/2019 Rocket Code

    10/11

    ; Enter with byte to send in W; Exit with received byte in Wspi_xfr

    movwf SSPBUF ; Send bytes_loop bsf STATUS,RP0 ; Bank 1

    btfss SSPSTAT,BF ; Data received/xmit complete?

    goto s_loop ; No, go pollbcf STATUS,RP0 ; Bank 0

    ;movlw B'00010000' ; Debug, toggle RB4, co

    mpleted SPIxorwf PORTB,F

    ;movf SSPBUF,W ; Received byte -> Wreturn

    ;;; 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 1x_poll btfss TXSTA,TRMT ; Finished transmitting

    previous byte? goto x_poll ; No, go pollbcf STATUS,RP0 ; Bank 0

    ;btfsc INDF,7 ; Test for termi

    nation charactergoto endmes ; Termination ch

    ar, message over;

    movf INDF,W ; Get charmovwf TXREG ; Send char

    ;movlw B'00001000' ; Debug, toggle

    RB3 on transmitted bytexorwf PORTB,F;

    incf FSR,F ; Point to nextchar

    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 hundredsgo_huns subwf raw_holder,F

    btfss STATUS,Cgoto cont_10 ; Finished converting 10

    0'sincf hundreds,Fgoto go_huns

  • 7/29/2019 Rocket Code

    11/11

    ;cont_10 addwf raw_holder,F ; Convert tens

    movlw D'10'go_tens subwf raw_holder,F

    btfss STATUS,Cgoto cont_1 ; Finished converting 10'sincf tens,Fgoto go_tens

    ;cont_1 addwf raw_holder,W ; Ones done

    addwf ones,F;

    return;;

    endROCKET1.ASM 06/25/98 3