;--------------------------------------------------------------------- ; フリスクUSB電力計 ; 2013.8.18 naka ; V2 2014.2.1 naka ; V3 2014.6.18 naka ; V3.1 2014.7.19 naka ; V3.1:修正 ; ・電圧、電流の平均値を求める際、四捨五入のために+5していたが、 ; 8で割るので+4に修正(ご指摘頂きました) ; ; V3:以下の機能追加・修正 ; ・零点調整機能を追加(負荷なしのときに0mAとなるよう自動調整) ; ・表示モードに電流が流れるアニメ表示追加 ; ・遅延時間算出にバグがあった(実害なし) ので修正(clockを勘違いしていた) ; ; V2:電流測定の調整 ; ・負荷なしのときに0mAとなるようにした ; ・手持ちテスターと比べ若干小さかった値をほぼ同じになるよう調整 ; ; 機能 ; USBホスト(給電側)とUSB機器(負荷側)の間に入れて、 ; 電圧(V)、電流(mA)、電力(W)、累積電力(Wh)、累積電流(mAh)、経過時間を ; 測定し、表示。 ; USB充電などの用途を想定しているので、経過時間は100時間まで、電流は ; 最大2.5A程度。ただし、最大電流では24時間程度まで。 ; ; (1). 電圧 x.xx V 最大5.8V(参考:USB規格は4.75V - 5.25V) ; (2). 電流 xxxxxmA 最大2.5A(参考:USB2.0は0.5A, USB3.1は1A, iPad充電器は2.5A) ; (3). 電力 xx.xxxW 5Vx2.5A = 12.500W ; (4). 累積電力 xxx.xxWh 12.5Wx24h=300.00Wh ; (5). 累積電流 xxxxxmAh 2.5Ax24h =60000mAh (内部16ビットなので65535でoverflow) ; (6). 経過時間 hh:mm:ss ; ; 表示モード切替 ; 電圧 | 電圧 | 経過時間 | 経過時間 |電流アニメ|コントラスト| 零点調整 ; 電流 | 電力 | 累積電力 | 累積電流 | (※) | 設定 | (※) ; ------------+---------+----------+----------+----------+------------+---------- ; LCD1行目 x.xxV | x.xxV | hh:mm:ss | hh:mm:ss | >>> | Contrast | Zero ; LCD2行目 xxxxxmA | xx.xxxW | xxx.xxWh | xxxxxmAh | | Setting | Adjust ; ; ※V3追加機能 ; ; I/Oポート ; (1). 入力ポート ; AN6(RC2): 電圧測定用 ; AN7(RC3): 電流測定用(実際に測定するのは電圧) ; RC4: モード切替SW ; (2). I2C(LCD接続) ; SCL(RC0), SDA(RC1) ; (3). OSCポート(X'TAL) ; OSC1(RA5),OSC2(RA4) 9.216MHz X'Tal ; (4). Program ; ICSPDAT(RA0), ICSPCLK(RA1) ; VPP(RA3) ; (5). 空き ; RA2 ; ; 使い方 ; USBホスト側(ACアダプタ等、電力供給側)に接続(通電)すると測定開始。 ; モードスイッチで表示を切り替えできる。どのモードで表示していても ; 経過時間と測定は継続しつづける。 ; USBホスト側から外す(非通電)と累積電流、電力、時間は消える。 ; ただし、最後に表示していたモードとコントラスト設定値とは記憶し、次回 ; の通電時はその値で動作開始。 ; ; モードスイッチ長押しでコントラスト設定モードになり、Contrast Setting ; を表示する。このモード時、スイッチを押すとコントラストが変わる。 ; 段階的に濃くなったあと、薄くなる(サイクリックに変わる)。 ; コントラスト設定モードを抜けるには、スイッチの長押し。 ; ; 負荷をつながずにUSB給電を開始する際にタクトスイッチを押していると、 ; Zero Adjustが表示され零点調整が行われる。約1秒後に調整が管理用し、 ; 表示が消える。 ; ; 補足 ; 電圧、電流の測定(AD変換)は毎秒8回行い、平均値をその1秒間の値としている。 ; LCD表示更新は1秒毎に行う。 ; 電力は毎秒の平均値の電圧と電流を乗じて求めている(USBの5V固定ではない)。 ; Wh, mAh 値は毎秒の累積値を3600秒(60秒 x 60分)で割った値。 ; ; 注意 ; ・大電流で長時間通電しっぱなしにすると内部のレジスタがオーバーフローし、 ; 正しい値を表示しない。2.5Aで24時間(通常あり得ないと思う)が限度。 ; ・電流測定用のシャント抵抗は40mΩなので2.5Aで0.1Vの電圧降下がある。 ; オームの法則 E=IR → 0.04Ω x 2.5A = 0.1V ; その他、USBケーブルの抵抗、USBコネクタの接触抵抗、銅箔パターンの抵抗など ; による電圧降下も見込まれる。 ; ・微少電流(25mA程度まで)は電流測定が正しく測定できない。 ; また総じて電流値(電力も同様)はそれほど精度が高くない ; (そんなにひどくもないが)。 ; ;--------------------------------------------------------------------- LIST P=PIC16F1823 INCLUDE "P16F1823.INC" __CONFIG _CONFIG1, _CPD_OFF & _CP_OFF & _BOREN_ON & _MCLRE_OFF & _PWRTE_ON & _WDTE_OFF & _FOSC_XT & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF __CONFIG _CONFIG2, _WRT_OFF & _PLLEN_OFF & _STVREN_ON & _LVP_OFF ERRORLEVEL -302 ;アセンブル時のバンク警告メッセージ抑制 ;--------------------------------------------------------------------- ; 変数レジスタの定義 ;--------------------------------------------------------------------- LCDBUF1 EQU 20H ; LCDバッファ1行目(8バイト) LCDBUF2 EQU 28H ; LCDバッファ2行目(8バイト) SECCNTLO EQU 30H ; 1秒を数えるカウンタ SECCNTHI EQU 31H ; SEC8CNT EQU 32H ; 1/8秒を数えるカウンタ(約1/8秒毎にAD変換) HOUR EQU 33H ; 時 MIN EQU 34H ; 分 SEC EQU 35H ; 秒 CNT EQU 36H ; カウンタ CNT1 EQU 37H ; WAIT用カウンタ CNT2 EQU 38H ; WAIT用カウンタ TMP EQU 39H ; 一時作業用 SECFLG EQU 3AH ; 0:秒フラグ, 1:1/8秒フラグ SWFLG EQU 3BH ; スイッチ状態フラグ ; 0:今の状態, 1:前回, 2:長押し SWLCNTLO EQU 3CH ; SW長押しカウンタ SWLCNTHI EQU 3DH ; CNTRST EQU 3EH ; コントラスト MODE EQU 3FH ; 表示モード PREVMODE EQU 40H ; 表示モード記憶用 ; CURLO EQU 41H ; 電流(mA) max 2500mA程度 CURHI EQU 42H ; VOLTLO EQU 43H ; 電圧(10mV) 5V = 500; 表示時に小数点移動 VOLTHI EQU 44H ; POWERLO EQU 45H ; 電力(mA*10mV) 最大2500mA*500 →積算時には100で割り、mWs POWERHI EQU 46H ; SUMVLTLO EQU 47H ; 毎秒の平均電圧計算用 SUMVLTHI EQU 48H ; SUMCURLO EQU 49H ; 毎秒の平均電流計算用 SUMCURHI EQU 4AH ; INTGCUR0 EQU 4BH ; MSB 積算電流(mAs) 表示時にmAhに変換 INTGCUR1 EQU 4CH ; INTGCUR2 EQU 4DH ; INTGCUR3 EQU 4EH ; LSB INTGPWR0 EQU 4FH ; MSB 積算電力(mWs) 表示時にWhに変換 INTGPWR1 EQU 50H ; INTGPWR2 EQU 51H ; INTGPWR3 EQU 52H ; LSB ;-------------------------------------------------------------------------- ; binariy to BCD変換用 ;-------------------------------------------------------------------------- bin EQU 53H hundreds EQU 54H tens_and_ones EQU 55H binH EQU 56H binL EQU 57H bcdH EQU 58H bcdM EQU 59H bcdL EQU 5AH counter EQU 5BH temp EQU 5CH ; 重複(同時に使わない) TEMP EQU 5CH ; 〃 ;-------------------------------------------------------------------------- ; 乗算用 ;-------------------------------------------------------------------------- ACCaLO equ 5DH ACCaHI equ 5EH ACCbLO equ 5FH ACCbHI equ 60H ACCcLO equ 61H ACCcHI equ 62H ACCdLO equ 63H ACCdHI equ 64H ;-------------------------------------------------------------------------- ; 除算用 ;-------------------------------------------------------------------------- AARGB0 EQU 65H AARGB1 EQU 66H AARGB2 EQU 67H AARGB3 EQU 68H BARGB0 EQU 69H BARGB1 EQU 6AH REMB0 EQU 6BH REMB1 EQU 6CH LOOPCOUNT EQU 6DH ;-------------------------------------------------------------------------- CNT3 EQU 6EH PATNO EQU 6FH ;-------------------------------------------------------------------------- ; どのバンクからも読み書きできる領域 ;-------------------------------------------------------------------------- DATA_EE_ADDR EQU 70H DATA_EE_DATA EQU 71H ADVLTHI EQU 72H ; AD変換結果(電圧) ADVLTLO EQU 73H ; ADCURHI EQU 74H ; AD変換結果(電流) ADCURLO EQU 75H ; WK EQU 76H WAITCNT EQU 77H ANMSPEED EQU 78H CNTANMINT EQU 79H ; アニメーション用インターバルカウンタ ZADJVAL EQU 7AH ; ;-------------------------------------------------------------------------- ; EEPROM ;-------------------------------------------------------------------------- ORG H'F000' ; EEPROM byte address=1E000 -> word addr=F000 DE D'0' ; 表示モード(0-5) DE D'32' ; コントラスト(0-63の真ん中;電源電圧やLCDモジュールの個体差に依存) DE D'0' ; 零点調整値 ;--------------------------------------------------------------------- ; リセット・割り込み ;--------------------------------------------------------------------- ORG 00H ; リセット時の飛び込み先 RESET1 GOTO MAIN ; 初期設定へ ; ;--------------------------------------------------------------------- ; 割り込み処理 888.9usec毎 ; (9.216MHz/4/256/8=1125回で1秒)で時間をカウント ;--------------------------------------------------------------------- ORG 04H ; 割り込み時の飛び込み先 INTRUPT BTFSS INTCON,TMR0IF ; Timer0割り込みか? RETFIE ; 違えば即リターン ; BCF INTCON,TMR0IF ;割り込みフラグリセット ; MOVLW D'1' ADDWF SECCNTLO,F ; 秒をカウント CLRW ADDWFC SECCNTHI,F ; INCF SEC8CNT,F ; MOVF SEC8CNT,W SUBLW D'139' ; 約1/8秒 889us*139 = 0.124s BTFSC STATUS,Z CALL CHKVOLT ; 電圧測定 ; MOVF SEC8CNT,W SUBLW D'140' ; 約1/8秒 140 BTFSS STATUS,Z GOTO CHKSEC ; CALL CHKCUR ; 電流測定 BSF SECFLG,1 ; 約1/8秒フラグ(電圧、電流測定完)セット CLRF SEC8CNT ; CHKSEC INCF CNTANMINT,F MOVF CNTANMINT,W SUBLW D'22' ; 矢印アニメのために20ms毎にフラグを立てる BTFSS STATUS,Z GOTO CHKSEC2 BSF SECFLG,2 CLRF CNTANMINT ; CHKSEC2 MOVF SECCNTLO,W SUBLW H'65' ; 1125=H'465' BTFSS STATUS,Z GOTO CHKSWPORT MOVF SECCNTHI,W SUBLW H'04' BTFSS STATUS,Z GOTO CHKSWPORT ; BSF SECFLG,0 ; 秒フラグセット CLRF SECCNTLO CLRF SECCNTHI CLRF SEC8CNT ; 1/8秒カウンタもクリア ; CHKSWPORT ; SWの状態チェック BTFSC PORTC,4 ; mode L:押された GOTO SWOFF ; BSF SWFLG,1 ; SWの状態 ON MOVLW D'1' ADDWF SWLCNTLO,F ; 長押しカウント CLRW ADDWFC SWLCNTHI,F ; MOVF SWLCNTHI,W SUBLW D'4' ; (889us*256*4=0.91sec) BTFSS STATUS,Z RETFIE BSF SWFLG,2 ; 長押しフラグセット CLRF SWLCNTLO CLRF SWLCNTHI RETFIE SWOFF BTFSS SWFLG,1 ; 前回は押されていた? RETFIE BSF SWFLG,0 ; SWが押されたフラグ BCF SWFLG,1 ; SWの状態 CLRF SWLCNTLO CLRF SWLCNTHI RETFIE ;--------------------------------------------------------------------- ; 初期化 ;--------------------------------------------------------------------- INIT BCF INTCON,GIE ;全割込み禁止 ; BANKSEL TRISC MOVLW B'00011111' MOVWF TRISC ; RC0:SCL, RC1:SDA, RC2:analog, RC3:analog, RC4:inc BANKSEL LATC CLRF LATC BANKSEL ANSELC MOVLW B'00001100' ; RC2,RC3 Analog MOVWF ANSELC ; BANKSEL ADCON1 ; MOVLW B'10010011' ;Right justify, Frc (Fosc/8) , FVR MOVWF ADCON1 ;Vref = FVR module BANKSEL FVRCON MOVLW B'10000001' ; 1.024V MOVWF FVRCON BANKSEL OPTION_REG MOVLW H'82' ;プリスケーラを1:8にする MOVWF OPTION_REG ; ;clock9.216MHz/4/256/8=1125Hz 約0.88ms ;1125回の割り込みで1秒をカウント ; BANKSEL PORTC MOVLW H'FF' MOVWF PORTC ; CLRF SECCNTLO CLRF SECCNTHI CLRF SEC8CNT CLRF SEC CLRF MIN CLRF HOUR CLRF SECFLG CLRF SWFLG CLRF SWLCNTLO CLRF SWLCNTHI CLRF MODE CLRF PREVMODE CLRF WAITCNT CLRF CNTANMINT CLRF PATNO ; CLRF SUMVLTLO CLRF SUMVLTHI CLRF SUMCURLO CLRF SUMCURHI CLRF INTGCUR0 CLRF INTGCUR1 CLRF INTGCUR2 CLRF INTGCUR3 CLRF INTGPWR0 CLRF INTGPWR1 CLRF INTGPWR2 CLRF INTGPWR3 ; CLRF ZADJVAL ; BSF INTCON,TMR0IE BSF INTCON,GIE ; 割り込み許可 ; RETURN ;--------------------------------------------------------------------- ; メイン処理 ;--------------------------------------------------------------------- MAIN CALL INIT ; 初期化 CALL LDSETTING ; EEPROMセッティング情報読み込み(モード、コントラスト) ; CALL I2CINIT ; I2C初期化 CALL LCDINIT ; LCD初期化 ; BTFSC SWFLG,1 CALL ZEROADJ ; 零点調整 ; CALL BOOTSPLASH ; ブートスプラッシュ ; MAIN_LP CALL DSPARROW CHK_SW BTFSC SWFLG,0 CALL CHGMODE ; モード切替 ; BTFSS SECFLG,1 ; 1/8秒フラグ(電圧、電流測定完了) GOTO CHK_1S ; BCF SECFLG,1 CALL CALCVLT ; 電圧値計算 CALL CALCCUR ; 電流値計算 CALL CALCSPEED CALL SUMVLTCUR ; 平均値を出すための累積 ; CHK_1S BTFSS SECFLG,0 ; 1秒フラグ GOTO MAIN_LP ; BCF SECFLG,0 CALL INCTIM ; 時間カウント CALL AVERAGE ; 電圧・電流の測定値の平均をとる CALL CALCPWR ; 電力計算 CALL INTGRAL ; 積算 CALL DISPLAY ; 表示する(コントラスト設定時は表示しない) GOTO MAIN_LP ; ;--------------------------------------------------------------------- ; 零点調整 ;--------------------------------------------------------------------- ZEROADJ CALL ZADJDSP ; "Zero Adjust"表示 ; MOVLW D'8' MOVWF CNT CLRF ZADJVAL ZADJ_LP BTFSS SECFLG,1 ; 1/8秒フラグ(電圧、電流測定完了) GOTO ZADJ_LP ; BCF SECFLG,1 MOVF ADCURLO,W ; AD変換の最大値を記憶する SUBWF ZADJVAL,W BTFSC STATUS,C GOTO ZADJ_1 MOVF ADCURLO,W MOVWF ZADJVAL ZADJ_1 DECFSZ CNT,F GOTO ZADJ_LP ; CALL SVSETTING ; EEPROMに保存 ; CALL CLRLCD ; LCDクリア CALL LCD1DSP CALL LCD2DSP ; BTFSC SWFLG,1 ; SWが離されるまでループ GOTO $-1 ; BCF SWFLG,0 BCF SWFLG,2 ; 長押しフラグクリア CLRF SWLCNTLO CLRF SWLCNTHI ; RETURN ;--------------------------------------------------------------------- ; 表示モード毎のLCD表示 ;--------------------------------------------------------------------- DISPLAY CALL CLRLCD ; LCDクリア MOVF MODE,W ; 表示モードに応じてジャンプ ADDWF PCL,F GOTO DSPMODE0 ; 電圧・電流表示 GOTO DSPMODE1 ; 電圧・電力表示 GOTO DSPMODE2 ; 経過時間・累積電力表示 GOTO DSPMODE3 ; 経過時間・累積電流表示 GOTO DSPMODE4 ; 電流フローアニメ GOTO DSPMODE5 ; コントラスト設定表示 ; DSPMODE0 ; 電圧、電流表示 CALL VLT2LCD CALL CUR2LCD RETURN DSPMODE1 ; 電力表示 CALL VLT2LCD CALL PWR2LCD RETURN DSPMODE2 ; 経過時間、累積電力表示 CALL TIM2LCD CALL IPWR2LCD RETURN DSPMODE3 ; 経過時間、累積電流表示 CALL TIM2LCD CALL ICUR2LCD RETURN DSPMODE4 ; 電流フローアニメ ; ここではとくに何もしない RETURN DSPMODE5 ; コントラスト設定文字表示 CALL CNSTDSP RETURN ;--------------------------------------------------------------------- ; 表示モード切り替え ;--------------------------------------------------------------------- CHGMODE BCF SWFLG,0 BTFSC SWFLG,2 ; 長押し GOTO SETCNTMODE ; コントラスト設定モード ; MOVF MODE,W SUBLW D'5' ; コントラスト BTFSC STATUS,Z GOTO CNTMODE ; 通常の0-4の5段階 INCF MODE,F MOVF MODE,W SUBLW D'5' BTFSC STATUS,Z CLRF MODE ; CALL DISPLAY ; 切り替えたら即表示変更 CALL SVSETTING RETURN ; SETCNTMODE BCF SWFLG,2 ; 長押しフラグクリア MOVF MODE,W SUBLW D'5' ; 既にコントラスト設定モードなら抜ける BTFSC STATUS,Z GOTO EXITCNTMODE ; MOVF MODE,W ; 今のモードを記憶 MOVWF PREVMODE MOVLW D'5' ; コントラスト設定モードにする MOVWF MODE RETURN ; CNTMODE ; コントラスト設定モード INCF CNTRST,F MOVF CNTRST,W SUBLW D'38' ; CONTRST= 22〜38の間で変化 BTFSS STATUS,Z GOTO CHGCNTRST MOVLW D'22' MOVWF CNTRST CHGCNTRST CALL LCDCNTRST ; コントラスト変更の反映 RETURN EXITCNTMODE MOVF PREVMODE,W ; 元のモードに戻す MOVWF MODE CALL SVSETTING CALL DISPLAY ; 戻したら即表示変更 RETURN ; ;--------------------------------------------------------------------- ; 電圧計算 ; 4.7K + 1.0Kで分圧した電圧の測定 1.0/(4.7+1.0) = 0.175 -> 5.7倍で元の電圧 ;--------------------------------------------------------------------- ; VOLT = (AD結果 * 57 + 50) / 100 = 10mV ; Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,ACCc ( 32 bits ) ; Divid Result: AARG, REM <-- AARG / BARG CALCVLT MOVF ADVLTLO,W MOVWF ACCbLO MOVF ADVLTHI,W MOVWF ACCbHI MOVLW D'57' MOVWF ACCaLO MOVLW D'0' MOVWF ACCaHI CALL D_mpyF ; MOVLW D'50' ADDWF ACCcLO,F MOVLW D'0' ADDWFC ACCcHI,F CLRW ADDWFC ACCbLO,F ADDWFC ACCbHI,F ; MOVF ACCcLO,W MOVWF AARGB3 MOVF ACCcHI,W MOVWF AARGB2 MOVF ACCbLO,W MOVWF AARGB1 MOVF ACCbHI,W MOVWF AARGB0 ; MOVLW D'100' MOVWF BARGB1 MOVLW D'0' MOVWF BARGB0 CALL FXD3216U ; MOVF AARGB3,W MOVWF VOLTLO MOVF AARGB2,W MOVWF VOLTHI RETURN ;--------------------------------------------------------------------- ; 電流計算 ; R3 * ( R1 / R2) * I ; OpAMP Vout = 820 * (0.04/100) * 1 = 0.328V -> 1/0.328 = 3.049 ;--------------------------------------------------------------------- ; CURENT = (AD結果 * 3049 + 500) / 1000 = mA ; Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,ACCc ( 32 bits ) ; Divid Result: AARG, REM <-- AARG / BARG CALCCUR MOVF ADCURHI,F ; AD変換結果が零点調整値以下のときは BTFSS STATUS,Z ; 負荷なしと推測し0に補正する GOTO CALCCUR1 MOVF ADCURLO,W SUBWF ZADJVAL,W BTFSC STATUS,C CLRF ADCURLO ; CALCCUR1 MOVF ADCURLO,W MOVWF ACCbLO MOVF ADCURHI,W MOVWF ACCbHI ; MOVLW H'E9' ; 3049 = H'0BE9' ...計算値 MOVLW H'21' ; 3105 = H'0C21' ...テスタ値と合わせこみ MOVWF ACCaLO ; MOVLW H'0B' MOVLW H'0C' MOVWF ACCaHI CALL D_mpyF ; MOVLW H'F4' ; 500 = H'1F4' ADDWF ACCcLO,F MOVLW H'01' ADDWFC ACCcHI,F CLRW ADDWFC ACCbLO,F ADDWFC ACCbHI,F ; MOVF ACCcLO,W MOVWF AARGB3 MOVF ACCcHI,W MOVWF AARGB2 MOVF ACCbLO,W MOVWF AARGB1 MOVF ACCbHI,W MOVWF AARGB0 ; MOVLW H'E8' ; 1000 = H'03E8' MOVWF BARGB1 MOVLW H'03' MOVWF BARGB0 CALL FXD3216U ; MOVF AARGB3,W MOVWF CURLO MOVF AARGB2,W MOVWF CURHI RETURN ;--------------------------------------------------------------------- ; 電圧、電流の平均を求めるための累積 ;--------------------------------------------------------------------- SUMVLTCUR MOVF VOLTLO,W ADDWF SUMVLTLO,F MOVF VOLTHI,W ADDWFC SUMVLTHI,F ; MOVF CURLO,W ADDWF SUMCURLO,F MOVF CURHI,W ADDWFC SUMCURHI,F RETURN ;--------------------------------------------------------------------- ; 電圧、電流の平均値 ; 1秒毎 ; SUMVOLT/8 ; 四捨五入のために SUMVOLT += 4 ; 8で割るためSUMVOLT を3ビット右シフト ;--------------------------------------------------------------------- AVERAGE ; 1秒の平均電圧を求める MOVLW D'4' ; +4 (四捨五入) ADDWF SUMVLTLO,F CLRW ADDWFC SUMVLTHI,F ; LSRF SUMVLTHI,F ; 1/8 RRF SUMVLTLO,F LSRF SUMVLTHI,F RRF SUMVLTLO,F LSRF SUMVLTHI,F RRF SUMVLTLO,W MOVWF VOLTLO MOVF SUMVLTHI,W MOVWF VOLTHI CLRF SUMVLTLO CLRF SUMVLTHI ; ; 1秒の平均電流を求める MOVLW D'4' ; +4 (四捨五入) ADDWF SUMCURLO,F CLRW ADDWFC SUMCURHI,F ; LSRF SUMCURHI,F ; 1/8 RRF SUMCURLO,F LSRF SUMCURHI,F RRF SUMCURLO,F LSRF SUMCURHI,F RRF SUMCURLO,W MOVWF CURLO MOVF SUMCURHI,W MOVWF CURHI CLRF SUMCURLO CLRF SUMCURHI RETURN ;--------------------------------------------------------------------- ; ブートスプラッシュ文字列表示 ;--------------------------------------------------------------------- BOOTSPLASH MOVLW D'16' MOVWF CNT CLRF TMP ; MOVLW HIGH LCDBUF1 MOVWF FSR1H MOVLW LOW LCDBUF1 MOVWF FSR1L MOVLW H'01' MOVWF PCLATH BOOTSPLASHL CALL BOOTSPLASHDT MOVWF INDF1 ADDFSR FSR1,D'1' INCF TMP,F DECFSZ CNT,F GOTO BOOTSPLASHL CLRF PCLATH ; CALL LCD1DSP ; LCDへ表示 CALL LCD2DSP ; LCDへ表示(2行目) RETURN ; BOOTSPLASHDT MOVF TMP,W ADDWF PCL,F RETLW 'U' RETLW 'S' RETLW 'B' RETLW ' ' RETLW 'W' RETLW 'a' RETLW 't' RETLW 't' RETLW 'M' RETLW 'e' RETLW 't' RETLW 'e' RETLW 'r' RETLW ' ' RETLW 'V' RETLW '3' ;--------------------------------------------------------------------- ; コントラスト文字列表示 ;--------------------------------------------------------------------- CNSTDSP MOVLW D'16' MOVWF CNT CLRF TMP ; MOVLW HIGH LCDBUF1 MOVWF FSR1H MOVLW LOW LCDBUF1 MOVWF FSR1L MOVLW H'01' MOVWF PCLATH CNSTDSPL CALL CNSTDSPDT MOVWF INDF1 ADDFSR FSR1,D'1' INCF TMP,F DECFSZ CNT,F GOTO CNSTDSPL CLRF PCLATH ; CALL LCD1DSP ; LCDへ表示 CALL LCD2DSP ; LCDへ表示(2行目) RETURN CNSTDSPDT MOVF TMP,W ADDWF PCL,F RETLW 'C' RETLW 'o' RETLW 'n' RETLW 't' RETLW 'r' RETLW 'a' RETLW 's' RETLW 't' RETLW ' ' RETLW 'S' RETLW 'e' RETLW 't' RETLW 't' RETLW 'i' RETLW 'n' RETLW 'g' ;--------------------------------------------------------------------- ; 零点調整文字列表示 ;--------------------------------------------------------------------- ZADJDSP MOVLW D'16' MOVWF CNT CLRF TMP ; MOVLW HIGH LCDBUF1 MOVWF FSR1H MOVLW LOW LCDBUF1 MOVWF FSR1L MOVLW H'01' MOVWF PCLATH ZADJDSPL CALL ZADJDSPDT MOVWF INDF1 ADDFSR FSR1,D'1' INCF TMP,F DECFSZ CNT,F GOTO ZADJDSPL CLRF PCLATH ; CALL LCD1DSP ; LCDへ表示 CALL LCD2DSP ; LCDへ表示(2行目) RETURN ZADJDSPDT MOVF TMP,W ADDWF PCL,F RETLW 'Z' RETLW 'e' RETLW 'r' RETLW 'o' RETLW ' ' RETLW ' ' RETLW ' ' RETLW ' ' RETLW ' ' RETLW ' ' RETLW 'A' RETLW 'd' RETLW 'j' RETLW 'u' RETLW 's' RETLW 't' ;--------------------------------------------------------------------- ; 電圧値をLCDに表示(表示位置はFSR1H,Lで指示) ;--------------------------------------------------------------------- VLT2LCD MOVF VOLTLO,W MOVWF binL MOVF VOLTHI,W MOVWF binH CALL _bin2bcd ; MOVF bcdM,W ; 3桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF1+3 ; ADDFSR FSR1,D'1' MOVLW '.' ; 小数点 MOVWF LCDBUF1+4 ; SWAPF bcdL,W ; 2桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF1+5 ; MOVF bcdL,W ; 1桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF1+6 ; MOVLW 'V' ; V MOVWF LCDBUF1+7 ; CALL LCD1DSP ; LCDへ表示 RETURN ; ;--------------------------------------------------------------------- ; 累積電力をLCD 2行目に表示 ; 積算値(10mWs)を、3600で割って10mWh単位にする ; -> 四捨五入のために1800加算してから3600で割る ; 小数点を2つ左に移動して、xxx.xxWh 表示 ;--------------------------------------------------------------------- IPWR2LCD MOVF INTGPWR3,W MOVWF AARGB3 MOVF INTGPWR2,W MOVWF AARGB2 MOVF INTGPWR1,W MOVWF AARGB1 MOVF INTGPWR0,W MOVWF AARGB0 ; MOVLW H'08' ; 四捨五入のために1800加算 ADDWF AARGB3,F ; 1800 = H'708' MOVLW H'07' ADDWFC AARGB2,F CLRW ADDWFC AARGB1,F ADDWFC AARGB0,F ; MOVLW H'10' ; 3600で割る MOVWF BARGB1 ; 3600 = H'0E10' MOVLW H'0E' MOVWF BARGB0 CALL FXD3216U ; MOVF AARGB3,W MOVWF binL MOVF AARGB2,W MOVWF binH CALL _bin2bcd ; BSF TMP,0 ; ゼロサプレスフラグ ; MOVF bcdH,W ; 5桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO IPWR_4 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2 ; IPWR_4 SWAPF bcdM,W ; 4桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO IPWR_3 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+1 ; IPWR_3 MOVF bcdM,W ; 3桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+2 ; MOVLW '.' ; 小数点 MOVWF LCDBUF2+3 ; SWAPF bcdL,W ; 2桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+4 ; MOVF bcdL,W ; 1桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+5 ; MOVLW 'W' ; W MOVWF LCDBUF2+6 ; MOVLW 'h' ; h MOVWF LCDBUF2+7 ; CALL LCD2DSP ; LCDへ表示 RETURN ;--------------------------------------------------------------------- ; 累積電流をLCD 2行目に表示 ; 積算値(mAs)を3600で割ってmAh単位にする ; -> 四捨五入のために1800加算してから3600で割る ; 最大65535mAhまで(2.5Aだと26.214hまで) ;--------------------------------------------------------------------- ICUR2LCD MOVF INTGCUR3,W MOVWF AARGB3 MOVF INTGCUR2,W MOVWF AARGB2 MOVF INTGCUR1,W MOVWF AARGB1 MOVF INTGCUR0,W MOVWF AARGB0 ; MOVLW H'08' ; 四捨五入のために1800加算 ADDWF AARGB3,F ; 1800 = H'708' MOVLW H'07' ADDWFC AARGB2,F CLRW ADDWFC AARGB1,F ADDWFC AARGB0,F ; MOVLW H'10' ; 3600で割る MOVWF BARGB1 ; 3600 = H'E10' MOVLW H'0E' MOVWF BARGB0 CALL FXD3216U ; MOVF AARGB3,W MOVWF binL MOVF AARGB2,W MOVWF binH CALL _bin2bcd ; BSF TMP,0 ; ゼロサプレスフラグ ; MOVF bcdH,W ; 5桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO ICUR_4 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2 ; ICUR_4 SWAPF bcdM,W ; 4桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO ICUR_3 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+1 ; ICUR_3 MOVF bcdM,W ; 3桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO ICUR_2 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+2 ; ICUR_2 SWAPF bcdL,W ; 2桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO ICUR_1 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+3 ; ICUR_1 MOVF bcdL,W ; 1桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+4 ; MOVLW 'm' ; MOVWF LCDBUF2+5 ; MOVLW 'A' ; MOVWF LCDBUF2+6 ; MOVLW 'h' ; MOVWF LCDBUF2+7 ; CALL LCD2DSP ; LCDへ表示 RETURN ;--------------------------------------------------------------------- ; 電力値(XX.XXW)をLCD 2行目に表示 ; 計算値の10mW単位を小数点を2つ左に移動して W 表示 ;--------------------------------------------------------------------- PWR2LCD MOVF POWERLO,W MOVWF binL MOVF POWERHI,W MOVWF binH CALL _bin2bcd ; SWAPF bcdM,W ; 4桁目 ANDLW H'0F' BTFSC STATUS,Z ; ゼロサプレス確認 GOTO PWR_3 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+2 ; PWR_3 MOVF bcdM,W ; 3桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+3 ; MOVLW '.' ; 小数点 MOVWF LCDBUF2+4 ; SWAPF bcdL,W ; 2桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+5 ; MOVF bcdL,W ; 1桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+6 ; MOVLW 'W' ; MOVWF LCDBUF2+7 ; CALL LCD2DSP ; LCDへ表示 RETURN ;--------------------------------------------------------------------- ; 電流値(5桁:XXXXXmA)をLCD 2行目に表示 ;--------------------------------------------------------------------- CUR2LCD MOVF CURLO,W MOVWF binL MOVF CURHI,W MOVWF binH CALL _bin2bcd ; BSF TMP,0 ; ゼロサプレスフラグ ; MOVF bcdH,W ; 5桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO CUR_4 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+1 ; CUR_4 SWAPF bcdM,W ; 4桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO CUR_3 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+2 ; CUR_3 MOVF bcdM,W ; 3桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO BCD2LCD_2 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+3 ; BCD2LCD_2 SWAPF bcdL,W ; 2桁目 ANDLW H'0F' BTFSS STATUS,Z ; ゼロサプレス確認 BCF TMP,0 ; ゼロサプレスフラグ・クリア BTFSC TMP,0 GOTO BCD2LCD_1 ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+4 ; BCD2LCD_1 MOVF bcdL,W ; 1桁目 ANDLW H'0F' ADDLW H'30' ; 文字コード化 MOVWF LCDBUF2+5 ; MOVLW 'm' MOVWF LCDBUF2+6 ; MOVLW 'A' MOVWF LCDBUF2+7 ; CALL LCD2DSP ; LCDへ表示 RETURN ;--------------------------------------------------------------------- ; USB電圧測定;実際には5Vを分圧した1V前後を測定 ;--------------------------------------------------------------------- CHKVOLT BANKSEL ADCON0 ; MOVLW B'00011001' ;Select channel AN6 MOVWF ADCON0 ;Turn ADC On CALL WCHARGE ;Acquisiton delay BSF ADCON0,ADGO ;Start conversion BTFSC ADCON0,ADGO ;Is conversion done? GOTO $-1 ;No, test again BANKSEL ADRESH ; MOVF ADRESH,W ;Read upper 2 bits ANDLW B'00000011' MOVWF ADVLTHI ;store in GPR space BANKSEL ADRESL ; MOVF ADRESL,W ;Read lower 8 bits MOVWF ADVLTLO BANKSEL 0 RETURN ; WCHARGE MOVLW D'13' ; 44usec MOVWF CNT WCHGLP DECFSZ CNT,F GOTO WCHGLP RETURN ;--------------------------------------------------------------------- ; 電流測定(Op-ampの出力電圧測定) ;--------------------------------------------------------------------- CHKCUR BANKSEL ADCON0 ; MOVLW B'00011101' ;Select channel AN7 MOVWF ADCON0 ;Turn ADC On CALL WCHARGE ;Acquisiton delay BSF ADCON0,ADGO ;Start conversion BTFSC ADCON0,ADGO ;Is conversion done? GOTO $-1 ;No, test again BANKSEL ADRESH ; MOVF ADRESH,W ;Read upper 2 bits ANDLW B'00000011' MOVWF ADCURHI ;store in GPR space BANKSEL ADRESL ; MOVF ADRESL,W ;Read lower 8 bits MOVWF ADCURLO BANKSEL 0 RETURN ; ;--------------------------------------------------------------------- ; 電力計算 ; POWER = (VOLT * CURENT + 500) / 1000 = 10mWs単位 ; Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,ACCc ( 32 bits ) ; Divid Result: AARG, REM <-- AARG / BARG ;--------------------------------------------------------------------- CALCPWR MOVF VOLTLO,W MOVWF ACCbLO MOVF VOLTHI,W MOVWF ACCbHI ; MOVF CURLO,W MOVWF ACCaLO MOVF CURHI,W MOVWF ACCaHI CALL D_mpyF ; MOVLW H'F4' ; 500=H'1F4' ADDWF ACCcLO,F MOVLW H'01' ADDWFC ACCcHI,F CLRW ADDWFC ACCbLO,F ADDWFC ACCbHI,F ; MOVF ACCcLO,W MOVWF AARGB3 MOVF ACCcHI,W MOVWF AARGB2 MOVF ACCbLO,W MOVWF AARGB1 MOVF ACCbHI,W MOVWF AARGB0 ; MOVLW H'E8' ; 1000=H'3E8' MOVWF BARGB1 MOVLW H'03' MOVWF BARGB0 CALL FXD3216U ; MOVF AARGB3,W MOVWF POWERLO MOVF AARGB2,W MOVWF POWERHI RETURN ;--------------------------------------------------------------------- ; 電流及び電力積算 ;--------------------------------------------------------------------- INTGRAL ; 電流の積算 MOVF CURLO,W ADDWF INTGCUR3,F MOVF CURHI,W ADDWFC INTGCUR2,F CLRW ADDWFC INTGCUR1,F ADDWFC INTGCUR0,F ; ; 電力の積算 MOVF POWERLO,W ADDWF INTGPWR3,F MOVF POWERHI,W ADDWFC INTGPWR2,F CLRW ADDWFC INTGPWR1,F ADDWFC INTGPWR0,F RETURN ; ;--------------------------------------------------------------------- ; 設定情報の読み出し ;--------------------------------------------------------------------- LDSETTING CLRF DATA_EE_ADDR CALL RDEEPROM ; EEPROM読み出し MOVWF MODE ; 表示モード INCF DATA_EE_ADDR,F CALL RDEEPROM ; EEPROM読み出し MOVWF CNTRST ; コントラスト INCF DATA_EE_ADDR,F CALL RDEEPROM ; EEPROM読み出し MOVWF ZADJVAL ; 零点調整値 RETURN ; ;--------------------------------------------------------------------- ; 設定情報の書き込み ;--------------------------------------------------------------------- SVSETTING MOVLW H'00' ; EEPROM先頭アドレス MOVWF DATA_EE_ADDR MOVF MODE,W ; 表示モード MOVWF DATA_EE_DATA CALL WRTEEPROM ; EEPROM書き込み ; INCF DATA_EE_ADDR,F MOVF CNTRST,W ; コントラスト MOVWF DATA_EE_DATA CALL WRTEEPROM ; EEPROM書き込み ; INCF DATA_EE_ADDR,F MOVF ZADJVAL,W ; 零点調整値 MOVWF DATA_EE_DATA CALL WRTEEPROM ; EEPROM書き込み RETURN ; ;--------------------------------------------------------------------- ; LCDバッファクリア ;--------------------------------------------------------------------- CLRLCD MOVLW D'16' MOVWF CNT ; MOVLW HIGH LCDBUF1 MOVWF FSR1H MOVLW LOW LCDBUF1 MOVWF FSR1L CLRLCDL MOVLW ' ' MOVWF INDF1 ADDFSR FSR1,D'1' DECFSZ CNT,F GOTO CLRLCDL RETURN ;--------------------------------------------------------------------- ; コントラスト設定 ;--------------------------------------------------------------------- LCDCNTRST MOVLW H'39' CALL LCDCMD MOVF CNTRST,W ANDLW H'0F' ; 下位4ビット IORLW H'70' CALL LCDCMD SWAPF CNTRST,W ANDLW H'03' ; 上位2ビット IORLW H'54' CALL LCDCMD MOVLW H'38' CALL LCDCMD RETURN ;--------------------------------------------------------------------- ; 秒分時のカウントアップ ;--------------------------------------------------------------------- INCTIM BCF SECFLG,0 ; 1秒フラグクリア ; INCF SEC,F MOVF SEC,W SUBLW D'60' ; 60秒 BTFSS STATUS,Z RETURN CLRF SEC INCF MIN,F MOVF MIN,W SUBLW D'60' ; 60分 BTFSS STATUS,Z RETURN CLRF MIN INCF HOUR,F MOVF HOUR,W SUBLW D'100' ; 100分 BTFSC STATUS,Z CLRF HOUR RETURN ; ;--------------------------------------------------------------------- ; LCDの1行目に経過時間を表示 ;--------------------------------------------------------------------- TIM2LCD MOVF HOUR,W MOVWF bin CALL binary_to_bcd ; SWAPF tens_and_ones,W ANDLW H'0F' ; ADDLW H'30' ; ASCIIコード化 MOVWF LCDBUF1 ; MOVF tens_and_ones,W ANDLW H'0F' ; ADDLW H'30' ; ASCIIコード化 MOVWF LCDBUF1+1 ; MOVLW ':' MOVWF LCDBUF1+2 ; MOVF MIN,W MOVWF bin CALL binary_to_bcd ; SWAPF tens_and_ones,W ANDLW H'0F' ; ADDLW H'30' ; ASCIIコード化 MOVWF LCDBUF1+3 ; MOVF tens_and_ones,W ANDLW H'0F' ; ADDLW H'30' ; ASCIIコード化 MOVWF LCDBUF1+4 ; MOVLW ':' MOVWF LCDBUF1+5 ; MOVF SEC,W MOVWF bin CALL binary_to_bcd ; SWAPF tens_and_ones,W ANDLW H'0F' ; ADDLW H'30' ; ASCIIコード化 MOVWF LCDBUF1+6 ; MOVF tens_and_ones,W ANDLW H'0F' ; ADDLW H'30' ; ASCIIコード化 MOVWF LCDBUF1+7 ; CALL LCD1DSP ; LCD 1行目に表示 RETURN ; ;--------------------------------------------------------------------- ; LCDへコマンド・データ転送 ;--------------------------------------------------------------------- LCD1DSP MOVLW H'80' + H'00' ; 1行目先頭へ CALL LCDCMD ; MOVLW D'8' MOVWF CNT MOVLW LOW LCDBUF1 MOVWF FSR1L MOVLW HIGH LCDBUF1 MOVWF FSR1H ; LCD1DSPL MOVF INDF1,W CALL LCDDATA ADDFSR FSR1,D'1' DECFSZ CNT,F GOTO LCD1DSPL ; RETURN ;--------------------------------------------------------------------- ; LCDへコマンド・データ転送 ;--------------------------------------------------------------------- LCD2DSP MOVLW H'80' + H'40' ; 1行目先頭へ CALL LCDCMD ; MOVLW D'8' MOVWF CNT MOVLW LOW LCDBUF2 MOVWF FSR1L MOVLW HIGH LCDBUF2 MOVWF FSR1H ; LCD2DSPL MOVF INDF1,W CALL LCDDATA ADDFSR FSR1,D'1' DECFSZ CNT,F GOTO LCD2DSPL ; RETURN ;--------------------------------------------------------------------- ; EEPROM読み出し ;--------------------------------------------------------------------- RDEEPROM BANKSEL EEADRL; MOVF LOW DATA_EE_ADDR,W ; MOVWF EEADRL ; Data Memory ; Address to read BCF EECON1,CFGS ; Deselect Config space BCF EECON1,EEPGD ; Point to DATA memory BSF EECON1,RD ; EE Read MOVF EEDATL,W ; W = EEDATL BANKSEL 0 RETURN ;--------------------------------------------------------------------- ; EEPROM書き込み ;--------------------------------------------------------------------- WRTEEPROM BANKSEL EEADRL ; MOVF DATA_EE_ADDR,W ; MOVWF EEADRL ; Data Memory Address to write MOVF DATA_EE_DATA,W ; MOVWF EEDATL ; Data Memory Value to write BCF EECON1,CFGS ; Deselect Configuration space BCF EECON1,EEPGD ; Point to DATA memory BSF EECON1,WREN ; Enable writes BCF INTCON,GIE ; Disable INTs. MOVLW 55h ; MOVWF EECON2 ; Write 55h MOVLW 0AAh ; MOVWF EECON2 ; Write AAh BSF EECON1,WR ; Set WR bit to begin write BSF INTCON,GIE ; Enable Interrupts BCF EECON1,WREN ; Disable writes BTFSC EECON1,WR ; Wait for write to complete GOTO $-2 ;Done BANKSEL 0 RETURN ;--------------------------------------------------------------------- ; I2C初期化(マスター) ;--------------------------------------------------------------------- I2CINIT BANKSEL SSP1CON1 BSF SSP1CON1,SSPM3 ;I2C Master mode, clock = FOSC / (4 * (SSP1ADD+1)) BCF SSP1CON1,SSPM2 BCF SSP1CON1,SSPM1 BCF SSP1CON1,SSPM0 ; BSF SSP1STAT,SMP ; Slew rate control なし(100KHz) BCF SSP1STAT,CKE ; Disable SMBus specific inputs ; MOVLW H'09' ; Boud rate 100K MOVWF SSP1ADD ; BSF SSP1CON1,SSPEN ; Enables the serial port BCF SSP1CON1,WCOL ; Write Collision Detect bit = No BCF SSP1CON1,SSPOV ; Receive Overflow Indicator bit = No ; BANKSEL 0 RETURN ;--------------------------------------------------------------------- ; I2Cスタート ;--------------------------------------------------------------------- I2CSTART BANKSEL SSP1CON2 BSF SSP1CON2,SEN ; Start Condition Enabled bit ; BANKSEL PIR1 BTFSS PIR1,SSP1IF ; 動作完了まで待つ GOTO $-1 ; BCF PIR1,SSP1IF ; フラグクリア ; RETURN ; ;--------------------------------------------------------------------- ; I2Cストップ ;--------------------------------------------------------------------- I2CSTOP BANKSEL SSP1CON2 BSF SSP1CON2,PEN ; Stop Condition Enable bit ; BANKSEL PIR1 BTFSS PIR1,SSP1IF ; 動作完了まで待つ GOTO $-1 ; BCF PIR1,SSP1IF ; フラグクリア ; RETURN ;--------------------------------------------------------------------- ; I2C送信 (Wレジの内容を送信する) ;--------------------------------------------------------------------- I2CSEND BANKSEL SSP1STAT BTFSC SSP1STAT,BF ; Data transmit complete GOTO $-1 ; MOVWF SSP1BUF ; バッファに格納すると送信開始 ; BANKSEL PIR1 BTFSS PIR1,SSP1IF ; 動作完了まで待つ GOTO $-1 ; BCF PIR1,SSP1IF ; フラグクリア ; RETURN ; ;--------------------------------------------------------------------- ; LCD データ(Wレジ内容をLCDに書き込む) ;--------------------------------------------------------------------- LCDDATA MOVWF TMP ; 書き込みデータ一時退避 ; CALL I2CSTART MOVLW H'7C' ; LCDスレーブアドレス CALL I2CSEND ; MOVLW H'40' ; Data (RS=1) CALL I2CSEND ; MOVF TMP,W CALL I2CSEND ; CALL I2CSTOP ; RETURN ; ;--------------------------------------------------------------------- ; LCDコマンド (W:CMD) ;--------------------------------------------------------------------- LCDCMD MOVWF TMP ; 一時退避 ; CALL I2CSTART MOVLW H'7C' CALL I2CSEND MOVLW H'00' ; Command (RS=0) CALL I2CSEND MOVF TMP,W CALL I2CSEND CALL I2CSTOP ; MOVLW H'01' ; Clear Display SUBWF TMP,W BTFSC STATUS,Z GOTO LCDW1MS MOVLW H'02' ; Return Home SUBWF TMP,W BTFSC STATUS,Z GOTO LCDW1MS ; CALL W27US ; Normal command RETURN LCDW1MS CALL W1MS RETURN ;--------------------------------------------------------------------- ; LCD初期化(データシート通り) ;--------------------------------------------------------------------- LCDINIT CALL W20MS ; 電源が安定するまでの待ち時間 CALL W20MS ; MOVLW H'38' ; Function set CALL LCDCMD ; MOVLW H'39' ; Functino set CALL LCDCMD ; MOVLW H'14' ; Intrenal OSC frequency CALL LCDCMD ; MOVF CNTRST,W ; コントラスト ANDLW H'0F' ; 下位4ビット IORLW H'70' CALL LCDCMD SWAPF CNTRST,W ANDLW H'03' ; 上位2ビット IORLW H'54' CALL LCDCMD ; MOVLW H'6C' ; Follower control CALL LCDCMD CALL W100MS ; 200ms CALL W100MS ; MOVLW H'38' ; Function set CALL LCDCMD ; MOVLW H'0C' + H'01' ; Display ON/OFF control CALL LCDCMD ; MOVLW H'01' ; Clear Display CALL LCDCMD ; CALL ARWPTN ; CGRAMへ矢印パターン登録 ; RETURN ;--------------------------------------------------------------------- ; 矢印アニメ '>>>' が流れる ;--------------------------------------------------------------------- DSPARROW MOVF MODE,W SUBLW D'4' ; 電流フロー表示モードのときのみ BTFSS STATUS,Z RETURN BTFSS SECFLG,2 ; 20ms毎のフラグ毎に表示切り替え RETURN ; BCF SECFLG,2 ; INCF WAITCNT,F MOVF WAITCNT,W SUBWF ANMSPEED,W ; 電流値から求めたWAITを超えたら表示 BTFSC STATUS,C RETURN ; CLRF WAITCNT CALL CLRLCD ; MOVF CURLO,F ; 電流確認 BTFSS STATUS,Z GOTO DSPARW0 MOVF CURHI,F BTFSS STATUS,Z GOTO DSPARW0 CLRF PATNO ; 電流値が0のときはPATNO=0のみ DSPARW0 ;; MOVF PCLATH,W ;; MOVWF PCLATH_BK MOVLW H'04' MOVWF PCLATH ; MOVF PATNO,W MOVWF WK BCF STATUS,C ; 8倍 RLF WK,F BCF STATUS,C RLF WK,F BCF STATUS,C RLF WK,W ADDWF PCL,F ; 0 CLRF LCDBUF1+0 ; H'00'が矢印パターンのコード MOVLW H'01' MOVWF LCDBUF2+0 GOTO SETARW1 NOP NOP NOP NOP ; 1 CLRF LCDBUF1+0 CLRF LCDBUF1+1 MOVLW H'01' MOVWF LCDBUF2+0 MOVWF LCDBUF2+1 GOTO SETARW1 NOP NOP ; 2 CLRF LCDBUF1+0 CLRF LCDBUF1+1 CLRF LCDBUF1+2 MOVLW H'01' MOVWF LCDBUF2+0 MOVWF LCDBUF2+1 MOVWF LCDBUF2+2 GOTO SETARW1 ; 3 CLRF LCDBUF1+1 CLRF LCDBUF1+2 CLRF LCDBUF1+3 MOVLW H'01' MOVWF LCDBUF2+1 MOVWF LCDBUF2+2 MOVWF LCDBUF2+3 GOTO SETARW1 ; 4 CLRF LCDBUF1+2 CLRF LCDBUF1+3 CLRF LCDBUF1+4 MOVLW H'01' MOVWF LCDBUF2+2 MOVWF LCDBUF2+3 MOVWF LCDBUF2+4 GOTO SETARW1 ; 5 CLRF LCDBUF1+3 CLRF LCDBUF1+4 CLRF LCDBUF1+5 MOVLW H'01' MOVWF LCDBUF2+3 MOVWF LCDBUF2+4 MOVWF LCDBUF2+5 GOTO SETARW1 ; 6 CLRF LCDBUF1+4 CLRF LCDBUF1+5 CLRF LCDBUF1+6 MOVLW H'01' MOVWF LCDBUF2+4 MOVWF LCDBUF2+5 MOVWF LCDBUF2+6 GOTO SETARW1 ; 7 CLRF LCDBUF1+5 CLRF LCDBUF1+6 CLRF LCDBUF1+7 MOVLW H'01' MOVWF LCDBUF2+5 MOVWF LCDBUF2+6 MOVWF LCDBUF2+7 GOTO SETARW1 ; 8 CLRF LCDBUF1+6 CLRF LCDBUF1+7 MOVLW H'01' MOVWF LCDBUF2+6 MOVWF LCDBUF2+7 GOTO SETARW1 NOP NOP ; 9 CLRF LCDBUF1+7 MOVLW H'01' MOVWF LCDBUF2+7 SETARW1 ;; MOVF PCLATH_BK,W ;; MOVWF PCLATH CLRF PCLATH CALL LCD1DSP CALL LCD2DSP ; INCF PATNO,F MOVF PATNO,W SUBLW D'10' BTFSC STATUS,Z CLRF PATNO ; RETURN ; ;--------------------------------------------------------------------- ; 矢印パターンの流れる速度(wait時間)計算 ; 20ms(最速) 〜 1000ms で 20ms毎に可変 ; 遅延ループ数 = (19 - 電流値mA / 128) でテーブルを引く ;--------------------------------------------------------------------- CALCSPEED BCF STATUS,C ; 電流値/128 RLF CURLO,W ; 最左ビットをキャリーへ RLF CURHI,W ; 上位バイトを左シフト SUBLW D'19' BTFSS STATUS,C ; 19以上だったら0 MOVLW D'0' MOVWF WK CALL SPEEDDT MOVWF ANMSPEED ; アニメーションスピード CLRF PCLATH RETURN SPEEDDT MOVLW H'04' MOVWF PCLATH MOVF WK,W ADDWF PCL,F ; RETLW D'1' ; 0 RETLW D'1' ; 1 RETLW D'1' ; 2 RETLW D'2' ; 3 RETLW D'2' ; 4 RETLW D'3' ; 5 RETLW D'4' ; 6 RETLW D'6' ; 7 RETLW D'7' ; 8 RETLW D'7' ; 9 RETLW D'9' ; 10 RETLW D'10' ; 11 RETLW D'13' ; 12 RETLW D'15' ; 13 RETLW D'19' ; 14 RETLW D'23' ; 15 RETLW D'27' ; 16 RETLW D'33' ; 17 RETLW D'40' ; 18 RETLW D'50' ; 19 ; ;--------------------------------------------------------------------- ; LCD CGRAMに矢印パターンを登録 ;--------------------------------------------------------------------- ARWPTN MOVLW H'40' ; CGRAMアドレス CALL LCDCMD MOVLW B'00000000' CALL LCDDATA ; CGRAMへ登録 MOVLW B'00000000' CALL LCDDATA MOVLW B'00000000' CALL LCDDATA MOVLW B'00010000' CALL LCDDATA MOVLW B'00011000' CALL LCDDATA MOVLW B'00001100' CALL LCDDATA MOVLW B'00000110' CALL LCDDATA MOVLW B'00000011' CALL LCDDATA ; MOVLW B'00000011' CALL LCDDATA MOVLW B'00000110' CALL LCDDATA MOVLW B'00001100' CALL LCDDATA MOVLW B'00011000' CALL LCDDATA MOVLW B'00010000' CALL LCDDATA MOVLW B'00000000' CALL LCDDATA MOVLW B'00000000' CALL LCDDATA MOVLW B'00000000' CALL LCDDATA RETURN ;--------------------------------------------------------------------- ; Waitルーチン(注)割り込みが入るので下記時間にはならない ;--------------------------------------------------------------------- W27US MOVLW D'18' ; CALL含めて約27マイクロ秒 LCD待ち時間 MOVWF CNT1 W27USLP DECFSZ CNT1,F GOTO W27USLP GOTO $+1 GOTO $+1 RETURN ; W1MS ;約1ミリ秒 MOVLW D'255' MOVWF CNT1 W1MSLP GOTO $+1 GOTO $+1 GOTO $+1 DECFSZ CNT1,F GOTO W1MSLP GOTO $+1 GOTO $+1 RETURN ; W20MS ;約20ミリ秒 MOVLW D'20' ; MOVWF CNT2 ; W20LP CALL W1MS ; DECFSZ CNT2,F ; GOTO W20LP ; RETURN ; ; W100MS MOVLW D'100' MOVWF CNT2 W100MSLP CALL W1MS DECFSZ CNT2,F GOTO W100MSLP RETURN ; ;--------------------------------------------------------------------- ;http://www.piclist.com/techref/microchip/math/radix/b2bhp-8b3d.htm ;******************************** ;binary_to_bcd - 8-bits ; ;Input ; bin - 8-bit binary number ; A1*16+A0 ;Outputs ; hundreds - the hundreds digit of the BCD conversion ; tens_and_ones - the tens and ones digits of the BCD conversion binary_to_bcd: CLRF hundreds SWAPF bin, W ; swap the nibbles ADDWF bin, W ; so we can add the upper to the lower ANDLW B'00001111' ; lose the upper nibble (W is in BCD from now on) SKPNDC ; if we carried a one (upper + lower > 16) ADDLW 0x16 ; add 16 (the place value) (1s + 16 * 10s) SKPNDC ; did that cause a carry from the 1's place? ADDLW 0x06 ; if so, add the missing 6 (carry is only worth 10) ADDLW 0x06 ; fix max digit value by adding 6 SKPDC ; if was greater than 9, DC will be set ADDLW -0x06 ; if if it wasn't, get rid of that extra 6 BTFSC bin,4 ; 16's place ADDLW 0x16 - 1 + 0x6 ; add 16 - 1 and check for digit carry SKPDC ADDLW -0x06 ; if nothing carried, get rid of that 6 BTFSC bin, 5 ; 32nd's place ADDLW 0x30 ; add 32 - 2 BTFSC bin, 6 ; 64th's place ADDLW 0x60 ; add 64 - 4 BTFSC bin, 7 ; 128th's place ADDLW 0x20 ; add 128 - 8 % 100 ADDLW 0x60 ; has the 10's place overflowed? RLF hundreds, F ; pop carry in hundreds' LSB BTFSS hundreds, 0 ; if it hasn't ADDLW -0x60 ; get rid of that extra 60 MOVWF tens_and_ones ; save result BTFSC bin,7 ; remeber adding 28 - 8 for 128? INCF hundreds, F ; add the missing 100 if bit 7 is set RETURN ; all done! ; ;Note: SKPDC is equivalent to BTFSS STATUS, DC and SKPNDC is equivalent to BTFSC STATUS, DC ;--------------------------------------------------------------------- ; 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. ;--------------------------------------------------------------------- ;******************************************************************* ; Double Precision Multiplication ; ; ( Optimized for Speed : straight Line Code ) ; ;*******************************************************************; ; Multiplication : ACCb(16 bits) * ACCa(16 bits) -> ACCb,ACCc ( 32 bits ) ; (a) Load the 1st operand in location ACCaLO & ACCaHI ( 16 bits ) ; (b) Load the 2nd operand in location ACCbLO & ACCbHI ( 16 bits ) ; (c) CALL D_mpy ; (d) The 32 bit result is in location ( ACCbHI,ACCbLO,ACCcHI,ACCcLO ) ; ; Performance : ; Program Memory : 240 ; Clock Cycles : 233 ; ; Note : The above timing is the worst case timing, when the ; register ACCb = FFFF. The speed may be improved if ; the register ACCb contains a number ( out of the two ; numbers ) with less number of 1s. ; ; The performance specs are for Unsigned arithmetic ( i.e, ; with "SIGNED equ FALSE "). ; ; Program: DBL_MPYF.ASM ; Revision Date: ; 1-13-97 Compatibility with MPASMWIN 1.40 ; ;*******************************************************************; ; ;******************************************************************* ;SIGNED equ FALSE ; Set This To 'TRUE' if the routines ; ; for Multiplication & Division needs ; ; to be assembled as Signed Integer ; ; Routines. If 'FALSE' the above two ; ; routines ( D_mpy & D_div ) use ; ; unsigned arithmetic. ;******************************************************************* ; multiplication macro ; mulMac MACRO LOCAL NO_ADD ; rrf ACCdHI, F ;rotate d right rrf ACCdLO, F btfss STATUS,C ;need to add? goto NO_ADD ; no addition necessary movf ACCaLO,W ; Addition ( ACCb + ACCa -> ACCb ) addwf ACCbLO, F ;add lsb btfsc STATUS,C ;add in carry incf ACCbHI, F movf ACCaHI,W addwf ACCbHI, F ;add msb NO_ADD rrf ACCbHI, F rrf ACCbLO, F rrf ACCcHI, F rrf ACCcLO, F ; ENDM ; ;*******************************************************************; ; Double Precision Multiply ( 16x16 -> 32 ) ; ( ACCb*ACCa -> ACCb,ACCc ) : 32 bit output with high word ; in ACCb ( ACCbHI,ACCbLO ) and low word in ACCc ( ACCcHI,ACCcLO ). ; D_mpyF ;results in ACCb(16 msb's) and ACCc(16 lsb's) ; ;; IF SIGNED ;; CALL S_SIGN ;; ENDIF ; call setup ; ; use the mulMac macro 16 times ; mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac mulMac ; ;; IF SIGNED ;; btfss sign,MSB ;; retlw 0 ;; comf ACCcLO ; negate ACCa ( -ACCa -> ACCa ) ;; incf ACCcLO ;; btfsc STATUS,Z ;; decf ACCcHI ;; comf ACCcHI ;; btfsc STATUS,Z ;;neg_B comf ACCbLO ; negate ACCb ;; incf ACCbLO ;; btfsc STATUS,Z ;; decf ACCbHI ;; comf ACCbHI ;; retlw 0 ;; ELSE retlw 0 ;; ENDIF ; ;******************************************************************* ; setup movlw .16 ; for 16 shifts movwf temp movf ACCbHI,W ;move ACCb to ACCd movwf ACCdHI movf ACCbLO,W movwf ACCdLO clrf ACCbHI clrf ACCbLO retlw 0 ; ;******************************************************************* ; neg_A comf ACCaLO, F ; negate ACCa ( -ACCa -> ACCa ) incf ACCaLO, F btfsc STATUS,Z decf ACCaHI, F comf ACCaHI, F retlw 0 ; ;******************************************************************* ; Assemble this section only if Signed Arithmetic Needed ; ;; IF SIGNED ;;; ;;S_SIGN movf ACCaHI,W ;; xorwf ACCbHI,W ;; movwf sign ;; btfss ACCbHI,MSB ; if MSB set go & negate ACCb ;; goto chek_A ;;; ;; comf ACCbLO ; negate ACCb ;; incf ACCbLO ;; btfsc STATUS,Z ;; decf ACCbHI ;; comf ACCbHI ;;; ;;chek_A btfss ACCaHI,MSB ; if MSB set go & negate ACCa ;; retlw 0 ;; goto neg_A ;;; ;; ENDIF ;--------------------------------------------------------------------- ; ; ; ; ;--------------------------------------------------------------------- ; AN526 ;--------------------------------------------------------------------- #define _C STATUS,C #define LSB 0 UDIV3216L macro ; Max Timing: 16+6*22+21+21+6*22+21+21+6*22+21+21+6*22+21+8 = 699 clks ; Min Timing: 16+6*21+20+20+6*21+20+20+6*21+20+20+6*21+20+3 = 663 clks ; PM: 240 DM: 9 CLRF TEMP RLF AARGB0,W RLF REMB1, F MOVF BARGB1,W SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0, F CLRW BTFSS _C MOVLW 1 SUBWF TEMP, F RLF AARGB0, F MOVLW 7 MOVWF LOOPCOUNT LOOPU3216A RLF AARGB0,W RLF REMB1, F RLF REMB0, F RLF TEMP, F MOVF BARGB1,W BTFSS AARGB0,LSB GOTO UADD26LA SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0, F CLRW BTFSS _C MOVLW 1 SUBWF TEMP, F GOTO UOK26LA UADD26LA ADDWF REMB1, F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0, F CLRW BTFSC _C MOVLW 1 ADDWF TEMP, F UOK26LA RLF AARGB0, F DECFSZ LOOPCOUNT, F GOTO LOOPU3216A RLF AARGB1,W RLF REMB1, F RLF REMB0, F RLF TEMP, F MOVF BARGB1,W BTFSS AARGB0,LSB GOTO UADD26L8 SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0, F CLRW BTFSS _C MOVLW 1 SUBWF TEMP, F GOTO UOK26L8 UADD26L8 ADDWF REMB1, F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0, F CLRW BTFSC _C MOVLW 1 ADDWF TEMP, F UOK26L8 RLF AARGB1, F MOVLW 7 MOVWF LOOPCOUNT LOOPU3216B RLF AARGB1,W RLF REMB1, F RLF REMB0, F RLF TEMP, F MOVF BARGB1,W BTFSS AARGB1,LSB GOTO UADD26LB SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0, F CLRW BTFSS _C MOVLW 1 SUBWF TEMP, F GOTO UOK26LB UADD26LB ADDWF REMB1, F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0, F CLRW BTFSC _C MOVLW 1 ADDWF TEMP, F UOK26LB RLF AARGB1, F DECFSZ LOOPCOUNT, F GOTO LOOPU3216B RLF AARGB2,W RLF REMB1, F RLF REMB0, F RLF TEMP, F MOVF BARGB1,W BTFSS AARGB1,LSB GOTO UADD26L16 SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0, F CLRW BTFSS _C MOVLW 1 SUBWF TEMP, F GOTO UOK26L16 UADD26L16 ADDWF REMB1, F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0, F CLRW BTFSC _C MOVLW 1 ADDWF TEMP, F UOK26L16 RLF AARGB2, F MOVLW 7 MOVWF LOOPCOUNT LOOPU3216C RLF AARGB2,W RLF REMB1, F RLF REMB0, F RLF TEMP, F MOVF BARGB1,W BTFSS AARGB2,LSB GOTO UADD26LC SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0, F CLRW BTFSS _C MOVLW 1 SUBWF TEMP, F GOTO UOK26LC UADD26LC ADDWF REMB1, F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0, F CLRW BTFSC _C MOVLW 1 ADDWF TEMP, F UOK26LC RLF AARGB2, F DECFSZ LOOPCOUNT, F GOTO LOOPU3216C RLF AARGB3,W RLF REMB1, F RLF REMB0, F RLF TEMP, F MOVF BARGB1,W BTFSS AARGB2,LSB GOTO UADD26L24 SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0, F CLRW BTFSS _C MOVLW 1 SUBWF TEMP, F GOTO UOK26L24 UADD26L24 ADDWF REMB1, F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0, F CLRW BTFSC _C MOVLW 1 ADDWF TEMP, F UOK26L24 RLF AARGB3, F MOVLW 7 MOVWF LOOPCOUNT LOOPU3216D RLF AARGB3,W RLF REMB1, F RLF REMB0, F RLF TEMP, F MOVF BARGB1,W BTFSS AARGB3,LSB GOTO UADD26LD SUBWF REMB1, F MOVF BARGB0,W BTFSS _C INCFSZ BARGB0,W SUBWF REMB0, F CLRW BTFSS _C MOVLW 1 SUBWF TEMP, F GOTO UOK26LD UADD26LD ADDWF REMB1, F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0, F CLRW BTFSC _C MOVLW 1 ADDWF TEMP, F UOK26LD RLF AARGB3, F DECFSZ LOOPCOUNT, F GOTO LOOPU3216D BTFSC AARGB3,LSB GOTO UOK26L MOVF BARGB1,W ADDWF REMB1, F MOVF BARGB0,W BTFSC _C INCFSZ BARGB0,W ADDWF REMB0, F UOK26L endm ;********************************************************************************************** ; 32/16 Bit Unsigned Fixed Point Divide 32/16 -> 32.16 ; Input: 32 bit unsigned fixed point dividend in AARGB0, AARGB1,AARGB2,AARGB3 ; 16 bit unsigned fixed point divisor in BARGB0, BARGB1 ; Use: CALL FXD3216U ; Output: 32 bit unsigned fixed point quotient in AARGB0, AARGB1,AARGB2,AARGB3 ; 16 bit unsigned fixed point remainder in REMB0, REMB1 ; Result: AARG, REM <-- AARG / BARG ; Max Timing: 2+699+2 = 703 clks ; Max Timing: 2+663+2 = 667 clks ; PM: 2+240+1 = 243 DM: 9 FXD3216U CLRF REMB0 CLRF REMB1 UDIV3216L RETLW 0x00 ;********************************************************************************************** ;--------------------------------------------------------------------- END ;--------------------------------------------------------------------- ; 終わり ;---------------------------------------------------------------------