; ; stripped down from standalong data logger ; ; reads temp and scratch. ; ; SL004ds1820.ASM - hack to play with ds1820 ; also has hack to read erase and write Program memory on PIC16F88 ; cutdown from SL002.asm ; ; on each tick read: ; LTC1285 ; PA2 - AtoD ; PA3 - AtoD ; PA4 - AtoD ; ; FOR PIC 16F88 18 PIN DEVICE - with internal AtoD converters. ; based on code for 16F84 ; ; FOR PIC 16F84 18 PIN DEVICE ; FOR PIC 16F88 18 PIN DEVICE - with internal AtoD converters. ; ; code needs to be recompiled for 24LC16 IIC memory chip ; code needs to be recompiled for 24LC65 IIC memory chip ; ; Logger starts on reset at interval set by p02 command; ; set p0080; to set memory to 24LC256 ; set p00E0; to set memory to 24LC65 ; ; ; Doug Rice 24/08/2008,29/09/2008 ; ; Output at 4800 baud with added stop bits. ; ; It took 3 monutes 30 seconds to upload 32K 24LC256 chip using the HEX format. ; ; TX D9 Pin 3 -[4k7]----+----- PB0 - check which pin is used. see EQU for each chip. ; RX D9 Pin 2 ----------/ ; ; GND D9 Pin 5 ---------------- 0V ; ; NOTE: it has been found that PA0 this affects the AtoD readings as PA0 is kept at -0.6 volts when the TX is not transmitting. ; If PA0 is pulled low, the AtoD reading is affected by the series resistance in series with the AtoD pin, by 14 per kOhm. ; If the TX line is disconnected the AtoD convert become high impedence. ; ; ; commands: ; r - rAA read AA ; w - wAADD write DD to AA ; g - gAA get fromm EEPROM address A ; p - p AADD put DD to EEPROM ; ; c - read ds18s20 ROM id ; d - reads scratch pad ds18s20 ; t - triggers read and read of scratch pad from ds18s20 ; ; ; EEPROM for program ; a - aAAAA;setaddr ; e - e; erase32 words at address AAAA 32 byte page. ; < - <; read word and increment ; > - >DDDD; write word and increment, needs to write 4 bytes at once. ; ; this seems to work. ; ; ; ;-------------------------------------------------------------------------- ; Sec 0. #Defines tofor different chips ;-------------------------------------------------------------------------- ; uncomment only one of these ; #define pic16F84 1 ;#define pic16F819 1 #define pic16F88 1 ; Configure for different size EEPROM ;MEM24LC16 EQU 1 ;MEM24LC65 EQU 1 MEM24LC256 EQU 1 debug equ 1 ;-------------------------------------------------------------------------- ; Sec 0. #Defines to select code ;-------------------------------------------------------------------------- ;-------------------------------------------------------------------------- ; Sec 0.1 #Defines for 16F88 ;-------------------------------------------------------------------------- ifdef pic16F88 LIST P=16F88, R=DEC INCLUDE "p16F88.inc" __idlocs 0x0088 ; __CONFIG _CONFIG1, _XT_OSC & _PWRTE_ON & _WDT_OFF ; __CONFIG _CONFIG2, _IESO_ON & _FCMEN_ON ; __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _INTRC_IO __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF ;#define wantAtoD 1 ;#define wantDataUpload 1 cblock 0x20 endc T0IF EQU TMR0IF ;PORTA ;PORT_RS232 EQU PORTA ;TRIS_RS232 EQU TRISA ; ; Move the rs232 port to PORTB RB0 as PA0 interferes with the AtoD converter. ; When Tx is low, it pulled the PA0 to -0.63 V. This makes the AtoD sensitive to series resistance. ; PORT_RS232 EQU PORTB TRIS_RS232 EQU TRISB RS232tx EQU 0 ; Serial Out RS232rx EQU 0 ; Serial In needs to be equal to BUTTON_RS232 PORTLED EQU PORTB PORTEEPROM EQU PORTB TRISEEPROM EQU TRISB DSport equ PORTA DStris equ TRISA DSbit equ 2 DSbit2 equ 3 ;PORTB ;PB0 EQU 0 ; Pull LEDoutput EQU 2 ; LED Output EEPROMscl EQU 3 ; eeprom scl EEPROMsda EQU 4 ; eeprom sda ADdout EQU 5 ; A/D Dout ADclk EQU 6 ; A/D clk AD_cs EQU 7 ; A/D -cs endif ;-------------------------------------------------------------------------- ; Sec 0.2 Constants ;-------------------------------------------------------------------------- ; *********** I/O EQUATES ************** ;PORTA EQU 5 ; 5 BITS ;PA0 EQU 0 ;PA1 EQU 1 ; ;PA2 EQU 2 ; AtoD on PIC16F88 ;PA3 EQU 3 ; AtoD on PIC16F88 ;PA4 EQU 4 ; AtoD on PIC16F88 ;PORTB EQU 6 ;PB0 EQU 0 ; Serial Out, Serial In ;PB1 EQU 1 ;PB2 EQU 2 ; LED Output - Flashes during error ;PB3 EQU 3 ; eeprom scl ;PB4 EQU 4 ; eeprom sda ;PB5 EQU 5 ; A/D Dout ;PB6 EQU 6 ; A/D clk ;PB7 EQU 7 ; A/D -cs ;-------------------------------------------------------------------------- ; Sec 0.2 PIC's EEPROM constants ;-------------------------------------------------------------------------- EE_MAX_WRTH EQU 0 EE_SAMPLERATEH EQU 1 EE_SAMPLERATEL EQU 2 ;-------------------------------------------------------------------------- ; Sec 1.1 Button and LED ;-------------------------------------------------------------------------- BUTTON_RS232 EQU RS232rx BUTTON_DOWN EQU 0 ; PORTB ; DoTimeSlice bits ; these bits are set to schedule a timer chain event DTsS4event EQU 0 ; RUN_BUFF EQU 0 ; ; IPtrigMenu DTSFast EQU 0 ; ************ MEMORY EQUATES **************** ; cblock 0x20 cblock LoopCnt w_temp status_temp LoopCnt2 TXCHARTMP DELL DELH DoTimeSlice ; if bit 7 set then do not do samples CLcntH CLcnt IPnew IPlast IPbuttonEvent IPnewFast IPlastFast IPbuttonEventUp IPtrigMenu ; ********************************************** ; variables used by Serial input and output routines RStxTemp RSloopCnt RSdelayCnt RSin ;RSout RSinterCharDelay RSafterCRCharDelay ; Serial input buffer RSipBuffCnt ; input buffer counter ; start of buffer RScmd RSAa ; RSaA ; RSDd ; RSdD ; RSterminator ; end of buffer ; temporary variables RSaddr RSdata RSeeaddrh RSeeaddrl ; ; Dallas DS18S20 variables ; DSmask ; one bit set to select bit in port DSbitCount DSdelayCnt DSbyte ; ; Dallas DS18S20 variables for binary to decimal conversion ; DStempMsb DStempLsb DStempRemain ; variables to convert binary to decimal DSbin ; binary number to be converted to BCD DShundreds ; BCD hundreds result DStens_and_ones ; BCD tens and ones result endc cblock 0xA0 DSmaskH ; one bit set to select bit in port endc ORG 0x00 goto Start ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register bcf INTCON,RBIF ; isr code can go here or be located as a call subroutine elsewhere retfie ; return from interrupt ; ;-------------------------------------------------------------------------- ; Sec 4.2 Main Program Init Code ;-------------------------------------------------------------------------- Start movlw ( 1 << DSbit ) ; 00001000 movwf DSmask ; movlw ~( 1 << DSbit ) ; 11110111 ; movwf DSmask_ banksel PORTA ; ; Set up ports ; ;movlw 1 << DSbit ; movfw DSmask movwf PORTA ; ; IIC is a wired or bus, so only toggle TRIS bits ; movlw 1< movlw EE_MAX_WRTH call EEread call RSwrtWasHex call RS232sendSpace movlw 'E' call RStxChar movlw 'N' call RStxChar movlw 'D' call RStxChar call RS232sendCR call RS232sendLF ; flash LED on Restart bsf PORTLED,LEDoutput call DelayA bcf PORTLED,LEDoutput goto $+1 movlw ( 1 << DSbit ) ; 00001000 movwf DSmask call DSreadRom movlw ( 1 << DSbit2 ) ; 00001000 movwf DSmask call DSreadRom call DSreadScratch call DSreadTemp call DSreadTemp call DSreadScratch goto MainLoop ;-------------------------------------------------------------------------- ; Sec 4.3 Main Program ;-------------------------------------------------------------------------- MainLoop nop movfw DoTimeSlice movfw IPbuttonEventUp movwf IPbuttonEventUp call CLtimeslice call IPtimesliceFast ; test for rising edge btfsc IPbuttonEventUp,BUTTON_RS232 ; RS232 input start call IPrs232 movF DoTimeSlice,w Bz MainLoop btfsc DoTimeSlice,RUN_BUFF call DLrunBuff goto MainLoop MAIN return ;-------------------------------------------------------------------------- ; Sec 5. Subroutines, procedures and functions ;-------------------------------------------------------------------------- ;-------------------------------------------------------------------------- ; Sec 5.1 Dallas DS18S20 temperature chip routines - http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2815 ;-------------------------------------------------------------------------- DSreadRom ; Rx Presence DS18S20 responds with presence pulse. ; Tx CCh Master issues Skip ROM command. ; Tx BEh Master issues Read Scratchpad command. ; Rx 9 data bytes call DSinit movlw 0x33 ; read |ROM call DSwriteByte call DSreadByte call RSwrtWasHex call DSreadByte call RSwrtWasHex movlw '-' call RStxChar call DSreadByte call RSwrtWasHex call DSreadByte call RSwrtWasHex movlw '-' call RStxChar call DSreadByte call RSwrtWasHex call DSreadByte call RSwrtWasHex movlw '-' call RStxChar call DSreadByte call RSwrtWasHex call DSreadByte call RSwrtWasHex movlw '-' call RStxChar return DSreadPowerSupply ; Rx Presence DS18S20 responds with presence pulse. ; Tx CCh Master issues Skip ROM command. ; Tx BEh Master issues Read Scratchpad command. ; Rx 9 data bytes call DSinit movlw 0xCC ; skip |ROM call DSwriteByte movlw 0xB4 ; read Powersupply call DSwriteByte DSreadTemp ; Rx Presence DS18S20 responds with presence pulse. ; Tx CCh Master issues Skip ROM command. ; Tx BEh Master issues Read Scratchpad command. ; Rx 9 data bytes call DSinit movlw 0xCC ; skip |ROM call DSwriteByte movlw 0x44 ; Convert Temp call DSwriteByte ; the DS18S20 thakes up to 0.75 seconds to measure the temperature. call DSinit movlw 0xCC ; skip |ROM call DSwriteByte movlw 0xBE ; read Scratchpad call DSwriteByte call DSdelay60us ; ; read out table so we can get to the remainder. ; call DSreadByte ; Temperature LSB movwf DStempLsb call DSreadByte ; Temperature MSB movwf DStempMsb ; TH reg call DSreadByte ; TH reg call DSreadByte ; TL reg call DSreadByte ; Reserved call DSreadByte ; Reserved call DSreadByte ; count remain movwf DStempRemain call DSreadByte ; count per C ; ; convert temp to decimal ; call DSdisplayAsDecimal movlw 0x0D call RStxChar movlw 0x0A call RStxChar return DSreadScratch call DSinit movlw 0xCC call DSwriteByte movlw 0xBE call DSwriteByte call DSdelay60us call DSreadByte movwf DStempLsb call RSwrtWasHex call DSreadByte movwf DStempMsb call RSwrtWasHex movlw '-' call RStxChar call DSreadByte call RSwrtWasHex call DSreadByte call RSwrtWasHex movlw '-' call RStxChar call DSreadByte call RSwrtWasHex call DSreadByte call RSwrtWasHex movlw '-' call RStxChar call DSreadByte call RSwrtWasHex call DSreadByte call RSwrtWasHex movlw '-' call RStxChar call DSreadByte call RSwrtWasHex call DSreadByte call RSwrtWasHex movlw '-' call RStxChar ; ; convert temp to decimal ; call DSdisplayAsDecimal movlw 0x0D call RStxChar movlw 0x0A call RStxChar return ; assert 0 DSassert0 comf DSmask,w andwf DSport,f ; banksel DStris ; bcf DStris, DSbit comf DSmask,w banksel DStris andwf DStris,f banksel DSport ; bcf DSport, DSbit comf DSmask,w andwf DSport,f return ; assert 1 DSrelease ; banksel DStris ; bsf DStris, DSbit movfw DSmask banksel DStris iorwf DStris,f banksel DSport ; bsf DSport, DSbit movfw DSmask iorwf DSport,f return ifdef DSold ; assert 0 DSassert0 movwf DSport andlw ~ ( 1 << DSbit ) movfw DSport banksel DStris bcf DStris, DSbit banksel DSport bcf DSport, DSbit return ; assert 1 DSrelease banksel DStris bsf DStris, DSbit banksel DSport bsf DSport, DSbit return endif DSinit ; M ---______------------- ; S --+--------+-___------ ; B ---______----___------ call DSrelease call DSdelay500us call DSdelayShort call DSassert0 call DSdelay500us call DSrelease ; ; The slave will assert 0 but I do not need to test this for this hack ; Assume it happens and check it on the scope ; call DSdelay500us return DSreadByte ; M ---__------------- ; S --+----+---------- ; B ---__------------- movlw 8 movwf DSbitCount movfw DSmask banksel DSmaskH movwf DSmaskH ; ; This takes too long with all the banksels ; DSmask needs to be in page 0 and page 1 ; DSreadByteLoop ; banksel DStris ; bcf DStris, DSbit banksel DSmaskH comf DSmaskH,w ; banksel DStris andwf DStris,f ; banksel DSport ; bcf DSport, DSbit banksel DSmask comf DSmask,w ; banksel DSport andwf DSport,f ; banksel DStris ; bsf DStris, DSbit banksel DSmaskH movf DSmaskH,w ; banksel DStris iorwf DStris,f banksel DSport movfw DSport ; andlw 1 << DSbit andwf DSmask,w addlw 0xFF ; if bit is 0, there will be no carry ; if DSbit is 1 then adding -1 causes a carry into C rrf DSbyte , f call DSdelay60us decfsz DSbitCount goto DSreadByteLoop call DSdelay60us movfw DSbyte return DSwriteByte ;write0 ; M ---_______---- ; S --+----+---------- ; B ---_______---- ;write1 ; M ---__------------- ; S --+----+---------- ; B ---__------------- movwf DSbyte movlw 8 movwf DSbitCount call DSrelease DSwriteByteLoop call DSdelayShort call DSassert0 call DSdelay10us rrf DSbyte,f skpnc call DSrelease call DSdelay40us call DSrelease decfsz DSbitCount goto DSwriteByteLoop return ; delays ; cycles = 5 + w*3 ; = 7 + 3*w ; delays padded with nops DSdelay500us movlw .164 nop goto DSdelay DSdelay60us movlw .17 goto $+1 goto DSdelay DSdelay40us movlw .11 goto DSdelay DSdelay10us movlw 1 goto DSdelay DSdelayShort nop return DSdelay ; 3 + 3*W movwf DSdelayCnt DSdelay1 decfsz DSdelayCnt goto DSdelay1 return ; DS18S20 OPERATION EXAMPLE 2 ; In this example there is only one DS18S20 on the bus and it is using parasite power. The master writes to ; the TH and TL registers in the DS18S20 scratchpad and then reads the scratchpad and recalculates the ; CRC to verify the data. The master then copies the scratchpad contents to EEPROM. ; MASTER MODE DATA (LSB FIRST) COMMENTS ; Tx Reset Master issues reset pulse. ; Rx Presence DS18S20 responds with presence pulse. ; Tx CCh Master issues Skip ROM command. ; Tx 4Eh Master issues Write Scratchpad command. ; Tx 2 data bytes Master sends two data bytes to scratchpad (TH and TL) ; Tx Reset Master issues reset pulse. ; Rx Presence DS18S20 responds with presence pulse. ; Tx CCh Master issues Skip ROM command. ; Tx BEh Master issues Read Scratchpad command. ; Rx 9 data bytes ; Master reads entire scratchpad including CRC. The master ;then recalculates the CRC of the first eight data bytes from ;the scratchpad and compares the calculated CRC with the ;read CRC (byte 9). If they match, the master continues; if not, ;the read operation is repeated. ;Tx Reset Master issues reset pulse. ;Rx Presence DS18S20 responds with presence pulse. ;Tx CCh Master issues Skip ROM command. ;Tx 48h Master issues Copy Scratchpad command. ;Tx DQ line held high by ;strong pullup ;Master applies strong pullup to DQ for at least 10ms while ;copy operation is in progress. ;-------------------------------------------------------------------------- ; Sec 5.1 Dallas DS18S20 binary to decimal routines ;-------------------------------------------------------------------------- DSdisplayAsDecimal movlw ' ' call RStxChar rrf DStempMsb, f btfsc STATUS, C goto DSdispnega bcf STATUS, C rrf DStempLsb, f movlw "+" goto DSshowDecimal DSdispnega ; ; this is complicated between 0 and -1 ; ; ; 0 1 1 ; 0 0 0 + remainer ;ff ff -0.5 + remainer ;ff fe -1 + remainer ; ; I have seen remainder = 0x10 but not 0 ; COUNT_PER_C = 0x10 ; formulae is COUNT_PER_C - COUNT_REMAIN bsf STATUS, C rrf DStempLsb,f comf DStempLsb,f btfsc DStempRemain,4 incf DStempLsb,f ; try and subtract from W movfw DStempRemain sublw 0x10 movwf DStempRemain movlw "-" goto DSshowDecimal DSshowDecimal call RStxChar movfw DStempLsb call DSdispDec ; display the value movlw "." call RStxChar ; now display remainer ; ; this needs to be sorted to work for negative ; movfw DStempRemain sublw 0x10 movwf DStempRemain movlw 0 btfsc DStempRemain,3 addlw 0x50 ; 0.50 btfsc DStempRemain,2 addlw 0x25 ; 0.25 btfsc DStempRemain,1 addlw 0x12 ; 0.12 5 btfsc DStempRemain,0 addlw 0x06 ; 0.06 25 ; we may need to do a decimal adjust. addlw 0x06 skpdc addlw -0x06 call RSwrtWasHex movlw " " call RStxChar movlw "C" call RStxChar return ;----------------------------------------------------------------------; ; Display binary value in W in decimal ; ; from http://www.piclist.com/techref/microchip/ds1820-code.htm ; ;----------------------------------------------------------------------; DSdispDec movwf DSbin call DSbinary_to_bcd movf DShundreds, W addlw '0' ; Send nbr as ASCII character call RStxChar swapf DStens_and_ones, W andlw H'F' addlw '0' ; Send nbr as ASCII character call RStxChar movf DStens_and_ones, W andlw H'F' addlw '0' ; Send nbr as ASCII character call RStxChar return ;----------------------------------------------------------------------; ; Change binary nbr in bin to BCD ; ;----------------------------------------------------------------------; DSbinary_to_bcd ; by Scott Dattalo clrf DShundreds ; ; add both nibbles together in W ; swapf DSbin, W addwf DSbin, W andlw B'00001111' ; ; ; skpndc addlw 0x16 skpndc addlw 0x06 addlw 0x06 skpdc addlw -0x06 ; bit 7 6 5 4 3 2 1 0 ; 128,64,32,16, 8,4,2,1 ; sum 240 + 15 = 255 btfsc DSbin,4 ; 16 addlw 0x16 - 1 + 0x6 skpdc addlw -0x06 btfsc DSbin,5 ; 32 addlw 0x30 btfsc DSbin, 6 ; 64 addlw 0x60 btfsc DSbin,7 ; 128 addlw 0x20 addlw 0x60 rlf DShundreds, f btfss DShundreds, 0 addlw -0x60 movwf DStens_and_ones btfsc DSbin,7 incf DShundreds, f return ;*************** ;************************************************** ; Delay 0x1d * 3 ticks of 4Mhz ~= 87us ; used to space bits for 9600 baud ; ; For 9600 baud, we need: ; ; 1 bit = 104.1666666667 us ; 1.5 bit= 156.25 us ; ; bit to bit = 103 cycles ; ; 1 bit delay = 206us ; ; For a clock rate of 4.014175Mhz for a bit delay of 1 bit = 104.1666666667 us ; 104.5358072248 cycles are needed. ; ; ; for Send Delay to delay = 16/17 cycles ( delay = 12 cycles = 6+3*movlw n) ; for Send Delay to delay = 16/17 cycles ( delay = 12 cycles = 6+3*movlw n) ; 104.5 ; -16.5 ; - 6 ; ====== ; 92 ; - 2 to make divisable by 3 ; ======= ; 90 ; / 3 ; ====== ; 30 or 0x1E Delay5 ; return nop nop movlw 0x1E DelayOne movwf DELL Delay51 decfsz DELL,f ; 1 goto Delay51 ; 2 clk clrwdt return ;*************** ; Delay 255 * 3 ticks of 4Mhz ~= 765us Delay7 movlw 0xFF goto DelayOne ;*************** ; Delay 255 * 3 ticks of 4Mhz ~= 5ms Delay7a movlw 0xFF movwf DELL Delay71a decfsz DELL,f return goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 clrwdt goto Delay71a ;*************** ; Delay 0x36 * 3 ticks of 4Mhz ~= 162us Delay9 movlw 0x36 goto DelayOne ;*************** ; Delay 255 * 255 * 3 ticks of 4Mhz ~= 0.195075 seconds DelayA movlw 0xFF movwf DELH DelayA2 movlw 0xFF movwf DELL clrwdt DelayA1 decfsz DELL,f goto DelayA1 decfsz DELH,f goto DelayA2 clrwdt return ;*************** ; Delay 255 * 255 * 3 ticks of 4Mhz ~= 0.195075 seconds Delay5ms movlw 0x08 movwf DELH DelayB2 movlw 0x4B movwf DELL clrwdt DelayB1 decfsz DELL,f goto DelayB1 decfsz DELH,f goto DelayB1 clrwdt return ;************************************************* ;-------------------------------------------------------------------------- ; Sec 5.1 Button Poll Routine ;-------------------------------------------------------------------------- IPtimeslice ; --_____ button press ; ----___ ; --_____ IPnew ; ____--- /IPlast ; __--___ ; ; This reads all Port A inputs and looks for Press movfw IPnew movwf IPlast movfw PORTB movwf IPnew ; IP last contains new setting, IPlast contains previous ; look for falling edges comf IPnew,W andwf IPlast,W ; now force IPbuttonEvent bits to high for new pressed button ; the service routine should reset the bit to clear the event. IORWF IPbuttonEvent,F return IPtimesliceFast ; Look for falling edges ; --_____ button press ; ----___ ; --_____ IPnew ; ____--- /IPlast ; __--___ ; movfw IPnewFast movwf IPlastFast movfw PORT_RS232 movwf IPnewFast comf IPlastFast,W andwf IPnewFast,W IORWF IPbuttonEventUp,F return ;-------------------------------------------------------------------------- ; Sec 5.2 ;-------------------------------------------------------------------------- ;-------------------------------------------------------------------------- ; Sec 5.2 .1 run process on request ;-------------------------------------------------------------------------- DLrunBuff bcf DoTimeSlice,RUN_BUFF movfw RSin call RSbuffInput return ;-------------------------------------------------------------------------- ; Sec 5.3 Button Input functions ;-------------------------------------------------------------------------- IPdownPressed bcf IPbuttonEvent,BUTTON_DOWN return IPrs232 bcf IPbuttonEventUp,BUTTON_RS232 goto RSrs232in ;-------------------------------------------------------------------------- ; Sec 5.4 Clock Chain Routine ;-------------------------------------------------------------------------- CLtimeslice ; banksel INTCON btfss INTCON,T0IF return movlw .54 ADDWF TMR0,f ; TMR0 timeout bcf INTCON,T0IF ;bsf DoTimeSlice,DTsS4event ; stop sampling when key pressed or memory full btfss DoTimeSlice,7 return ; This is called about every 50 ms decfsz CLcnt return ; read eeprom 0 movlw EE_SAMPLERATEL call EEread banksel CLcnt movwf CLcnt return CLdisableAutoSample ; disable time sample. reaneable by clearing bcf DoTimeSlice,7 return CLenableAutoSample bsf DoTimeSlice,7 return ;-------------------------------------------------------------------------- ; Sec 5.5 Serial Input Routine ;-------------------------------------------------------------------------- RSinit ; zero pointer banksel RSipbuffStart ; reset input buffer movlw RSipbuffStart movwf RSipBuffCnt clrf RSaddr clrf RSin return ;************************************************** ;RS232in RSrs232in ; Test is in main loop or uncomment code below to ; spin for a start bit ; clrwdt ; btfss PORT_RS232,RS232rx ; goto RSrs232in ; call RSdelayBit ; delay through Stop Bit call RSdelayHalfBit ; delay halfway into first bit movlw 8 movwf RSloopCnt RSrs232inL0 call RSdelayBit ; delay halfway into first bit movfw PORT_RS232 andlw 1<< RS232rx ; mask off bit addlw -1<< RS232rx ; use ripple carry to move into C rrf RSin,F ; call RSdelayBit decfsz RSloopCnt,f goto RSrs232inL0 ; do not test for Stop bit comf RSin,f bsf DoTimeSlice,RUN_BUFF call CLdisableAutoSample return ;-------------------------------------------------------------------------- ; Sec 5.6 Serial Output Routines ;-------------------------------------------------------------------------- ;************************************************* ; This routine transmits out the DDATA on the RS232 port ; RSwrtWasHex ; ; Write W reg as HEX to RS232 ; banksel TXCHARTMP movwf TXCHARTMP SWAPF TXCHARTMP,W call RSwrtHexNibble movfw TXCHARTMP goto RSwrtHexNibble RSwrtHexNibble ; currently only displays 0..9, A..F andlw 0x0F addlw 0x06 ; is it A..F, if so trigger a digit overflow skpndc addlw 7; subtract 10, then add 'A'-'0' addlw 0x30-6 ; Subtract extra 6 added to cause DC goto RStxChar RS232sendCR movlw 0x0D goto RStxChar RS232sendLF movlw 0x0A goto RStxChar RS232sendSpace movlw ' ' goto RStxChar RStxChar ; ; Output Start Bit ; Start bit is low, data bits are inverted ; movwf RStxTemp comf RStxTemp,f BANKSEL PORT_RS232 bcf PORT_RS232,RS232tx ; Make RS232 pin an ouput while transmitting character BANKSEL TRIS_RS232 bcf TRIS_RS232,RS232tx BANKSEL PORT_RS232 ; 1200 baud output ; move the char into RStxtemp, it is destroyed. ; zzz_-xxxxxxxx__ ; ; Do one more stop bit for luck ; ; This was needed on my XP machine ; but has not been needed before. ; ; bcf PORT_RS232,RS232tx call RSdelayBit ;Start Bit bsf PORT_RS232,RS232tx call RSdelayBit movlw 8 movwf RSloopCnt RStxCharLp1 ; After start bit, which is 1, then test each bit ; I need to set PA:0 to same as LSB RStxTemp ; this compares PA:0 with RStxTemp so see if it needs toggling ; The xorwf PORT_RS232,f causes the bit to be toggled if required. rrf RStxTemp,f movfw STATUS andlw 1 << C ; mask off bit addlw ( 1 << RS232tx) -1 ; shift bit by using a ripple carry xorwf PORT_RS232,W ; Doeas output need toggling ? andlw 1 << RS232tx ; Mask off output pin xorwf PORT_RS232,f ; Toggle output pin if needed call RSdelayBit ; delay bit decfsz RSloopCnt,f goto RStxCharLp1 bcf PORT_RS232,RS232tx call RSdelayBit ; apply stop bit ; apply an inter character delay of 4 bits ; call RSdelayBit ; get inter character delay from the EEPROM ; you have to read from RAM, and not EEPROM as pXXXX; does not work as EEwrt needs delay before EEread ; movfw RSinterCharDelay movlw 1 RStxCharInterDelay movwf RSloopCnt RStxCharLp2 call RSdelayBit decfsz RSloopCnt,f goto RStxCharLp2 ; Make RS232 pin an input so that main loop can test for start bit BANKSEL TRIS_RS232 bsf TRIS_RS232,RS232tx BANKSEL PORT_RS232 return ; timing functions to delay serial routines for a bit or half bit. RSdelayHalfBit movlw 0x1D ; shorten delay as edge detector takes about 22 us for 4800 baud goto RSdelayBit0 RSdelayBit nop movlw 0x40 ; for 4800 baud RSdelayBit0 movwf RSdelayCnt RSdelayBit1 decfsz RSdelayCnt,f ; 1 goto RSdelayBit1 ; 2 clk clrwdt return ;-------------------------------------------------------------------------- ; Sec 5.7 Serial Output Format Routines ;-------------------------------------------------------------------------- RSasciiToNibble movwf RSin ; if 0..1 then 0x30 to 0x39 ; if A..F then 0x41 to 0x46 ; if a..f then 0x61 to 0x66 ; test if bit 4 set and assume a letter or number btfss RSin,4 addlw 0x09 ; letter so add 9 andlw 0x0F ; mask of nibble return ;-------------------------------------------------------------------------- ; Sec 5.8 Serial Input Buffer Routine ;-------------------------------------------------------------------------- ; take serial input CAADD and put into buffer ; if char id ; the do command ; if char is CR reset buffer pointer ; if buff end then reset buff pointer RSipbuffStart EQU RScmd RSipbuffEnd EQU RSterminator RSbuffInput movwf RSin ; look for line feed and reset buff cnt addlw -0x0D BNZ RSbuffInput1 movlw RSipbuffStart movwf RSipBuffCnt return RSbuffInput1 ; end of line command - do command addlw -';'+0x0D BNZ RSbuffInput2 goto RSbuffInputProcess RSbuffInput2 ; Store the current time into the next register. movfw RSipBuffCnt movwf FSR movfw RSin movwf INDF incfSZ RSipBuffCnt,f movfw RSipBuffCnt addlw -(RSipbuffEnd+1) ; Check if the end of memory SKPZ goto RSbuffInputEnd1 movlw RSipbuffStart movwf RSipBuffCnt ; reset cursor movlw 0x0D call RStxChar return RSbuffInputProcess movlw RSipbuffStart movwf RSipBuffCnt movfw RSAa ; if 0..1 then 0x30 to 0x39 ; if A..F then 0x41 to 0x46 ; if a..f then 0x61 to 0x66 ; test if bit 4 set and assume a letter or number btfss RSAa,4 addlw 0x09 ; letter so add 9 andlw 0x0F ; mask of nibble movwf RSin SWAPF RSin,F movfw RSaA btfss RSaA,4 addlw 0x09 ; letter so add 9 andlw 0x0F ; mask of nibble ADDWF RSin,w movwf RSaddr movfw RSDd btfss RSDd,4 addlw 0x09 ; letter so add 9 andlw 0x0F ; mask of nibble movwf RSin SWAPF RSin,F movfw RSdD btfss RSdD,4 addlw 0x09 ; letter so add 9 andlw 0x0F ; mask of nibble ADDWF RSin,w movwf RSdata ; call RStxChar ; got to end of buffer so process. does not allow for backspace ; Write to file register movlw -'w' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput3 movfw RSaddr movwf FSR movfw RSdata movwf INDF goto RSbuffInputEndOK RSbuffInput3 ; put octet in EEPROM movlw -'p' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput4 BANKSEL RSaddr movfw RSaddr call EEsetAddr BANKSEL RSdata movfw RSdata call EEwrt goto RSbuffInputEndOK RSbuffInput4 ; read from file register movlw -'r' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput5 movfw RSaddr movwf FSR movfw INDF movwf RSin RSbuffInput4display movlw '=' call RStxChar SWAPF RSin,w call RSwrtHexNibble movfw RSin call RSwrtHexNibble goto RSbuffInputEnd RSbuffInput5 ; get from EEPROM register movlw -'g' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput6 movfw RSaddr call EEread movwf RSin goto RSbuffInput4display RSbuffInput6 ; get from EEPROM register movlw -'d' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput7 call RSbuffInputEnd2 movlw ( 1 << DSbit ) ; 00001000 movwf DSmask call DSreadScratch ; call RSbuffInputEnd movlw ( 1 << DSbit2 ) ; 00001000 movwf DSmask call DSreadScratch goto RSbuffInputEnd RSbuffInput7 ; get from EEPROM register movlw -'t' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput8 call RSbuffInputEnd2 movlw ( 1 << DSbit ) ; 00001000 movwf DSmask call DSreadTemp ; call RSbuffInputEnd movlw ( 1 << DSbit2 ) ; 00001000 movwf DSmask call DSreadTemp goto RSbuffInputEnd RSbuffInput8 ; get from EEPROM register movlw -'c' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput9 call RSbuffInputEnd2 movlw ( 1 << DSbit ) ; 00001000 movwf DSmask call DSreadRom call RSbuffInputEnd banksel DSmask movlw ( 1 << DSbit2 ) ; 00001000 movwf DSmask call DSreadRom goto RSbuffInputEnd ; ; EEPROM for program ; a - setaddr ; e - erase32 ; < - read word and increment ; > - write word and increment RSbuffInput9 ; set address for EEprom routines using AADD for AH AL movlw -'a' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput10 banksel RSaddr movfw RSaddr call EEsetProgAddrH banksel RSdata movfw RSdata call EEsetProgAddrL goto RSbuffInputEndOK RSbuffInput10 ; put octet in EEPROM movlw -'e' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput11 ; assumes EEADRH and EEADR are set up ; call EEsetProgAddr call EEprogErase goto RSbuffInputEndOK RSbuffInput11 ; put octet in EEPROM movlw -'>' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput12 banksel RSaddr movfw RSaddr banksel EEDATH movwf EEDATH banksel RSdata movfw RSdata banksel EEDATA movwf EEDATA ; assumes EEADRH and EEADR are set up call EEprogWrite call EEincProgAddr goto RSbuffInputEndOK RSbuffInput12 ; read from file register movlw -'<' ADDWF RScmd,w ; test to see if command is s, if so save into register. bnz RSbuffInput13 ; assumes EEADRH and EEADR are set up ; call EEsetProgAddr call EEprogRead call EEincProgAddr movlw '=' call RStxChar ; ; banksel EEDATH movfw EEDATH banksel RSin movwf RSin SWAPF RSin,w call RSwrtHexNibble movfw RSin call RSwrtHexNibble ; ; banksel EEDATA movfw EEDATA banksel RSin movwf RSin SWAPF RSin,w call RSwrtHexNibble movfw RSin call RSwrtHexNibble goto RSbuffInputEnd RSbuffInput13 movlw '?' call RStxChar goto RSbuffInputEnd RSbuffInputEndOK movlw '*' call RStxChar RSbuffInputEnd movlw ' ' call RStxChar RSbuffInputEnd0 movlw '-' call RStxChar RSbuffInputEnd2 movlw 0x0D call RStxChar movlw 0x0A call RStxChar bcf PORTLED,LEDoutput RSbuffInputEnd1 return cblock LASTFILE endc ;-------------------------------------------------------------------------- ; Sec 5.10 EEprom Routines for 16F88 ;-------------------------------------------------------------------------- EEsetProgAddrH ; set up EEADH banksel EEADRH movwf EEADRH return EEsetProgAddrL EEsetAddr banksel EEADR movwf EEADR return EEread ; w contains address banksel EEADR movwf EEADR banksel EECON1 ifdef EEPGD bcf EECON1, EEPGD; Point to Data memory endif EEprogReadCommon bsf EECON1,RD BANKSEL EEDATA ; Select Bank of EEDATA movfw EEDATA banksel 0 return EEprogRead ; Assumes addres is set up banksel EECON1 ifdef EEPGD bsf EECON1, EEPGD; Point to Prog memory endif goto EEprogReadCommon EEprogWrite ; blocking, EEADR and EEDATA set up. banksel EECON1 bcf EECON1,WREN ; disable EROM ifdef FREE BCF EECON1, FREE ; Disable Row Erase operation endif ifdef EEPGD bsf EECON1, EEPGD ; Point to PROG endif goto EEwrtCommon EEprogErase ; blocking, EEADR and EEDATA set up. banksel EECON1 bcf EECON1,WREN ; disable EROM ifdef FREE BSF EECON1, FREE ; Enable Row Erase operation endif ifdef EEPGD bsf EECON1, EEPGD ; Point to PROG endif goto EEwrtCommon EEwrt ; blocking, EEADR and EEDATA set up. banksel EEDATA movwf EEDATA ;bcf PIR1,EEIF banksel EECON1 bcf EECON1,WREN ; disable EROM ifdef FREE BCF EECON1, FREE ; Enable Row Erase operation endif ifdef EEPGD bcf EECON1, EEPGD ; Point to DATA endif EEwrtCommon bsf EECON1,WREN bcf INTCON,GIE movlw 0x55 movwf EECON2 movlw 0xAA movwf EECON2 bsf EECON1,WR BsF INTCON,GIE ; Now wait for EEwrt to finish write EEwaitForWrt ; block until EEPROM write has finished. bcf EECON1,WREN ; disable EROM ; NOTE:- I have commented out the goto and the write to eeprom started to work ; btfsc EECON1,WR ; goto EEwaitForWrt ;bcf EECON1,EEIF ; EEPROM finished banksel 0 return ; ; EEPROM for program ; a - setaddr ; e - erase32 words at address. ; < - read word and increment ; > - write word and increment, needs to write 4 butes at once. ; EEincProgAddr ; banksel RSeeaddrl ; incfsz RSeeaddrl ; goto $+2 ; incfsz RSeeaddrh banksel EEADR incfsz EEADR return banksel EEADRH incf EEADRH,f return LastProgWord ;-------------------------------------------------------------------------- ; Sec 7.0 EEPROM data ;-------------------------------------------------------------------------- ORG 0x2100 ; set up a bit map to stop upload. ifdef MEM24LC16 DE 0xF8 ; EE_MAX_WRTH endif ifdef MEM24LC65 DE 0xE0 ; EE_MAX_WRTH endif ifdef MEM24LC256 DE 0x80 ; EE_MAX_WRTH ;DE 0xFF ; EE_MAX_WRTH endif DE .1 ; EE_SAMPLERATEH Sample counts in 50 ms intervals DE .20 ; EE_SAMPLERATEL Sample counts in 50 ms intervals 20 times per second ;DE .20 ; EE_SAMPLERATEL Sample counts in 50 ms intervals 20 times per second ;DE .80 ; EE_SAMPLERATEL Sample counts in 50 ms intervals 20 times per second cblock LastVar endc END