goo blog サービス終了のお知らせ 

JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

PIC12F1822 MCC I2C LCD AQM0802A 表示テスト

2021-05-18 08:52:14 | MPLAB X MCC
 PIC12F1822を使って、MPLAB X MCCでI2C設定をして、I2C LCD AQM0802Aに文字を表示するテストを行いました。

 まず、projectを作成してから、MCCで各種設定を行います。MCCを開いて、System Moduleの設定を行います。

INTOSC,FOSCとし、クロックは16MHzとしました。
Low Voltage programingのチェックははずし、RA3は、GPIOとしました。


 I2C通信を使うために、MSSPを導入します。
 Serial ProtocolをI2Cにセットします。
 Modeは、Masterにセット、クロックは100000Hz(100kHz)とし、Interrupt Drivenにチェックを入れます。(割込みを使うんですね)

 割込みを使うので、Interrupt Moduleの設定を行います。
 下のように、チェックを入れました。

 Pin Moduleには、ちゃんとRA1がSCL、RA2がSDAが設定されています。
 一応ウィークプルアップ(WPU)にチェックを入れ、RegistrersでnWPUEN enableにしておきます。


 Generateをクリックして、設定終了です。MCCを閉じて、プログラミングをします。各種設定ファイルとmain.cが生成されます。

 PIC12F1822とAQM0802Aモジュールの接続回路図です。電源は乾電池を使います。

 MCCを使ってAQM0802Aを表示した例は、Web上では例は少なく、どのようにプログラミングするのか頭を悩ませました。そんな中、KazHatブログというサイトの記事が参考になりました。(というか、コピーさせていただきました)

 AQM0802Aをコントロールするには、I2Cスレーブアドレス(AQM0802Aの場合、0x3e)に続いて、コントロールバイト(コマンドの場合0x00、データの場合00x40)を送り、次にコマンドまたはデータを送ります。

 このフォーマットを実現するためには、mcc_generated_files/examples/i2c_master_example.cの中のI2C_Write1ByteRegister(i2c_address_t address, uint8_t reg, uint8_t data)という関数を使います。

 試しに、i2c_address = 0x3e,reg = 0x40,data = 0x41としてAQM0802A
送信した場合のI2C信号を見てみました。I2Cアドレスは、bit0にwriteの0が加わって、0x7cとして送信されます。OKです。


 以前にMCCを使わないで組んだプログラムとKazHatさんのプログラムを合わせたような次のようなプログラムでテストしました。
 printf()関数を使っていますので、projectのpropertiesで、XC8 Global OptionsのC standerdをC90にしてコンパイルします。
-------------------------------------------------------
/*
* PIC12F1822 MCC I2C LCD AQM0802A
* 2021.05.17
* JH7UBC Keiji Hata
*/

#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c_master_example.h"

#define I2CLCD_AQM0802A 0x3e

//-------- send character ------------------------
void LCD_dat(char chr)
{
I2C_Write1ByteRegister(I2CLCD_AQM0802A, 0x40, chr);
__delay_us(30); // 30us
}

//-------- send command -------------------------
void LCD_cmd(char cmd)
{
I2C_Write1ByteRegister(I2CLCD_AQM0802A, 0x00, cmd);
if(cmd & 0xFC) // bit6 = 1
__delay_us(30); // 30us
else
__delay_ms(2); // 2ms Clear or Home
}

//-------- clear LCD--------------------------
void LCD_clr(void){
LCD_cmd(0x01);
}

//--------- Home -----------------------------
void LCD_home(void){
LCD_cmd(0x02);
}

//--------- Cursor X,Y -----------------------
void LCD_cursor(unsigned char x,unsigned char y){
if (y == 0)
LCD_cmd(0x80 + x);
if (y == 1)
LCD_cmd(0xc0 + x);
}

//-------- display strings -------------------------
void LCD_str(char *str){
while(*str)
LCD_dat(*str++); //pointer increment
}

//-------- write 1 character to LCD ----------------
void putch(unsigned char ch){
LCD_dat(ch);
}

//-------- LCD initialize ---------------------------
void LCD_init(){
__delay_ms(40); //40ms wait
LCD_cmd(0x38); //8bit,2line
LCD_cmd(0x39); //IS=1 : extention mode set
LCD_cmd(0x14); //Internal OSC Frequency
LCD_cmd(0x70); //Contrast set
LCD_cmd(0x56); //Power/ICON/Contrast Control
LCD_cmd(0x6C); //Follower control
__delay_ms(200);//200ms wait
LCD_cmd(0x38); //IS=0 : extention mode cancel
LCD_cmd(0x0C); //Display ON
LCD_cmd(0x01); //Clear Display
__delay_ms(2); //wait more than 1.08ms
}

void main()
{
// initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();

LCD_init();

char msg[] = "Hello!";
LCD_str(msg);

unsigned char count = 0;

while (1)
{
LCD_cursor(2,1);
printf("%3d",count);
count++;
__delay_ms(1000);
}
}
-------------------------------------------------------
ブレッドボードと文字が表示された様子です。

 一応、表示できましたが、PIC12F1822のプログラムメモリ2K Wordsのうち85%を使ってしまいました。データメモリは128byteのうち77%を使いました。
 ちなみに、同等のプログラムをMCCを使わないで組んだ場合は、プログラムメモリーの37%、データメモリの27%を使いました。

 つまり、MCCを使うと設定が簡略化させる分メモリーをたくさん使うということですね。メモリ容量の大きいPIC向きということでしょうか。

PIC12F1822 MCC シリアル通信テスト

2021-05-10 10:29:46 | MPLAB X MCC
 MPLAB MCCを使ったシリアル通信のテストをします。

 使うPICは、前回と同じPIC12F1822です。

 以前に行ったPIC12F1822のシリアル通信テストは、ここに掲載しています。
 USBシリアル変換は、FT234Xを使います。回路図です。


 この時の、通信設定は、次のとおりです。
------------------------------------------------------------------
void serial_init(unsigned long BR){
TXSTA = 0x24; //SYNC=0 TXEN = 1 BRGH = 1
BRG16 = 1; //BRG 16bit mode
RCSTA = 0x90; //非同期、継続受信可
unsigned int X= _XTAL_FREQ/BR/4 - 1;
SPBRGH = X / 256;
SPBRGL = X % 256;
------------------------------------------------------------------
 けっこう複雑ですね。では、MCCで設定してみます。

 projectを作成し、MCCを開きます。
 まず、System_moduleを設定します。

 今回は、クロックを8MHzとして、PLLを使い×4=32MHz動作としました。
 Low voltage Programmingをはずし、設定は、これだけにしました。

 シリアル通信のための設定をします。Divice Resourceまたは、Avilable ResourceからEUSARTを選ぶと、Project ResourceにEUSARTが登録され、Pin managerにEUSARTが表示され、RA0にTXが、RA1にRXが自動的にセットされます。

 EUSARTの設定をします。Project ResourceのEUSARTをクリックすると設定画面が開きます。

通信速度(Baud Rate)はデフォルトで9600bpsです。他の設定もデフォルトのままにしました。



Generateして、main.cに簡単なプログラムを書きました。
キーボードから入力された文字をそのまま送り返す、いわゆるエコーバックのプログラムです。

 USARTなどの設定が見えないだけに、すごく簡単です。

 build 書き込みを行いPICとFT234Xをブレッドボード上に配線します。

 Tera Termを立ち上げて、通信テストを行います。キーボードから送った文字がそのままTera Termに表示されました。


 通信テストOKです。
 複雑な計算を行わないでもシリアル通信の設定ができました。
 確かにブラックボックスですが、使いやすくなりましたね。

MPLAB X MCCを使ってみる

2021-05-09 15:21:18 | MPLAB X MCC
 私は、2013年からPICの勉強を始めました。勉強とPICを使った製作の経過は、JH7UBCホームページのこちらに掲載しています。

 最初の頃は、MPLAB IDEとアセンブラの組み合わせでプログラミングをして、HEXファイルを自作のPIC writer(RCDライタ,writer509,PICerFTなど)で書き込みを行いました。PIC用のアセンブラで煩わしいのが、BANK切り替えでした。

 2018年からMPLAB X IDEに切り替え、言語もXC8に変更しました。これに伴い、BANK切り替えの煩わしさからは解放されましたが、各レジスタの設定は、先人のWeb上の情報や、PICの説明書などを見ながら行ってきました。PIC writerは、PICKit3を購入して、IDEでbuildして即書き込みができるようになりました。

 最近、MPLAB X IDEでプラグインのMCC(MPLAB Code Configurator)を使えば、各種設定が画面上ででき、configやレジスタ設定のコードを自動で生成してくれ、プログラム開発の効率が格段に向上することを知りました。

 そこで、さっそくMCCをインストールして、試してみることにしました。インストールのしかたは、こちらのサイトなどを参照してください。

 手元にPIC16F84がたくさんあったので、これで試そうと思ったのですが、これらのレガシーPICにはMCCは対応していないようです。F1シリーズに対応しているようです。そこで、最もシンプルなPICであるPIC12F1822(8pin PIC)を使ってみます。定番のLチカをやってみます。回路図です。


 まず、PIC12F1822_Blinkという名前でprojectを作成。
 次に、各種設定を行うために、MPLAB IDEのメニューからTools→Enbendded→MPLAB Code Configuratorを開きます。次のような画面になります。


 右上にPINの配置図、左側にmoduleなどの選択、真ん中に各設定項目が表示されます。

 まず、System Moduleで、クロックやレジスタの設定を行います。
 内部クロックで16MHzとします。
 LEDは、RA1に接続することにしますので、画面の一番下に表示されているPin ManagerでPortAの1,outputのカギマークをクリックします。



次に、Registersタグをクリックすると各レジスタの設定ができます。
 一応上の図のように設定しました。
 Pin Modeを詳しく設定します。MCC画面の左上のProject ResourcesをPin Moduleに切り替え、RA1のoutoutだけを指定します。



 今回の設定は、こんなもので大丈夫でしょう。左上のTree ViewのGenerateをクリックすると各種設定ファイルが自動的に生成されます。
 MCCを終了して(MCCのアイコンをクリックすると終了します)設定ファイルの中身を見てみます。

mcc.cです。OSC関係とWDT設定が生成されています。


device_config.cです。設定したとおりにconfigが生成されています。


pin manager.cです。pin設定のコードが生成されています。

この時点で、main.cも次のような形で自動的に生成されています。
-------------------------------------------------------------
#include "mcc_generated_files/mcc.h"

void main(void)
{
// initialize the device
SYSTEM_Initialize();

while (1)
{

}
}
--------------------------------------------------------------------
プログラムは、
while(1){
}
の間に記入します。
RA1に接続したLEDを500msごとに点滅しますので、次のようにしました。
PIC F18シリーズには、LATレジスタがありますので、RAレジスタではなく、LATAレジスタを操作しています。


 ブレッドボードです。電源は電池2本で供給しています。

 プログラム通りLEDが点滅しました。

 初めてMCCを使いましたので、記事の中に誤りがあるかもしれません。
 その場合、コメントなどで教えていただきたいと思います。