その10 7SEG表示式 温度-湿度計
7SEG-LED 3桁表示方式の 温度-湿度計です。 TempLanから、X-Port01(イーサネット接続)を取除き、 表示部分を暗いところでもくっきり見えるように7SEG-LED 3桁表示方式に変更しています。 今回は2つのセンサーを搭載し、2つのA/D変換入力を切換えながら約8秒間隔で情報を表示します。 温度センサーは、LM35A(右上の写真の、左下部の半固定抵抗器の隣)。 湿度センサーユニットは、マルツ電波で購入した、HSM-20G(左上と,左下の写真の緑色の基盤)です。 一番右の基盤は、TL431CPにより4.00VのA/D変換用基準電圧を発生する回路です。 外部電源は、5Vの電源アダプターでかなり安定した動作ができました。 電源コモンライン部分の1000μの電解コンデンサーが、 リップルの少ない安定した電力を供給し、 PICのRA3/AN3/Vref+端子に4.00Vの基準電圧を加える事によって、 D/A変換精度を向上させて安定した表示が行えます。 私は7SEG-LEDは、ROHM(ローム)社製のLA-601XB(黄色、アノードコモン)を使用しています。 7セグメントLEDを順番に高速に切換えながら点灯させる(ダイナミック点灯方式)を使用してI/Oポート数を減らしています。 格桁は、コモン端子に接続されたトランジスタ(PNP)のベース電圧がLow(0V)になる事によって選択されて、 表示したいセグメントのビットをLow(0V)にする事によって表示されます。 電源投入後1〜2分ぐらいは初期変動があるようです。
;********************************************************************** ; PICTempRH Nov. 3rd 2009 ; 温度センサー & 湿度センサー 7SEG-LED ; LM35DZ 用の ゼロ点補正を含む ; AD変換値から20(0x14)を単純に2バイト減算する ; 湿度表示時ドット2個表示化 ;********************************************************************** list p=16f873a #include __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _HS_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF w_temp EQU 0x20 status_temp EQU 0x21 R0 EQU 0x22 R1 EQU 0x23 R2 EQU 0x24 CNT1 EQU 0x25 CNT2 EQU 0x26 CNT3 EQU 0x27 CCNT EQU 0x28 ;温度更新時間カウント CNT4 EQU 0x29 CNT5 EQU 0x2a H_comp EQU 0x2c ;LM35DZ温度補正値(上位バイト) L_comp EQU 0x2d ;LM35DZ温度補正値(下位バイト) A_H EQU 0x2e A_L EQU 0x2f ;バイナリ->BCD変換用 count EQU 0x30 temp EQU 0x31 H_byte EQU 0x32 L_byte EQU 0x33 ;Symbols #define HcompRH 0 #define LcompRH 0x4d ; 300mV(300*1024/4.0/1000=76.8->0x4d) #define HcompTm 0 #define LcompTm d'15' ; 1.5deg ;********************************************************************** ORG 0x000 ; processor reset vector clrf PCLATH ; ensure page bits are cleared goto main ; go to beginning of program ORG 0x004 ; interrupt vector location movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register bcf STATUS,RP0 ; ensure file register bank set to 0 movwf status_temp ; save off contents of STATUS register ; isr code can go here or be located as a call subroutine elsewhere bcf STATUS,RP0 ; ensure file register bank set to 0 movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt main bcf STATUS,RP0 bcf STATUS,RP1 ; バンク0に設定 clrf INTCON ; 割り込みを禁止 ;*********************************************************** ; 初期化 ;*********************************************************** bsf STATUS,RP0 ; バンク1に設定 clrf PORTA movlw b'11111111' movwf TRISA ; PORTAを全入力に clrf TRISB ; PORTBを全出力に movlw b'00011111' movwf TRISC ; PORTCの上位3ビットのみを出力に bcf STATUS,RP0 ; バンク0に設定 ; movlw 0xe0 ; movwf PORTC ; 7segを全桁消灯 ; main Temp ; A/Dコンバータ設定(Temp用) ADTm movlw b'11000001' ; A/D入力=AN0 movwf ADCON0 bsf STATUS,RP0 ; bank1 movlw b'10000001' ; ADFM=0,VREF+=AN3 movwf ADCON1 bcf STATUS,RP0 ; bank0 movlw LcompTm movwf L_comp movlw HcompTm movwf H_comp movlw 0x01 movwf CCNT movlw 0x01 movwf CNT4 movlw 0xff movwf CNT5 main_loop decfsz CCNT,f goto loop1 adc_loop bsf ADCON0,GO adc_loop1 btfsc ADCON0,GO ; A/D変換待ち goto adc_loop1 bsf STATUS,RP0 ; Bank=1 movf ADRESL,w bcf STATUS,RP0 ; Bank=0 movwf L_byte ; 下位バイト取り込み rrf L_byte,f ; 右ローテートで1/2する bcf STATUS,C ; キャリー無視 movf ADRESH,w ; 上位バイト取り込み movwf H_byte rrf H_byte,f ; 右ローテートで1/2する btfss STATUS,C ; キャリーが立っているか? goto adc_do2 movlw b'10000000' iorwf L_byte,f ; キャリーがあれば1桁下げ adc_do2 movf L_comp,w subwf L_byte,f btfss 3h,0 decf H_byte,f movf H_comp,w subwf H_byte,f call B2_BCD movf R1,w movwf R0 movf R2,W movwf R1 andlw 0xf0 bcf STATUS,C rrf R1,f rrf R1,f rrf R1,f rrf R1,f movlw 0xff movwf CCNT loop1 movf R2,w call GET_7SEG movwf PORTB movlw 0xc0 movwf PORTC call dly_4m movf R1,w call GET_7SEG movwf PORTB bcf PORTB,0 ; 2桁目に小点表示 movlw 0xa0 movwf PORTC call dly_4m movf R0,w call GET_7SEG movwf PORTB movlw 0x60 movwf PORTC call dly_4m decfsz CNT5,f goto main_loop decfsz CNT4,f goto main_loop ; main %RH ; A/Dコンバータ設定(%RH用) ADRH movlw b'11001001' ; A/D入力=AN1 movwf ADCON0 bsf STATUS,RP0 ; bank1 movlw b'10000001' ; ADFM=0,VREF+=AN3 movwf ADCON1 bcf STATUS,RP0 ; bank0 movlw LcompRH movwf L_comp movlw HcompRH movwf H_comp movlw 0x01 movwf CCNT movlw 0xff movwf CNT4 RHmain_loop decfsz CCNT,f goto RHloop1 bsf ADCON0,GO RHadc_RHloop1 btfsc ADCON0,GO ; A/D変換待ち goto RHadc_RHloop1 bsf STATUS,RP0 ; Bank=1 movf ADRESL,w bcf STATUS,RP0 ; Bank=0 movwf L_byte ; 下位バイト取り込み movf ADRESH,w ; 上位バイト取り込み movwf H_byte RHadc_do2 ;%RH=%RH-0.3 movf L_comp,w subwf L_byte,f btfss 3h,0 decf H_byte,f movf H_comp,w subwf H_byte,f movf L_byte,w movwf A_L movf H_byte,w movwf A_H ;%RH=%RH*1.13=%RH+%RH/8 bcf STATUS,C rrf A_H,f ; 上位から処理 rrf A_L,f ; A = A/2 bcf STATUS,C rrf A_H,f ; 上位から処理 rrf A_L,f ; A = A/2 bcf STATUS,C rrf A_H,f ; 上位から処理 rrf A_L,f ; A = A/2 movf A_L,w addwf L_byte,f btfsc 3h,0 incf H_byte,f movf A_H,w addwf H_byte,f call B2_BCD movf R1,w movwf R0 movf R2,W movwf R1 andlw 0xf0 bcf STATUS,C rrf R1,f rrf R1,f rrf R1,f rrf R1,f movlw 0xff movwf CCNT RHloop1 movf R2,w call GET_7SEG movwf PORTB bcf PORTB,0 ; 少数点表示 movlw 0xc0 movwf PORTC call dly_4m movf R1,w call GET_7SEG movwf PORTB bcf PORTB,0 ; 少数点表示 movlw 0xa0 movwf PORTC call dly_4m movf R0,w call GET_7SEG movwf PORTB movlw 0x60 movwf PORTC call dly_4m decfsz CNT4,f goto RHmain_loop goto ADTm ; Sub ;************************************************* ; Convert BCD to 7SEG Code ; PORT B0 is used for another,then data is ; shifted 1 bit left ;************************************************* GET_7SEG andlw 0FH ;Mask upper 4bits addwf PCL,f ;Add to PC reg retlw B'10000001' ;Code 0 retlw B'11110011' ;Code 1 retlw B'01001001' ;Code 2 retlw B'01100001' ;Code 3 retlw B'00110011' ;Code 4 retlw B'00100101' ;Code 5 retlw B'00000101' ;Code 6 retlw B'11110001' ;Code 7 retlw B'00000001' ;Code 8 retlw B'00110001' ;Code 9 retlw B'00010001' ;Code A retlw B'00000111' ;Code b retlw B'10001101' ;Code C retlw B'01000011' ;Code d retlw B'00001101' ;Code E retlw B'00011101' ;Code F dly_4m movlw 0x04 movwf CNT1 dly_4m1 call dly_1m decfsz CNT1,f goto dly_4m1 return dly_1m movlw 0x04 movwf CNT2 dly_1m1 movlw 0xfa movwf CNT3 dly_1m2 NOP NOP NOP NOP decfsz CNT3,f goto dly_1m2 decfsz CNT2,f goto dly_1m1 return ; バイナリ->BCD変換ルーチン ; Microchip アプリケーションノート AN526より B2_BCD bcf STATUS,0 movlw .16 movwf count clrf R0 clrf R1 clrf R2 RHloop16 rlf L_byte,F rlf H_byte,F rlf R2,F rlf R1,F rlf R0,F decfsz count,F goto adjDEC retlw 0 adjDEC movlw R2 movwf FSR call adjBCD movlw R1 movwf FSR call adjBCD movlw R0 movwf FSR call adjBCD goto RHloop16 adjBCD movlw 3 addwf 0,W movwf temp btfsc temp,3 movwf 0 movlw 30 addwf 0,W movwf temp btfsc temp,7 movwf 0 retlw 0 end
何も考えないで買ってきた7SEG-LEDがアノードコモンタイプだったので、 表示論理が逆になっています。 また、この7SEG-LEDは高輝度タイプだったので、 各セグメントに 10mA程の電流でもかなり明るい感じです。 マルツ電波で買ってきた湿度センサーは、 データー表から近似一次式を当てはめて、 PICで計算して表示しています。 (その8参照)