;--------------------------------------------------------------------- ; 喋る超音波メジャー (Talking Measure) ; ; 2016.05.28 naka ; ; (1). GP0 [out]: 超音波センサ・トリガ ; (2). GP1 [out]: センサからのECHOモニタ ; (3). GP2 [out]: PWM出力(スピーカへ) ; (4). GP3(T1G) [in] : 超音波センサ・エコー ; (5). GP4 [in] : I2C SDA ; (6). GP5 [in] : I2C SCL ; ; ・動作クロック :8MHz ; ・シリアルEEPROM 24FC1025(1Mbit) ; ;--------------------------------------------------------------------- ;--------------------------------------------------------------------- ; デバイス定義 ;--------------------------------------------------------------------- LIST P=PIC12F615 INCLUDE "P12F615.INC" __CONFIG _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _IOSCFS_8MHZ & _INTRC_OSC_NOCLKOUT & _BOR_OFF ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制 ;--------------------------------------------------------------------- ; 変数レジスタの定義 ;--------------------------------------------------------------------- WAIT1 EQU H'40' WAIT2 EQU H'41' CNT EQU H'42' TMP EQU H'43' TMP2 EQU H'44' WK EQU H'45' WK2 EQU H'46' ADDRH1 EQU H'47' ADDRH EQU H'48' ADDRL EQU H'49' ECHOL EQU H'4A' ECHOM EQU H'4B' ECHOH EQU H'4C' DISTL EQU H'4D' DISTM EQU H'4E' DISTH EQU H'4F' binH EQU H'50' binL EQU H'51' bcdH EQU H'52' bcdM EQU H'53' bcdL EQU H'54' counter EQU H'55' temp EQU H'56' ECHOERR EQU H'57' BKdatai EQU H'58' WAVFLG EQU H'59' ;--------------------------------------------------------------------- ; マクロ定義 ;--------------------------------------------------------------------- BANK0 MACRO BCF STATUS,RP0 ;BANK0に切り替える ENDM BANK1 MACRO BSF STATUS,RP0 ;BANK1に切り替える ENDM ;--------------------------------------------------------------------- ; リセットベクタ ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 GOTO MAIN ; ; ORG 04H ; 割り込み時の飛び込み先 ;--------------------------------------------------------------------- ; 割り込み処理 ;--------------------------------------------------------------------- INTRUPT BCF INTCON,T0IF ;割り込みフラグリセット BSF ECHOERR,0 ; ECHOタイムアウト フラグ設定 RETFIE ;--------------------------------------------------------------------- ; メイン処理 ;--------------------------------------------------------------------- MAIN CALL INIT ; CALL WAIT100MS ; 超音波センサが安定するまで待つ(念のため) ; CLRW CALL GETINDX ; ダミーで読み込み(なぜか1回目がうまくいかないので) MAIN_LP CALL USTRIG ; 超音波トリガ CALL CKECHO ; エコー確認(時間測定) CALL CALCDST ; 距離に変換 CALL CNVBCD ; BCD変換 CALL TALKDST ; しゃべる CALL WAIT05S ; 0.5秒待つ GOTO MAIN_LP ; ;--------------------------------------------------------------------- ; 初期化 ;--------------------------------------------------------------------- INIT CLRF INTCON ;全割込み禁止 CLRF CMCON0 CLRF CMCON1 CLRF T1CON ; BANK1 CLRF ANSEL MOVLW B'00001000' ; ポートはGP3を入力、 MOVWF TRISIO ; 他は全て出力端子(通信時に変える) MOVLW H'65' MOVWF PR2 ; PWM周期 CLRF APFCON ; Pin Finction Control BSF APFCON,T1GSEL ; T1G = GP3 BSF APFCON,P1BSEL ; ; BCF PIE1,TMR1IE ;Timer1 割込みを不許可 ; ;timer0 割り込みセット (超音波センサーのECHOがHIGHを持続する不具合対策) MOVLW H'87' ;プリスケーラを1:256にする MOVWF OPTION_REG ;clock8MHz -> 2Mcycle BANK0 ;1/2Mcycle * 256 * 256 = 32.8ms ... 5.4m ; CLRF GPIO ; MOVLW B'00001100' MOVWF CCP1CON ; PWM P1A single mode CLRF CCPR1L ; ; FOSC/4 = 2MHz -> PreScale 2:1 -> 1MHz (1us/COUNT) BSF T1CON,T1GINV ; Timer1 gate is active-high BCF T1CON,TMR1ON ; Timer1 Gate off BCF T1CON,TMR1GE ; Timer1 Gate Enable BCF T1CON,T1CKPS1 ; prescaler 1:2 BSF T1CON,T1CKPS0 ; prescaler BCF T1CON,TMR1CS BCF CMCON1,T1ACS BSF CMCON1,T1GSS CLRF CMCON0 ; BANK1 BANK0 ; RETURN ; ;--------------------------------------------------------------------- WAIT10US MOVLW D'5' MOVWF WAIT1 W10USLP DECFSZ WAIT1,F GOTO W10USLP RETURN ; WAIT1MS MOVLW D'221' MOVWF WAIT1 W1MSLP GOTO $+1 GOTO $+1 GOTO $+1 DECFSZ WAIT1,F GOTO W1MSLP GOTO $+1 GOTO $+1 GOTO $+1 RETURN ; WAIT10MS MOVLW D'10' MOVWF WAIT2 W10MSLP CALL WAIT1MS DECFSZ WAIT2,F GOTO W10MSLP RETURN ; WAIT100MS MOVLW D'100' MOVWF WAIT2 W100MSLP CALL WAIT1MS DECFSZ WAIT2,F GOTO W100MSLP RETURN ; WAIT05S MOVLW D'100' MOVWF WAIT2 W05SLP CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS DECFSZ WAIT2,F GOTO W05SLP RETURN ; WAIT1S MOVLW D'200' MOVWF WAIT2 W1SLP CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS CALL WAIT1MS DECFSZ WAIT2,F GOTO W1SLP RETURN ; WSMPTIM ; 8KHz = 125us RETURN MOVLW D'40' MOVWF WAIT1 WSTLP DECFSZ WAIT1,F GOTO WSTLP RETURN ;--------------------------------------------------------------------- ; Ultrasonic Triger ;--------------------------------------------------------------------- USTRIG BCF PIR1,TMR1IF ; Clear Timer1 interrupt flag BSF T1CON,TMR1GE ; Timer1 Gate Enable BSF T1CON,TMR1ON ; Timer1 On CLRF TMR1L ; エコーパルス幅カウント用タイマ クリア CLRF TMR1H ; BSF GPIO,GP0 ; トリガ CALL WAIT10US BCF GPIO,GP0 ; RETURN ;--------------------------------------------------------------------- ; 超音波センサのエコー確認 ;--------------------------------------------------------------------- CKECHO BCF INTCON,T0IF ;割り込みフラグリセット CLRF TMR0 CLRF ECHOERR BSF INTCON,T0IE ; タイマ0割り込みイネーブル BSF INTCON,GIE ; 割り込み許可 ; CKECHO1 BTFSC GPIO,GP3 ; ECHO立ち上がりを待つ GOTO CKECHO1_1 BTFSS ECHOERR,0 ; タイムアウト確認 GOTO CKECHO1 ; CKECHO1_1 BSF GPIO,1 ; ECHOモニタLED ON CLRF TMR0 CKECHO2 BTFSS GPIO,GP3 ; ECHO立下りを待つ GOTO CKECHO2_2 BTFSS ECHOERR,0 ; タイムアウト確認 GOTO CKECHO2 ; CKECHO2_2 BTFSS ECHOERR,0 BCF GPIO,1 ; ECHOモニタLED OFF ; BCF INTCON,T0IE ; タイマ0割り込み禁止 BCF INTCON,GIE ; 割り込み禁止 CLRF TMR0 ; ; TIMER1 カウンタ値を確認 BCF T1CON,TMR1ON ; Timer1 Off BCF T1CON,TMR1GE ; Timer1 Gate Off ; MOVF TMR1L,W MOVWF ECHOL MOVF TMR1H,W MOVWF ECHOM CLRF ECHOH RETURN ;--------------------------------------------------------------------- ; 時間を距離に変換 ;--------------------------------------------------------------------- CALCDST ; ; 距離(m) = 時間/2(往復なので) x 音速(340m/s) ; 距離(cm) = TMR1 * 1us * 17 / 1000 [cm] ; 17 / 1000 ≒ 35 / 2048 = 0.017089 ; ~~~~ 11bit 右シフト CALL MLT35 CALL DIV2048 CALL CNVBCD ; BCD値に変換 ; RETURN ;--------------------------------------------------------------------- ; 35倍 32倍+2倍+1倍 ;--------------------------------------------------------------------- MLT35 MOVF ECHOL,W ; 1倍 MOVWF DISTL MOVF ECHOM,W MOVWF DISTM CLRF DISTH ; BCF STATUS,C ; 2倍 RLF ECHOL,F RLF ECHOM,F RLF ECHOH,F MOVF ECHOL,W ADDWF DISTL,F MOVF ECHOM,W BTFSC STATUS,C ADDLW D'1' ADDWF DISTM,F MOVF ECHOH,W BTFSC STATUS,C ADDLW D'1' ADDWF DISTH,F ; BCF STATUS,C ; 4倍 RLF ECHOL,F RLF ECHOM,F RLF ECHOH,F ; BCF STATUS,C ; 8倍 RLF ECHOL,F RLF ECHOM,F RLF ECHOH,F ; BCF STATUS,C ; 16倍 RLF ECHOL,F RLF ECHOM,F RLF ECHOH,F ; BCF STATUS,C ; 32倍 RLF ECHOL,F RLF ECHOM,F RLF ECHOH,F MOVF ECHOL,W ADDWF DISTL,F MOVF ECHOM,W BTFSC STATUS,C ADDLW D'1' ADDWF DISTM,F MOVF ECHOH,W BTFSC STATUS,C ADDLW D'1' ADDWF DISTH,F RETURN ;--------------------------------------------------------------------- ; ÷2048 (11ビット右シフト) ;--------------------------------------------------------------------- DIV2048 ; 1cm以下を四捨五入するため、1024加算 MOVLW H'04' ADDWF DISTM,F BTFSC STATUS,C INCF DISTH,F ; MOVF DISTM,W ; 8ビットシフト= 1/256 MOVWF DISTL MOVF DISTH,W MOVWF DISTM CLRF DISTH ; BCF STATUS,C ; 1/512 RRF DISTM,F RRF DISTL,F ; BCF STATUS,C ; 1/1024 RRF DISTM,F RRF DISTL,F ; BCF STATUS,C ; 2/2048 RRF DISTM,F RRF DISTL,F RETURN ;--------------------------------------------------------------------- ; BIN->BCD ;--------------------------------------------------------------------- CNVBCD MOVF DISTL,W MOVWF binL MOVF DISTM,W MOVWF binH CALL _bin2bcd RETURN ;--------------------------------------------------------------------- ; 距離発声 ;--------------------------------------------------------------------- TALKDST CLRF datai CALL SETDUTY MOVLW H'04' ; プリスケーラなし MOVWF T2CON ; TIMER2スタート BCF WAVFLG,0 ; BTFSC ECHOERR,0 ; 測定タイムアウトエラー確認 GOTO TLKERR ; MOVF bcdM,F ; ゼロチェック BTFSS STATUS,Z GOTO TALK MOVF bcdL,F BTFSC STATUS,Z GOTO TLKZERO TALK ; メートル発声 MOVF bcdM,W BTFSC STATUS,Z GOTO TLK10CMJ TLKM ; メートル SUBLW D'4' ; 5メートル以上はエラー BTFSS STATUS,C GOTO TLKERR MOVLW D'1' ; -1 オフセット SUBWF bcdM,W CALL SPECH MOVF bcdL,F ; メートルジャストならセンチの発声なし BTFSC STATUS,Z GOTO TLKRET ; TLK10CMJ MOVLW H'0F' ANDWF bcdL,W ; 10センチジャストか判定 BTFSS STATUS,Z GOTO TLK10CM ; 10センチジャスト発声 SWAPF bcdL,W ANDLW H'0F' ADDLW D'14' ; 10センチジャスト音声オフセット CALL SPECH GOTO TLKRET ; TLK10CM ; 10センチ発声 SWAPF bcdL,W ANDLW H'0F' BTFSC STATUS,Z GOTO TLK1CM ADDLW D'23' ; 10センチ音声オフセット CALL SPECH ; TLK1CM ; 1センチ発声 MOVF bcdL,W ANDLW H'0F' ADDLW D'5' ; 1センチ音声オフセット CALL SPECH GOTO TLKRET ; TLKZERO MOVLW D'4' ; ゼロセンチ CALL SPECH GOTO TLKRET ; TLKERR MOVLW D'33' ; 測定エラー CALL SPECH GOTO TLKRET ; TLKRET CALL FADEOUT CLRF T2CON ; TIMER2ストップ RETURN ;--------------------------------------------------------------------- ; BCD->BIN ;--------------------------------------------------------------------- BCD2BIN MOVWF WK ANDLW H'0F' MOVWF WK2 ; SWAPF WK,W ; 10の位を10倍 ANDLW H'0F' MOVWF TMP MOVWF TMP2 BCF STATUS,C RLF TMP,F RLF TMP,F RLF TMP,W ADDWF TMP2,W ADDWF TMP2,W ADDWF WK2,W RETURN ; ;--------------------------------------------------------------------- ; 再生(Wレジでwavの番号を渡す) ;--------------------------------------------------------------------- SPECH CALL GETINDX ; インデックスを読み込む(アドレスがADDRH,ADDRLに返る) CALL BYTEREAD ; バイトリード SPECHL CALL ACK CALL RX ; シーケンシャルリード MOVF datai,F ; 終了確認 BTFSC STATUS,Z GOTO SPECHE ; ターミネータ0x00まで繰り返す ; BTFSS WAVFLG,0 ; PWM開始後の最初のWAVデータならフェイドイン CALL FADEIN ; 開始時にプツという音がしないように。 BSF WAVFLG,0 ; CALL SETDUTY ; CALL WAIT10US ; 発声速度調整 GOTO SPECHL SPECHE CALL RDTERM ; 読み込み完了 RETURN ; ;--------------------------------------------------------------------- ; フェイドイン(PWMデューティを0から最初のWAVデータ値にする) ;--------------------------------------------------------------------- FADEIN MOVF datai,W MOVWF WK2 ; datai退避 MOVWF CNT BTFSC STATUS,Z RETURN CLRF WK FADEINLP MOVF WK,W MOVWF datai CALL SETDUTY CALL WAIT10US INCF WK,F DECFSZ CNT,F GOTO FADEINLP ; MOVF WK2,W ; datai復元 MOVWF datai RETURN ; ;--------------------------------------------------------------------- ; フェイドアウト(直前のWAVデータ値BKdataiを徐々に0にする) ;--------------------------------------------------------------------- FADEOUT MOVF BKdatai,W ; 0 なら終了 BTFSC STATUS,Z RETURN DECF BKdatai,W MOVWF datai CALL SETDUTY CALL WAIT10US GOTO FADEOUT ; ;--------------------------------------------------------------------- ; WAV振幅をPWMのデューティへ設定 ;--------------------------------------------------------------------- SETDUTY MOVF datai,W MOVWF BKdatai ; 保存 ANDLW H'03' ; 下位2ビット取り出し MOVWF TMP SWAPF TMP,W ; B'000000XX' → B'00XX0000' IORLW B'00001100' ; B'00XX1100' MOVWF CCP1CON ; PWMデューティの下位2ビット設定 ; BCF STATUS,C ; 2ビット右シフト RRF datai,F BCF STATUS,C RRF datai,W MOVWF CCPR1L ; PWMデューティの上位6ビット設定 RETURN ;--------------------------------------------------------------------- ; EEPROMのインデックスを読み、WAV本体のアドレス取得 ;--------------------------------------------------------------------- GETINDX MOVWF TMP BCF STATUS,C RLF TMP,W ; 2倍してインデックスアドレス MOVWF ADDRL CLRF ADDRH ; 上位アドレスクリア CLRF ADDRH1 CALL BYTEREAD ; Highアドレス読み込み CALL ACK MOVF datai,W MOVWF ADDRH CALL RX ; シーケンシャルリードでLowアドレス CALL RDTERM ; 読み込み完了 MOVF datai,W MOVWF ADDRL CALL RSTADDR ; アドレス復元 RETURN ; ;--------------------------------------------------------------------- ; アドレス復元(16ビットADDRH,Lを17ビットアドレスに戻す) ;--------------------------------------------------------------------- RSTADDR CLRF ADDRH1 BCF STATUS,C RLF ADDRL,F RLF ADDRH,F RLF ADDRH1,F ; 最上位アドレス RETURN ; ;--------------------------------------------------------------------- ; I2Cアクセスルーチン ; 流用元:Microchip Applicatin Note : AN982 ; Interfacing I2C Serial EEPROMs to PIC10 and PIC12 Drivers ;--------------------------------------------------------------------- ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ; ; Filename: i2c_routines.inc ; Date: March 21, 2005 ; File Version: 1.0 ; Assembled using: MPLAB IDE 7.00.00.0 ; ; Author: Chris Parris ; Company: Microchip Technology, Inc. ; ;*******************RAM register definitions********************** #define STARTRAM 0x60 ; Start RAM at address 0x60 cblock STARTRAM buffer ; Transfer/Receive bit buffer datai ; Data input byte buffer datao ; Data output byte buffer bitcount ; Bit loop counter bytecount ; Byte loop counter addressH ; Word address pointer addressL ; Word address pointer loops ; Delay loop counter loops2 ; Delay loop counter pollcnt ; Polling loop counter endc ;*******************Bit definitions******************************* SDA equ 4 ; I2C data pin, GPIO pin GP4 SCL equ 5 ; I2C clock pin, GPIO pin GP5 DO equ 0 ; TX/RX buffer output bit DI equ 1 ; TX/RX buffer input bit ACKB equ 2 ; ACK/NO ACK select bit ;*******************Macro definitions***************************** WRITE_ADDR equ b'10100000' ; Control byte for write operations READ_ADDR equ b'10100001' ; Control byte for read operations ;*******************Delay Macros********************************** ; Each macro delay for 1 inst. cycle less than ; required, as the instruction immediately ; before the macro call provides 1 inst. cycle. ;***************************************************************** THIGH macro ; Clock high time delay (5 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) nop ; 0.5us endm THDSTA macro ; Start condition hold time delay (5 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) nop ; 0.5us endm TSUSTA macro ; Start condition setup time delay (5 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) nop ; 0.5us endm TSUSTO macro ; Stop condition setup time delay (5 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) nop ; 0.5us endm TAA macro ; Output valid from clock delay (4 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) goto $+1 ; 2-inst. cycle delay (1 us) nop ; 0.5us endm ;*******************Start bit subroutine************************** ; This routine generates a Start condition ; (high-to-low transition of SDA while SCL ; is still high. ;***************************************************************** BSTART bsf GPIO,SCL ; Make sure SCL is high TSUSTA ; Start condition setup time delay BANK1 BCF TRISIO,SDA ; Configure SDA to be an output BANK0 bcf GPIO,SDA ; Pull SDA low to initiate ; Start condition THDSTA ; Start condition hold time delay bcf GPIO,SCL ; Bring SCL low in preparation ; for data transfer BANK1 BSF TRISIO,SDA ; Configure SDA to be an input BANK0 retlw 0 ;*******************Stop bit subroutine*************************** ; This routine generates a Stop condition ; (low-to-high transition of SDA while SCL ; is still high. ;***************************************************************** BSTOP BANK1 BCF TRISIO,SDA ; Configure SDA to be an output BANK0 bcf GPIO,SDA ; Pull SDA low bsf GPIO,SCL ; Make sure SCL is high TSUSTO ; Stop condition setup time delay BANK1 BSF TRISIO,SDA ; Configure SDA to be an input BANK0 retlw 0 ;*******************Bit output subroutine************************* ; This routine outputs bit 'DO' in 'buffer' to ; the serial EEPROM device. ;***************************************************************** BITOUT bcf GPIO,SCL ; Make sure SCL is low btfss buffer,DO ; Check for state of bit to xmit goto bitlow ; If bit is low, pull SDA low clockout ; If bit is high, leave SDA high bsf GPIO,SCL ; Bring SCL high to begin transfer THIGH ; Clock high time delay bcf GPIO,SCL ; Bring SCL low again BANK1 BSF TRISIO,SDA ; Configure SDA to be an input BANK0 retlw 0 bitlow BANK1 BCF TRISIO,SDA ; Configure SDA to be an output BANK0 bcf GPIO,SDA ; Pull SDA low goto clockout ;*******************Bit input subroutine************************** ; This routine inputs a bit of data from the ; serial EEPROM device, and stores it in bit ; 'DO' of 'buffer'. ;***************************************************************** BITIN bcf GPIO,SCL ; Make sure SCL is low BANK1 BSF TRISIO,SDA ; Configure SDA to be an input BANK0 bsf buffer,DI ; Assume input bit is high bsf GPIO,SCL ; Bring SCL high to begin transfer TAA ; Output valid from clock delay btfss GPIO,SDA ; Check for state of SDA bit bcf buffer,DI ; If SDA is low, set bit low bcf GPIO,SCL ; Bring SCL low again retlw 0 ;*******************Data transmit subroutine********************** ; This routine transmits the byte of data ; stored in 'datao' to the serial EEPROM ; device. Instructions are also in place ; to check for an ACK bit, if desired. ; Just replace the 'goto' instruction, ; or create an 'ackfailed' label, to provide ; the functionality. ;***************************************************************** TX movlw .8 movwf bitcount ; Initialize loop counter to 8 txlp bsf buffer,DO ; Assume output bit is high btfss datao,7 ; Check state of next output bit bcf buffer,DO ; If low, set buffer bit low call BITOUT ; Call routine to output bit rlf datao,F ; Rotate datao left for next bit decfsz bitcount,F ; Decrement counter, check if done goto txlp ; Keep looping call BITIN ; Call routine to read ACK bit retlw 0 ;*******************Data receive subroutine*********************** ; This routine reads in one byte of data from ; the serial EEPROM device, and stores it in ; 'datai'. It then responds with either an ; ACK or a NO ACK bit, depending on the value ; of 'ACKB' in 'buffer'. ;***************************************************************** RX clrf datai ; Clear input buffer movlw .8 movwf bitcount ; Initialize loop counter to 8 bcf STATUS,C ; make sure carry bit is low rxlp rlf datai,F ; Rotate datai 1 bit left call BITIN ; Read a bit btfsc buffer,DI bsf datai,0 ; Set bit 0 if necessary decfsz bitcount,F ; 8 bits done? goto rxlp ; If not, do another RETLW 0 ACK bcf buffer,DO ; If ACKB = 1, send ACK (DO = 0) call BITOUT ; Send bit retlw 0 NOACK bsf buffer,DO ; If ACKB = 1, send ACK (DO = 0) call BITOUT ; Send bit retlw 0 ;*******************Delay Subroutine****************************** ; This routine takes the value in 'loops' and ; multiplies it by 1 millisecond to determine ; the delay time. ;***************************************************************** WAIT top movlw .100 ; Timing adjustment variable movwf loops2 ; this loop creates a 1 ms delay top2 nop ; Delay for 10 us goto $+1 ; the delay includes the decfsz & goto goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 goto $+1 decfsz loops2, F ; Inner loops complete? goto top2 ; If no, go again decfsz loops, F ; Outer loops complete? goto top ; If no, go again retlw 0 ; If yes, return from sub ;*******************Byte read test subroutine********************* ; This routine tests the byte read feature ; of the serial EEPROM device. It will read ; 16 bytes of data from the device starting at ; address 0x50, 1 byte at a time. ;***************************************************************** BYTEREAD movlw .8 movwf bytecount ; Initialize counter to 16 bytes rxbyte call BSTART ; Generate start bit ; Now send the control byte ; for a write, to set address movlw WRITE_ADDR movwf datao ; Copy control byte to buffer BTFSC ADDRH1,0 BSF datao,3 ; BLOCK select bit call TX ; Output control byte to device ; Next, the address pointer movf ADDRH,W ; Copy address to WREG movwf datao ; Copy address to buffer call TX ; Output address to device ; Next, the address pointer movf ADDRL,W ; Copy address to WREG movwf datao ; Copy address to buffer call TX ; Output address to device call BSTART ; Generate another start bit ; to switch to read mode movlw READ_ADDR movwf datao ; Copy control byte to buffer BTFSC ADDRH1,0 BSF datao,3 ; BLOCK select bit call TX ; Output control byte to device ; Finally, read the data byte call RX ; Input data from device RETURN RDTERM CALL NOACK call BSTOP ; Generate stop bit RETURN ;--------------------------------------------------------------------- ; 16-bit binary to BCD conversion ; pete griffiths 2007 ; http://picprojects.org.uk/projects/pictips.htm ; ; These file register variables will ; need to be defined elsewhere. ; binH ; binL ; bcdH ; bcdM ; bcdL ; counter ; temp ; ; binH, binL contain the binary value to ; convert. Conversion process destroys contents. ; Result is in bcdH, bcdM, bcdL on return. ; Call _bin2bcd to perform conversion. ; ; Executes in 454 instructions _bin2bcd movlw d'16' movwf counter clrf bcdL clrf bcdM clrf bcdH _repeat rlf binL,F rlf binH,F rlf bcdL,F rlf bcdM,F rlf bcdH,F decfsz counter,F goto _adjust return _adjust movlw d'14' subwf counter,W skpnc goto _repeat movfw bcdL addlw 0x33 movwf temp movfw bcdL btfsc temp,3 addlw 0x03 btfsc temp,7 addlw 0x30 movwf bcdL movfw bcdM addlw 0x33 movwf temp movfw bcdM btfsc temp,3 addlw 0x03 btfsc temp,7 addlw 0x30 movwf bcdM goto _repeat ; we only need to do the test and add +3 for ; the low and middle bcd variables since the ; largest binary value is 0xFFFF which is ; 65535 decimal so the high bcd byte variable ; will never be greater than 6. ; We also skip the tests for the first two ; shifts. ;--------------------------------------------------------------------- END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------