#ifndef _adcon_inc_ #define _adcon_inc_ messg "include 'adcon.inc'" LIST ; Title : Analog to Digital converter ; By : komi ; Last update : 2005.11.18 ; Version : 0.1 NOLIST ;---------------------------------------------------------------------------- ; ; ANSEL を使用するタイプ(PIC16F88など)と使用しないタイプとで ; ADCON_init の引数の意味が異なるので注意. ; ; アクィジション時間は標準で 20usec としています. ; ;---------------------------------------------------------------------------- ; ; 解説 ; ; ■初期化 ; ・定義 ; ADCON_init ; 引数 ; ... ANSEL 有効なら ANSELに設定する値 ; ... ANSEL 無効なら PCFG3:0 に設定する値 ; ; ... A/D 変換クロックの指定 ; Tosc/n のnを指定する. ; n = 2, 8, 32 (PIC16F877の場合) ; n = 2, 4, 8, 16, 32,64 (PIC16F819の場合) ; n = 0 を指定すると自動計算される. ; 上記以外を指定するとRCを使用となる. ; ; 注意 ; ポートの入出力設定は行わなれない ; ;---------------------------------------------------------------------------- ; PIC16F877 ; PCFG3:PCFG0 |AN7|AN6|AN5|AN4|AN3|AN2|AN1|AN0| ; -------------+---+---+---+---+---+---+---+---+- ; 0000 | A | A | A | A | A | A | A | A | ; 0001 | A | A | A | A | + | A | A | A | ; 0010 | D | D | D | A | A | A | A | A | ; 0011 | D | D | D | A | + | A | A | A | ; 0100 | D | D | D | D | A | D | A | A | ; 0101 | D | D | D | D | + | D | A | A | ; 011x | D | D | D | D | D | D | D | D | ; 1000 | A | A | A | A | + | - | A | A | ; 1001 | D | D | A | A | A | A | A | A | ; 1010 | D | D | A | A | + | A | A | A | ; 1011 | D | D | A | A | + | - | A | A | ; 1100 | D | D | D | A | + | - | A | A | ; 1101 | D | D | D | D | + | - | A | A | ; 1110 | D | D | D | D | D | D | D | A | ; 1111 | D | D | D | D | + | - | D | A | ; ; ; | | | | | | | | | ; ;---------------------------------------------------------------------------- #ifndef CLOCK_FREQ error "Please define that is CPU CLOCK frequency.(ADCON.INC)" #endif #ifndef _delay_inc_ error "Please include 'delay.inc'. (before ADCON.INC)" #endif ;------------------------------------------------------------------ ; A/D 初期化 ; ADCON_init MACRO arg1, arg2 NOLIST variable freq2, freq4, freq8, freq16, freq32, freq64, freqAD, flg variable adcs01 = 0, adcs2 = 0, n #ifdef ADCS2 flg = 1 #else flg = 0 #endif n = arg2 tCLK = 6; freqAD = D'625000' freq2 = CLOCK_FREQ / D'2' freq4 = CLOCK_FREQ / D'4' freq8 = CLOCK_FREQ / D'8' freq16 = CLOCK_FREQ / D'16' freq32 = CLOCK_FREQ / D'32' freq64 = CLOCK_FREQ / D'64' if (n == 0) if (freq2 <= freqAD) n = 2 else if (freq4 <= freqAD && flg) n = 4 else if (freq8 <= freqAD) n = 8 else if (freq16 <= freqAD && flg) n = 16 else if (freq32 <= freqAD) n = 32 else if (freq64 <= freqAD && flg) n = 64 endif endif endif endif endif endif endif if (n == 2) adcs01 = B'00000000' adcs2 = B'00000000' messg "Tad = Tosc / 2 (ADCON.INC)" else if (n == 4 && flg) adcs01 = B'10000000' adcs2 = B'01000000' messg "Tad = Tosc / 4 (ADCON.INC)" else if (n == 8) adcs01 = B'01000000' adcs2 = B'00000000' messg "Tad = Tosc / 8 (ADCON.INC)" else if (n == 16 && flg) adcs01 = B'01000000' adcs2 = B'01000000' messg "Tad = Tosc / 16 (ADCON.INC)" else if (n == 32) adcs01 = B'10000000' adcs2 = B'00000000' messg "Tad = Tosc / 32 (ADCON.INC)" else if (n == 64 && flg) adcs01 = B'10000000' adcs2 = B'01000000' messg "Tad = Tosc / 64 (ADCON.INC)" else adcs01 = B'11000000' adcs2 = B'00000000' messg "Tad = RC (ADCON.INC)" endif endif endif endif endif endif #ifdef ANSEL LIST ; PIC16F88系A/D banksel ANSEL MOVLW arg1 MOVWF ANSEL banksel ADCON1 MOVLW (adcs2 | B'00000000') MOVWF ADCON1 NOLIST #else LIST ; PIC16F877系A/D banksel ADCON1 MOVLW (adcs2 | arg1) MOVWF ADCON1 NOLIST #endif LIST banksel ADCON0 MOVLW adcs01 MOVWF ADCON0 ENDM ;------------------------------------------------------------------ ; A/D変換する(8bit) ; W_ADCON_get_U1 MACRO chU1 banksel ADCON1 BCF ADCON1, ADFM ; 左詰 (ADFM = 0) banksel chU1 MOVF chU1, W ADDWF chU1, W ADDWF chU1, W ADDWF chU1, W ANDLW B'00111000' IORLW B'00000001' banksel ADCON0 MOVWF ADCON0 ; チャンネル選択 delay_us_V1 D'20' ; 20usec 待ち banksel ADCON0 BSF ADCON0, GO ; 変換開始 BTFSC ADCON0, NOT_DONE GOTO $-1 ; 変換完了待ち MOVF ADRESH, W ENDM W_ADCON_get_V1 MACRO chV1 banksel ADCON1 BCF ADCON1, ADFM ; 左詰 (ADFM = 0) MOVLW (((chV1 << D'3') & B'00111000') | B'00000001') banksel ADCON0 MOVWF ADCON0 ; チャンネル選択 delay_us_V1 D'20' ; 20usec 待ち banksel ADCON0 BSF ADCON0, GO ; 変換開始 BTFSC ADCON0, NOT_DONE GOTO $-1 ; 変換完了待ち MOVF ADRESH, W ENDM U1_ADCON_get_U1 MACRO resU1, chU1 W_ADCON_get_U1 chU1 banksel resU1 MOVWF resU1 ENDM U1_ADCON_get_V1 MACRO resU1, chV1 W_ADCON_get_V1 chV1 banksel resU1 MOVWF resU1 ENDM ;------------------------------------------------------------------ ; A/D変換する(10bit) ; U2_ADCON_get_U1 MACRO resU2, chU1 banksel ADCON1 BSF ADCON1, ADFM ; 右詰 (ADFM = 1) banksel chU1 MOVF chU1, W ADDWF chU1, W ADDWF chU1, W ADDWF chU1, W ANDLW B'00111000' IORLW B'00000001' banksel ADCON0 MOVWF ADCON0 ; チャンネル選択 delay_us_V1 D'20' ; 20usec 待ち BSF ADCON0, GO ; 変換開始 BTFSC ADCON0, NOT_DONE GOTO $-1 ; 変換完了待ち MOVF ADRESH, W banksel resU2 MOVWF resU2 banksel ADRESL MOVF ADRESL, W banksel resU2 MOVWF (resU2+1) ENDM U2_ADCON_get_V1 MACRO resU2, chV1 banksel ADCON1 BSF ADCON1, ADFM ; 右詰 (ADFM = 1) MOVLW (((chV1 << D'3') & B'00111000') | B'00000001') banksel ADCON0 MOVWF ADCON0 ; チャンネル選択 delay_us_V1 D'20' ; 20usec 待ち BSF ADCON0, GO ; 変換開始 BTFSC ADCON0, NOT_DONE GOTO $-1 ; 変換完了待ち MOVF ADRESH, W banksel resU2 MOVWF resU2 banksel ADRESL MOVF ADRESL, W banksel resU2 MOVWF (resU2+1) ENDM ;------------------------------------------------------------------ ;---------------------------------------------------------------------------- LIST #endif