* File - ds1620.asm ********************************************************* * ubc physics 319 - temperature sensor ic * ds1620 8-pin minidip * fall, 1997 * physics ubc 319 * sc * * an assembler program to introduce dallas ds1620: * use portc to communicate with ds1620 * PC0 <-> DQ * PC1 -> CLK/CONV * PC2 -> /RST * from ds1620 spec * the signed 9-bit with resolution is .5 * range -55°C to 125°C. * subroutines geti and disp9bits deal with that manner * ie for 1.5 one should enter 3 * for -1.5 one should enter 509, 512-(1.5*2)=509 * enter 255 -> 127.5, enter 511 -> -.5 ********************************************************** rbase equ $1000 nvalue equ 200 eeprom equ $f800 stack equ $00ff opts equ %10010000 ;a/d on option equ rbase+$39 ;system options admask1 equ %00110000 ;(adctl) continuous conversion, ad0 to 3 adctl equ rbase+$30 ;a/d control register adr1 equ $1031 ad1 rtimsk equ %00001000 ;(pactl) 4.1 msec interrupt with 8 mhz xtal pactl equ rbase+$26 ;rti prescaler, pulse accum. ptdmsk equ %00000010 ;(ddrd) port d data direction:input except txd ddrd equ rbase+$09 ;data direction register, portd bdmsk24 equ %00110010 ;(baud) 2400 baud with 8 mhz crystal baud equ rbase+$2b ;sci baud rate control sc2msk2 equ %00101100 ;(sccr2) enable tx and rx and rx interrupt sccr2 equ rbase+$2d ;sci control register 2 scsr2 equ $102e ;sci status re scdr equ rbase+$2f ;sci data, read (rdr) and write (tdr) tflg1 equ $23 ;name the timer flag 1 tflg2 equ $25 ;name the timer flag 2 tmsk1 equ $22 ;name the timer mask 1 tmsk2 equ $24 portc equ $03 ddrc equ $07 ************************* * operational constants * ************************* TRUE equ $ff cr equ $d ;carriage return lf equ $a ;left readtemperature equ $aa ds1620 protocol readcounter equ $a0 readslope equ $a9 loadslope equ $41 startconvert equ $ee stopconvert equ $22 writeTH equ $01 writeTL equ $02 readTH equ $a1 readTL equ $a2 writeconfig equ $0c readconfig equ $ac ******************** * system variables * ******************** org 0 COMMAND_PENDING rmb 1 *continuous rmb 1 COMMAND rmb 1 T rmb 1 read temperature ds1620 T1 rmb 1 counter rmb 2 read counter ds1620, count_remain slope rmb 2 read slope ds1620, count_per_C th rmb 2 TH register ds1620 tl rmb 2 TL register ds1620 config rmb 1 config register ds1620 frac rmb 1 fraction frac1 rmb 1 w rmb 1 w1 rmb 1 period rmb 2 sample rate 1/(period/30) temp rmb 2 base rmb nvalue ;used for the bottom of the 200 values ******************************************************** * main part of the program. * ******************************************************** org eeprom main: sei ;this is where the reset vector points ldaa #opts ;define system options staa option lds #stack ;initialize the stack pointer ldaa #admask1 ;set a/d to scan ad0 through ad3 cont. staa adctl ldaa #rtimsk ;initialize rti rate staa pactl ldaa #ptdmsk ;initialize portd staa ddrd ldaa #bdmsk24 ;baud=2400 staa baud ldaa #sc2msk2 staa sccr2 ;enable sci receiver and xmtr and rx int. ldaa scdr ;dummy read to flush receive buffer ldd #3 30 for a second std period clr COMMAND_PENDING * clr continuous cli ;enable interrupts jsr showmenu begin: jsr processcommand ;this is the program loop jmp begin ****************************************************** * subroutines to process the user command ******************************************************* processcommand: ldaa COMMAND_PENDING ;commands received via sci interrupt cmpa #TRUE beq process rts process: clr COMMAND_PENDING * clr continuous jsr putnewline ldaa COMMAND cmpa #'r read 100 data points beq pcr cmpa #'R beq pcr cmpa #'d display stored data beq pcd cmpa #'D display ds1620 stuff beq ds1620 cmpa #'p beq purge purge data seqment cmpa #'s reset sampling rate beq srate cmpa #'S beq srate cmpa #'H set TH beq sth cmpa #'h beq sth cmpa #'L set TL beq stl cmpa #'l beq stl cmpa #'c set config beq sc cmpa #'C beq sc jsr showmenu rts ******************************************************** * subroutine to record the data ******************************************************** pcr: ldy #0 again: pshy * save the loop counter ldaa #$2e * show a dot for a read jsr sendbyte jsr delay jsr rdT ldd temp puly * restore the loop counter std base,y iny iny cpy #nvalue blo again rts sth: jsr setth rts stl: jsr settl rts sc: jsr setconfig rts ******************************************************* * subroutine to download the data * ********************************************************* pcd: ldy #0 repeat ldd base,y jsr disp9bits jsr putnewline iny iny cpy #nvalue blo repeat rts ds1620: jsr allds1620 rts purge: ldy #nvalue ploop: clr base,y ldaa #'0 jsr sendbyte dey bne ploop rts srate: jsr dispsr ldx #wassr jsr sendstring jsr putnewline ldx #sratest jsr sendstring jsr geti ldd temp std period jsr dispsr ldx #issr jsr sendstring jsr putnewline srrts: rts geti: sei var par in temp ldd #0 std temp ldx #rbase rdrf: brclr $2e,x $20 rdrf ldab scsr2 ldab scdr cmpb #13 the enter key beq srdone cmpb #$30 the zero key blo rdrf cmpb #$39 the nine key bhi rdrf pshb save the numeral key ldd temp lsld times 10 lsld lsld addd temp addd temp std temp pulb retrieve the numeral key subb #$30 convert to numeral clra addd temp std temp bra rdrf srdone: jsr putnewline cli rts dispsr: ldd period display sampling period dispn: ldx #10 display n in d idiv pshb xgdx cpd #0 beq pulb jsr dispn recursive pulb: pulb addb #$30 tba jsr sendbyte rts setth: ldd th jsr disp9bits ldx #THstr jsr sendstring ldx #enterstr jsr sendstring jsr geti ldd temp std th ldab #writeTH ldy #8 jsr outbits ldd th ldy #9 jsr outbits ldx #rbase bclr portc,x #%00000111 terminate ds1620 communication rts settl: ldd tl jsr disp9bits ldx #TLstr jsr sendstring ldx #enterstr jsr sendstring jsr geti ldd temp std tl ldab #writeTL ldy #8 jsr outbits ldd tl ldy #9 jsr outbits ldx #rbase bclr portc,x #%00000111 terminate ds1620 communication rts setconfig: clra ldab config jsr dispn ldx #cfstr jsr sendstring ldx #enterstr jsr sendstring jsr geti ldd temp stab config ldaa #writeconfig jsr wds1620 ldx #rbase bclr portc,x #%00000111 terminate ds1620 communication rts rdT: ldab #readconfig read config protocol jsr rds1620 stab config save the config setting ldaa #writeconfig write config protocol ldab #$03 one shot and cpu mode jsr wds1620 ldab #startconvert start convert command jsr cds1620 dordT ldab #readconfig jsr rds1620 lslb bcc dordT while done bit=0 ldab #readtemperature jsr rds1620 read temperature std temp ldaa #writeconfig restore config setting ldab config jsr wds1620 rts allds1620: ldab #readconfig read config protocol jsr rds1620 stab config save the config setting ldaa #writeconfig write config protocol ldab #$03 one shot and cpu mode jsr wds1620 ldab #startconvert start convert command jsr cds1620 do ldab #readconfig jsr rds1620 lslb bcc do while done bit=0 ldab #readtemperature jsr rds1620 read temperature bita #%00000001 bne negative clra bra storeT negative: ldaa #$ff storeT: std T ldab #readcounter jsr rds1620 read counter count_remain std counter jsr dispn ldx #crstr jsr sendstring jsr putnewline ldab #loadslope jsr cds1620 command ds1620 count_per_C to counter ldab #readcounter jsr rds1620 read slope std slope jsr dispn ldx #cpcstr jsr sendstring jsr putnewline jsr calT jsr rdtl jsr rdth ldaa #writeconfig restore config setting ldab config jsr wds1620 jsr rdconfig rts rdconfig: ldab #readconfig jsr rds1620 clra jsr dispn ldx #cfstr jsr sendstring jsr putnewline rts rdtl: ldab #readTL jsr rds1620 std tl jsr disp9bits ldx #TLstr jsr sendstring jsr putnewline rts rdth: ldab #readTH jsr rds1620 std th jsr disp9bits ldx #THstr jsr sendstring jsr putnewline rts disp9bits: lsra val par in D bcc pos comb incb pshb ldaa #45 the negative sign jsr sendbyte pulb pos: pshb lsrb clra jsr dispn pulb lsrb bcc even ldaa #$2e the dot jsr sendbyte ldaa #53 the 5 character jsr sendbyte even: ldaa #$f8 the degree sign jsr sendbyte ldaa #'C jsr sendbyte rts calT: * to calculate the read temperature to 100th * temperature=temp_read-1+.75+(count_per_c-count_remain)/count_per_c ldd T jsr dispn ldaa #240 the approx sign jsr sendbyte ldd T bpl positive comb 2's complement arithmatics incb ldaa #45 the negative sign jsr sendbyte positive: clra std T ldd slope beq nofrac subd counter ldx slope fdiv xgdx std w ldd #5000 std frac ldd #0 f: lsl w1 rol w bcc lsr addd frac lsr: lsr frac ror frac1 tst w bne f addd #7500 std frac cpd #10000 bls noinc subd #10000 std frac inc T1 noinc: dec T1 ldd T lsrb jsr dispn ldaa #$2E the decimal dot jsr sendbyte ldd frac ldx #1000 idiv xgdx tba adda #'0 jsr sendbyte xgdx ldx #100 idiv xgdx tba adda #'0 jsr sendbyte xgdx ldx #10 idiv xgdx tba adda #'0 jsr sendbyte nofrac: ldaa #$f1 the +/- sign jsr sendbyte ldaa #$2e jsr sendbyte ldaa #'0 jsr sendbyte ldaa #'1 jsr sendbyte ldaa #$f8 jsr sendbyte ldaa #'C jsr sendbyte jsr putnewline rts rds1620: * read ds1620, protocol in b, and return read data in d. * PC0 <-> DQ * PC1 -> CLK/CONV * PC2 -> /RST ldx #rbase ldy #$08 jsr outbits ldab ddrc,x setup portc to read orab #%00000111 andb #%00000110 PC0 for input DQ stab ddrc,x ldy #$09 bra clkR getDQ: lsrd shift in data, lsb first clkR: bclr portc,x #%00000010 nop ldaa portc,x bset portc,x #%00000010 dey cmpy #0 bne getDQ bclr portc,x #%00000111 terminate ds1620 communication anda #$01 rts wds1620: * write ds1620, protocol in a, and write data in b. * PC0 <-> DQ * PC1 -> CLK/CONV * PC2 -> /RST pshb tab ldx #rbase ldy #$08 save the write data jsr outbits write protocol pulb retrieve write data ldy #$08 jsr outbits write data bclr portc,x #%00000111 terminate ds1620 communication rts cds1620: * command ds1620, protocol in b. * PC0 <-> DQ * PC1 -> CLK/CONV * PC2 -> /RST ldx #rbase ldy #$08 jsr outbits write protocol bclr portc,x #%00000111 terminate ds1620 communication rts outbits: * shift n bits out from D, lsb first. n in y * PC0 <-> DQ * PC1 -> CLK/CONV * PC2 -> /RST ldx #rbase pshb ldab ddrc,x setup portc to write byte orab #%00000111 stab ddrc,x bset portc,x #%00000111 RST line must be hi pulb ob: bclr portc,x #%00000001 lsra rorb shift out bit, lsb first bcc clkW bset portc,x #%00000001 clkW: bclr portc,x #%00000010 nop bset portc,x #%00000010 dey bne ob rts ********************************************************** * this is the delay program, from where one can * set the period between recordings. ********************************************************** delay: ldy period beq nodelay ldx #rbase bclr tflg1,x %01111111 bb brclr tflg2,x %10000000 bb bclr tflg2,x %01111111 dey bne bb nodelay: rts ************************************************************** * this subroutine transmits a byte, contained in register a * to the serial device via the sci ************************************************************** sendbyte: sb1 ldab scsr2 ;wait for transmit data register empty (tdre) bpl sb1 staa scdr ;send byte rts *************************************************************** * the following programs are all related to the operation of * the menu. they are lines, double lines, messages, and * such. *************************************************************** putnewline: ldaa #cr jsr sendbyte ldaa #lf jsr sendbyte rts putdblline: ldaa #cr jsr sendbyte ldaa #lf jsr sendbyte ldaa #lf jsr sendbyte rts sendstring: rv1: ldaa 0,x ;$ff denotes end of string cmpa #$ff beq rvx jsr sendbyte inx bra rv1 rvx: rts *************** * menu * * subroutine * *************** showmenu: jsr putnewline ldx #m_undln jsr sendstring jsr putdblline ldx #m_header1 jsr sendstring jsr putnewline ldx #m_header2 jsr sendstring jsr putnewline ldx #m_undln jsr sendstring jsr putnewline ldx #m_line1 jsr sendstring jsr putnewline ldx #m_line2 jsr sendstring jsr putnewline ldx #m_line3 jsr sendstring jsr putnewline ldx #m_line4 jsr sendstring jsr putdblline ldx #m_line5 jsr sendstring jsr putnewline ldx #m_line6 jsr sendstring jsr putnewline ldx #m_line8 jsr sendstring jsr putnewline ldx #m_line7 jsr sendstring jsr putdblline ldx #m_prompt jsr sendstring rts ************** ** messages ** ************** m_line1 fcc 'd => download temperature data' fcb $ff m_line2 fcc 'r => read temperature' fcb $ff m_line3 fcc 's => set sampling period' fcb $ff m_line4 fcc 'p => purge data segment' fcb $ff m_line5 fcc 'h => set high temperature trigger' fcb $ff m_line6 fcc 'l => set low temperature trigger' fcb $ff m_line7 fcc 'D => display ds1620' fcb $ff m_line8 fcc 'c => set config register' fcb $ff m_prompt fcc '?' fcb $ff m_header1 fcc 'ubc physics 319 - ds1620 applet' fcb $ff m_header2 fcc ' fall 1997, sc' fcb $ff m_undln fcc '___________________________________' fcb $ff sratest fcc 'set sampling period > ' fcb $ff wassr fcc '*32.77ms sampling period was set.' fcb $ff issr fcc '*32.77ms sampling period is set.' fcb $ff crstr fcc ' count_remain' fcb $ff cpcstr fcc ' count_per_C' fcb $ff THstr fcc ' TH' fcb $ff TLstr fcc ' TL' fcb $ff cfstr fcc ' config register' fcb $ff enterstr fcc '. enter a new integer> ' fcb $ff ************************************************************************* * Gets bytes from SCI. Sets COMMAND_PENDING flag. SerInputInt: ldaa scsr2 ldaa scdr staa COMMAND ldaa #TRUE staa COMMAND_PENDING SIIX: rti ***************************************************************** org $FFD6 * Interrupt and reset vectors. SCI_VECT FDB SerInputInt SPI_VECT FDB main PAI_VECT FDB main PAO_VECT FDB main TOF_VECT FDB main TOC5_VECT FDB main TOC4_VECT FDB main TOC3_VECT FDB main TOC2_VECT FDB main TOC1_VECT FDB main TIC3_VECT FDB main TIC2_VECT FDB main TIC1_VECT FDB main RTI_VECT FDB main IRQ_VECT FDB main XIRQ_VECT FDB main SWI_VECT FDB main TRAP_VECT FDB main COP_FAIL_VECT FDB main COP_CMF_VECT FDB main RESET_VECT FDB main