PIC18F の EEPROM 読み書き
ここ数年、私が使うPIC は 8bit の 18Fシリーズ、それも PIC18F23K22 または PIC18F46K22 だけになりました。I/Oの数とメモリーが足りる限り 23K22 を使います。
RasPi と UART で通信しながらI/Oを動かし、タイミングが微妙な信号を作ったり検出したりする用途に使っています。USB-UARTで接続する場合はRasPi に限らず、Linux, WIndows にも使えますから、使い回しが容易です。
今回の用途は、PC等との連携は無くボタン操作でRCサーボを4台動かすものです。CPUは PIC18F23K22で、一つのタイマーで4台分の信号を作って各々独立に制御します。
23K22, 46K22 は3.3V でも 5.0V でも動作します。今回はRCサーボ信号に合わせて5.0Vで使います。(この柔軟性が気に入っています。)
RCサーボ以外にも接続先のUART信号電圧が5Vの場合にも5.0Vの回路にします。
1回路だけならトランジスタ等をかませて3.3V駆動で使う場合もありますが、3.3Vと5.0Vの2電源にしたくない場合はFETのゲート電圧(4V)を確保するためとか、Vfの大きいLEDを直接駆動するためと言った場面で5.0V駆動を選ぶことがあります。どちらの電源電圧を選択したとしても、ファームウェアはコンフィグレーションビットも含め同じものが使えちゃいます。
今回のRCサーボは入手し易く、利用者が多くて情報も豊富な SG90 です。
SG90の機差や取付バラツキを微調整する為に、停止位置(角度)をボタン操作で修正してEEPROMに保存する必要があり、久しぶりにEEPROMの読み書きに挑戦です。アセンブラでは使ったことがあるのですが、XC8では初めてです。(タイトル画像の基板反対面に操作ボタンがあります。)
ライブラリ関数は使いたくないので、自作の関数で期待した動作を確認しました。1byte の変数2つを使ってアドレスとデータをやり取りします。
( eepwk0 をアドレス、eepwk1 をデータに使います。)
動作確認した関数
コンパイラは XC8 Ver. 1.40
こちらは読出し用です。
void eeprd(void) // EEPROM 1byte 読出し
{
EEADR = eepwk0 ; // アドレス
EECON1bits.EEPGD = 0 ; // EEPROM 指定
EECON1bits.CFGS = 0 ;
EECON1bits.RD = 1 ; // 読出し指示
eepwk1 = EEDATA ; // データ
}
eepwk0 にアドレス(1byte)を入れて、eeprd を呼ぶと eepwk1 からデータを読み出せます。
こちらは書込み用です。
eepwk0 にアドレス(1byte)、eepwk1 にデータを入れて、eepwr を呼ぶとデータを書き込みます。
(書込み中の電源断など細かい配慮はありません。)
void eepwr(void) // EEPROM 1byte 書込み
{
EEADR = eepwk0 ; // アドレス
EEDATA = eepwk1 ; // データ
EECON1bits.EEPGD = 0 ; // EEPROM 指定
EECON1bits.CFGS = 0 ;
EECON1bits.WREN = 1 ; // 書込み許可
EECON2 = 0x55 ; // おまじない
EECON2 = 0xAA ;
EECON1bits.WR = 1 ; // 書込み開始
while( EECON1bits.WR == 1 ) // 終了待ち
{ }
EECON1bits.WREN = 0 ; // 書込み禁止
}
アセンブラ上がりなのでデータの受け渡しはメモリー(PICの場合はFile Registers)でやっちゃってます。
PIC18F の話題も時々紹介したいと思います。
これからも宜しくお願い致します。