PIC内蔵EEPROMへのアクセス
PIC16F887で内蔵EEPROMへの読み書きができました。
といっても実作業はほとんどなしで、データシートに読み書き用の記述例があるからそのままそっくり持ってきただけですw
サンプルと変えた部分は、
・sleep命令の削除。今回はsleepしなくていい
・regというレジスタに読み書きしてきたデータを入れる
・サンプルでDATA_EE_ADDRと記述されてる部分に実際のアドレスを記述。今回はデータEEPROMの先頭の0x00
動作としては電源が入るとEEPROMの0x00から1バイトのデータを読み込んでPORTBに繋がってるLEDにそのまま出力。
その後読み込んだデータをインクリメントして同じアドレスのEEPROMへ格納。
その後は無限ループで何もしない。
これで電源をON/OFFするたびにLEDが1ずつカウントアップされていくような動作になります。
内臓のEEPROMを使う利点は何といっても電源を切ってもデータが保持されるということ。そのため上記のような動作が可能となっています。
今回戸惑ったのがANSELと汎用レジスタの扱い。
アナログポートとして動作させるか指定するANSELというレジスタが電源投入時は全て1、つまりアナログ入力とデジタルI/Oどちらにも使えるポートをアナログ入力として使うっていう設定になっています。(PIC16F887とか新しめのPICからそうなった?)
今回はデジタルOUTとして使いたいのでANSELを0にしてアナログ入力を無効にして、TRISレジスタを0にしておけば・・・と思っていたのですが全く出力されません。
そこでデータシートをよくよく読んでみると、デジタルOUTとして使いたいときはTRISレジスタは0、ANSELは1にしておくこと、とありました。
どうやらANSLEをいじるのはTRISが1(入力)の時だけみたいで、デジタルOUTの時は特に指定なしで良さそうです。
それから汎用レジスタregの扱い。
EEPROMを読み書きする際はバンク切り替えが多く発生します。そこで最初に書いたプログラムではバンク0のレジスタを指定してたためデータが意図したレジスタに入っていませんでした。これは毎回ちゃんとそのレジスタのバンクを指定するか、どのバンクからでも読める0x70以降のアドレスに配置するかで解決できました。
今回作ったプログラムを以下に書いておきます。使用PICはPIC16F887
list p=16f887 ; list directive to define processor #include <p16f887.inc> ; processor specific variable definitions __CONFIG _CONFIG1, _LVP_OFF & _FCMEN_OFF & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _HS_OSC __CONFIG _CONFIG2, _WRT_OFF & _BOR21V reg EQU 0x70 org 0x2100 de 0x00 ;********************************************************************** ORG 0x000 ; processor reset vector nop goto main ; go to beginning of program main bcf STATUS,RP0 ;bank0 bcf STATUS,RP1 clrf INTCON banksel TRISA ;bank change clrf TRISA clrf TRISB clrf TRISC clrf TRISD clrf TRISE bcf STATUS,RP0 ;bank0 bcf STATUS,RP1 clrf PORTA clrf PORTB clrf PORTC clrf PORTD clrf PORTE clrf reg main_loop call read movfw reg movwf PORTB incf reg,f call write bsf PORTD,1 nop goto $-1 read BANKSEL EEADR ; MOVLW 0x00 MOVWF EEADR ;Data Memory BANKSEL EECON1 ; BCF EECON1, EEPGD ;Point to DATA memory BSF EECON1, RD ;EE Read BANKSEL EEDAT ; MOVFw EEDAT movwf reg banksel PORTA return write BANKSEL EEADR MOVLW 0x00 MOVWF EEADR ;Data Memory Address to write movfw reg MOVWF EEDAT ;Data Memory Value to write BANKSEL EECON1 ; BCF EECON1, EEPGD ;Point to DATA memory BSF EECON1, WREN ;Enable writes BCF INTCON, GIE ;Disable INTs. BTFSC INTCON, GIE ;SEE AN576 GOTO $-2 MOVLW 0x55 ; MOVWF EECON2 ;Write 55h MOVLW 0xaa ; MOVWF EECON2 ;Write AAh BSF EECON1, WR ;Set WR bit to begin write BSF INTCON, GIE ;Enable INTs. BCF EECON1, WREN ;Disable writes BCF STATUS, RP0 ;Bank 0 BCF STATUS, RP1 return END ; directive 'end of program'