;--------------------------------------------------------------------- ; 8ピンPICの喋る時計 ; ; 2011.05.05 naka ; ; (1). GP0 [in] : 時刻設定modeスイッチ ; (2). GP1 [in] : 時刻設定inc / adj(±30秒の調整)スイッチ ; (3). GP2 [out]: PWM出力(スピーカへ) ; (4). GP3 [in] : 時刻発声スイッチ(振動スイッチ) ; (5). GP4 [in] : I2C SDA ; (6). GP5 [in] : I2C SCL ; ; ・動作クロック :8MHz ; ・消費電力(待機時):約0.1〜0.2uA (実測) ; (喋り時):30mA程度 ; ・クロックモジュール(RTC-8564NB) ; ・シリアル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' OFFSET EQU H'43' TMP EQU H'44' TMP2 EQU H'45' WK EQU H'46' WK2 EQU H'47' SWFLG EQU H'48' FLG EQU H'49' HOUR EQU H'4A' ADDRH1 EQU H'4B' ADDRH EQU H'4C' ADDRL EQU H'4D' MIN EQU H'4E' MIN10 EQU H'4F' CLKCTL1 EQU H'50' CLKCTL2 EQU H'51' CLKSEC EQU H'52' CLKMIN EQU H'53' CLKHOUR EQU H'54' ;--------------------------------------------------------------------- ; マクロ定義 ;--------------------------------------------------------------------- BANK0 MACRO BCF STATUS,RP0 ;BANK0に切り替える ENDM BANK1 MACRO BSF STATUS,RP0 ;BANK1に切り替える ENDM ;--------------------------------------------------------------------- ; リセットベクタ ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 GOTO MAIN ; ; ORG 04H ; 割り込み時の飛び込み先 GOTO MAIN ;--------------------------------------------------------------------- ; メイン処理 ;--------------------------------------------------------------------- MAIN CALL INIT ; CALL WAIT1S ; クロックモジュールの発振安定待ち CALL INTCLK ; クロックモジュールの初期化 ; GOTO TALKTIM ; MAINLP CLRF CCP1CON ; PWM停止 CLRF T2CON ; TIMER2停止 BCF INTCON,GPIF ; GPIO変化フラグクリア BSF INTCON,PEIE BSF INTCON,GPIE ; SLEEP NOP ; MOVLW H'04' ; プリスケーラなし MOVWF T2CON ; TIMER2スタート CALL TESTSW BTFSC SWFLG,0 ; タクトSW-0(SETMODE)が押されるのを待つ GOTO SETMODE BTFSC SWFLG,1 ; タクトSW-1(ADJUST)が押されるのを待つ GOTO ADJUST BTFSS SWFLG,2 ; タクトSW-2(SPEECH)が押されるのを待つ GOTO MAINLP TALKTIM CALL READCLK ; 現在の時刻読み上げ CALL SPEECH GOTO MAINLP ; SETMODE CALL SETTIM ; 時刻設定 GOTO MAINLP ADJUST CALL ADJTIM ; 時刻アジャスト GOTO MAINLP ; ;--------------------------------------------------------------------- ; 初期化 ;--------------------------------------------------------------------- INIT CLRF INTCON ;全割込み禁止 BANK1 CLRF ANSEL BANK1 CLRF T1CON CLRF CMCON0 CLRF CMCON1 CLRF APFCON ; Pin Finction Control MOVLW B'00001011' ; ポートは0,1,3ビット目を入力、 MOVWF TRISIO ; 他は全て出力端子(通信時に変える) MOVLW H'65' MOVWF PR2 ; PWM周期 BANK0 ; MOVLW H'30' MOVWF GPIO MOVLW H'04' ; プリスケーラなし MOVWF T2CON ; TIMER2スタート ; CLRF CLKHOUR CLRF CLKMIN ; BANK1 MOVLW B'00001011' MOVWF IOC ; GPIO変化割り込み(GPIO 0,1,3) BANK0 ; RETURN ;--------------------------------------------------------------------- ; SW状態確認 ;--------------------------------------------------------------------- TESTSW BCF SWFLG,0 BCF SWFLG,1 BCF SWFLG,2 ; BTFSC GPIO,0 ; 設定モードスイッチ確認 BSF SWFLG,0 BTFSC GPIO,1 ; ADJ/INCスイッチ確認 BSF SWFLG,1 BTFSS GPIO,3 ; Talkスイッチ確認 BSF SWFLG,2 ; CALL WAIT10MS ; チャタリング防止 RETURN ; ;--------------------------------------------------------------------- ; 時刻設定 ;--------------------------------------------------------------------- SETTIM ; 現在の時刻をCLOCKモジュールから読み出す MOVLW D'32' ; 「時刻設定」発声 CALL SPECH ; CALL READCLK CALL INCMINI ; 設定のためにBCDを分解 CALL INCHINI ; 設定のためにBCDをBINに ; CALL WAIT05S ; 0.5秒待ち CALL SPECH_HOUR ; 時を読み上げ SETTIMH CALL TESTSW BTFSC SWFLG,0 ; 設定モードSW GOTO SETTIMM BTFSS SWFLG,1 ; ADJ/INC SW GOTO SETTIMH ; CALL INCHOUR ; 時インクリメント CALL SPECH_HOUR ; 時を読み上げ ; CALL TESTSW BTFSC SWFLG,1 ; ADJ/INC SWが離されるまで待つ GOTO $-2 GOTO SETTIMH SETTIMM CALL SPECH_MIN ; 分を読み上げ SETTIML CALL TESTSW BTFSC SWFLG,0 ; 設定モードSW GOTO SETTIME ; 設定終了 BTFSS SWFLG,1 ; ADJ/INC SW GOTO SETTIML ; CALL INCMIN ; 分インクリメント CALL SPECH_MIN ; 分を読み上げ ; CALL TESTSW BTFSC SWFLG,1 ; ADJ/INC SWが離されるまで待つ GOTO $-2 GOTO SETTIML ; SETTIME ; 設定終了 CALL WRTCLK CALL READCLK CALL SPEECH ; 時刻読み上げ ; RETURN ;--------------------------------------------------------------------- ; 時刻アジャスト(30秒未満は切り捨て、30秒以上は分・時をインクリメント) ;--------------------------------------------------------------------- ADJTIM ; 現在の時刻をCLOCKモジュールから読み出す CALL READCLK CALL INCMINI ; 設定のためにBCDを分解 CALL INCHINI ; 設定のためにBCDをBINに ; ADJTIMS ; 秒を調べる SWAPF CLKSEC,W ; "0X',"1X","2X" の時はクリア CLRF CLKSEC ; 秒をクリア ANDLW H'0F' SUBLW D'2' BTFSC STATUS,C GOTO ADJEND ADJINC CALL INCMIN ; 分インクリメント BTFSC FLG,0 CALL INCHOUR ; 時インクリメント ; ADJEND ; 設定終了 CALL WRTCLK CALL READCLK CALL SPEECH ; アジャストした時刻読み上げ ; CALL TESTSW BTFSC SWFLG,1 ; ADJ/INC SWが離されるまで待つ GOTO $-2 ; RETURN ;--------------------------------------------------------------------- ; 時刻設定(時) ;--------------------------------------------------------------------- INCHINI MOVF CLKHOUR,W CALL BCD2BIN MOVWF TMP MOVLW D'12' ; 24H→12Hに変換 SUBWF TMP,W BTFSS STATUS,C MOVF TMP,W ; 12を引く前の値 MOVWF HOUR RETURN INCHOUR INCF HOUR,F MOVF HOUR,W SUBLW D'12' BTFSS STATUS,Z GOTO INCHOURS ; CLRF HOUR ; 0時(12時)に戻る ; INCHOURS MOVF HOUR,W CALL BIN2BCD MOVWF CLKHOUR ; RETURN ; BIN2BCD MOVWF OFFSET MOVLW H'00' MOVWF PCLATH MOVF OFFSET,W ADDWF PCL,F ; RETLW H'00' RETLW H'01' RETLW H'02' RETLW H'03' RETLW H'04' RETLW H'05' RETLW H'06' RETLW H'07' RETLW H'08' RETLW H'09' RETLW H'10' RETLW H'11' ;--------------------------------------------------------------------- ; 時刻設定(分) ;--------------------------------------------------------------------- INCMINI MOVF CLKMIN,W ANDLW H'0F' MOVWF MIN SWAPF CLKMIN,W ANDLW H'0F' MOVWF MIN10 RETURN INCMIN BCF FLG,0 ; 時桁上げフラグ INCF MIN,F MOVF MIN,W SUBLW D'10' BTFSS STATUS,Z GOTO INCMINS ; CLRF MIN ; 桁上げ INCF MIN10,F MOVF MIN10,W SUBLW D'6' BTFSS STATUS,Z GOTO INCMINS ; CLRF MIN10 ; 00分に戻る BSF FLG,0 ; 時桁上げフラグ ; INCMINS SWAPF MIN10,W IORWF MIN,W ; BCD変換 MOVWF CLKMIN 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 ;--------------------------------------------------------------------- ; 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 ; ;--------------------------------------------------------------------- ; 時刻 ;--------------------------------------------------------------------- SPEECH CALL SPECH_HOUR CALL WAIT100MS CALL SPECH_MIN RETURN ; ;--------------------------------------------------------------------- ; 時:10の位と、1の位の再生 ;--------------------------------------------------------------------- SPECH_HOUR MOVF CLKHOUR,W ; HOUR(BCD)をバイナリにする CALL BCD2BIN MOVWF TMP MOVLW D'12' ; 24H→12Hに変換 SUBWF TMP,W BTFSS STATUS,C MOVF TMP,W ; 12を引く前の値 CALL SPECH RETURN ; ;--------------------------------------------------------------------- ; 分:10の位と、1の位の再生 ;--------------------------------------------------------------------- SPECH_MIN MOVF CLKMIN,W ANDLW H'0F' BTFSC STATUS,Z ; 1分の桁が0なら、 GOTO SPECH_MIN10 ; 10分刻みの発声 ; SWAPF CLKMIN,W ANDLW H'0F' BTFSC STATUS,Z ; 10分の桁が0なら、1分の桁の音声のみ GOTO SPECH_MIN1 ADDLW D'20' ; 10分の音声オフセット CALL SPECH ; じゅう、にじゅう、、、 CALL WAIT10MS ; 間をとる SPECH_MIN1 MOVF CLKMIN,W ANDLW H'0F' ADDLW D'11' ; 1分の音声オフセット CALL SPECH ; いっぷん、にふん、、、 RETURN ; SPECH_MIN10 SWAPF CLKMIN,W ANDLW H'0F' ADDLW D'26' ; 10分刻み音声オフセット CALL SPECH ; れいふん、じゅっぷん、、、、 RETURN ; ;--------------------------------------------------------------------- ; クロックモジュール初期化 ;--------------------------------------------------------------------- ; ORG H'0100' INTCLK CALL BYTEWRITEC ; Clock Module書き込み開始 ; MOVLW D'16' MOVWF CNT CLRF OFFSET INTCLKL CALL INTCLKD ; 書き込みデータ取得 MOVWF datao CALL TX ; 書き込み INCF OFFSET,F DECFSZ CNT,F GOTO INTCLKL CALL WRTTERM RETURN ; INTCLKD ; 初期化データ MOVLW H'01' MOVWF PCLATH MOVF OFFSET,W ADDWF PCL,F ; RETLW B'00000000' ; 0x00番地 Control 1 RETLW B'00000000' ; 0x01番地 Control 2 RETLW B'00000000' ; 0x02番地 Seconds(00秒) RETLW B'00000000' ; 0x03番地 Minutes(00分) RETLW B'00010010' ; 0x04番地 Hours(12時) RETLW B'00000001' ; 0x05番地 Days(1日) RETLW B'00000101' ; 0x06番地 Weekdays(金曜) RETLW B'00000100' ; 0x07番地 Months/Century(4月) RETLW B'00010001' ; 0x08番地 Years(11年) RETLW B'00000000' ; 0x09番地 Minutes Alarm RETLW B'00000000' ; 0x0A番地 Hour Alarm RETLW B'00000000' ; 0x0B番地 Day Alarm RETLW B'00000000' ; 0x0C番地 Weekday alarm RETLW B'00000000' ; 0x0D番地 CLOCKOUT frequency RETLW B'00000000' ; 0x0E番地 Timer control RETLW B'00000000' ; 0x0F番地 Timer ;--------------------------------------------------------------------- ; クロックモジュールへ時刻設定 ;--------------------------------------------------------------------- WRTCLK CALL BYTEWRITEC ; Clock Module書き込み開始 ; MOVLW B'00100000' ; Control 1 STOP BIT=1 MOVWF datao CALL TX ; 書き込み ; CLRF datao ; Control 2 CALL TX ; 書き込み ; CLRF datao ; Secounds CALL TX ; 書き込み ; MOVF CLKMIN,W ; Minutes MOVWF datao CALL TX ; 書き込み ; MOVF CLKHOUR,W ; Hour MOVWF datao CALL TX ; 書き込み CALL WRTTERM ; CALL BYTEWRITEC ; Clock Module書き込み開始 ; MOVLW B'00000000' ; Control 1 STOP BIT=0 ; カウント開始 MOVWF datao CALL TX ; 書き込み CALL WRTTERM ;--------------------------------------------------------------------- ; クロックモジュール読み出し ;--------------------------------------------------------------------- READCLK CALL BYTEREADC ; Clock Module読み込み開始 ; CALL RX ; control 1 読み込み CALL ACK MOVF datai,W MOVWF CLKCTL1 ; CALL RX ; control 2 読み込み CALL ACK MOVF datai,W MOVWF CLKCTL2 ; CALL RX ; secounds 読み込み CALL ACK MOVF datai,W ANDLW H'7F' MOVWF CLKSEC ; CALL RX ; minutes 読み込み CALL ACK MOVF datai,W ANDLW H'7F' MOVWF CLKMIN ; CALL RX ; hour 読み込み MOVF datai,W ANDLW H'3F' MOVWF CLKHOUR ; CALL RDTERM RETURN ;--------------------------------------------------------------------- ; 再生(Wレジでwavの番号を渡す) ;--------------------------------------------------------------------- SPECH CALL GETINDX ; インデックスを読み込む(アドレスがADDRH,ADDRLに返る) CALL BYTEREAD ; バイトリード SPECHL CALL ACK CALL WAIT10US ; 再生速度調整 CALL SETDUTY CALL RX ; シーケンシャルリード MOVF datai,F ; 終了確認 BTFSS STATUS,Z GOTO SPECHL ; ターミネータ0x00まで繰り返す CALL RDTERM ; 読み込み完了 ; MOVLW D'80' MOVWF datai CALL SETDUTY BCF GPIO,2 RETURN ; ;--------------------------------------------------------------------- ; WAV振幅をPWMのデューティへ設定 ;--------------------------------------------------------------------- SETDUTY MOVF datai,W 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 ; 上位アドレスクリア BCF ADDRH1,0 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 BCF STATUS,C RLF ADDRL,F RLF ADDRH,F BCF ADDRH1,0 BTFSC STATUS,C BSF ADDRH1,0 ; 最上位アドレス 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 (2 us) goto $+1 ; 2-inst. cycle delay (2 us) endm THDSTA macro ; Start condition hold time delay (5 us) goto $+1 ; 2-inst. cycle delay (2 us) goto $+1 ; 2-inst. cycle delay (2 us) endm TSUSTA macro ; Start condition setup time delay (5 us) goto $+1 ; 2-inst. cycle delay (2 us) goto $+1 ; 2-inst. cycle delay (2 us) endm TSUSTO macro ; Stop condition setup time delay (5 us) goto $+1 ; 2-inst. cycle delay (2 us) goto $+1 ; 2-inst. cycle delay (2 us) endm TAA macro ; Output valid from clock delay (4 us) goto $+1 ; 2-inst. cycle delay (2 us) nop ; 1-inst. cycle delay (1 us) 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 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 ;------------------------------------------------------------------- ; クロックモジュールアクセス ;------------------------------------------------------------------- WRITE_ADDRC equ b'10100010' ; Control byte for write operations READ_ADDRC equ b'10100011' ; Control byte for read operations BYTEWRITEC movlw .8 movwf bytecount ; Initialize counter to 16 bytes txbyte call BSTART ; Generate start bit ; Now send the control byte ; for a write, to set address movlw WRITE_ADDRC movwf datao ; Copy control byte to buffer call TX ; Output control byte to device ; Next, the address pointer clrf datao ; 0x00アドレス call TX ; Output address to device RETURN WRTTERM CALL NOACK call BSTOP ; Generate stop bit RETURN ; BYTEREADC movlw .8 movwf bytecount ; Initialize counter to 16 bytes rxbytec call BSTART ; Generate start bit ; Now send the control byte ; for a write, to set address movlw WRITE_ADDRC movwf datao ; Copy control byte to buffer call TX ; Output control byte to device clrf datao ; 0x00アドレス call TX ; Output address to device call BSTART ; Generate another start bit ; to switch to read mode movlw READ_ADDRC movwf datao ; Copy control byte to buffer call TX ; Output control byte to device ; Finally, read the data byte RETURN ;--------------------------------------------------------------------- END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------