先月までPIC16F1827を利用して、MPLAB X + MCCでプログラムの勉強をしてきました。しかし、BME280(温度、湿度、気圧センサー)のデータを読み、処理する段階で浮動小数点計算が入ってきて、メモリ不足をおこしてしまいました。
メモリ容量の大きいPICを探したら、PIC16F18326がありました。しかも安価(@140円)です。秋月電子から購入して、実験を始めました。まず、I2Cを利用したAQM0802Aの表示テストを行います。
PIC16F18326の主なスペックです。
最大クロック 32MHz
プログラムメモリ 16kW
EEPROM 256B
RAM 2KB
GPIO 12
ADC 11ch
DAC 1ch
EUSART 1ch
I2C 2ch
SPI 2ch
タイマ 7
機能は多くありませんが、プログラムメモリが大きいのが特徴です。
MPLAB Xでプロジェクトを作成し、MCCを立ち上げます。
System moduleのセットをします。
あれっ、PIC16F1827などの時と画面がちょっと違います。
とりあえず、HFINTOSC,16MHz,Colck Divider=4,Low-voltage programingはoffとしました。
PIC16F18326のドキュメントからクロックの説明図を見ると
なるほど、オッシレータを選択して、その後にDividerが入っているんですね。なお、PIC16F18326の説明は、こちらのサイトに説明があり、参考になりました。
I2Cを利用するために、MSSP1モジュールを導入します。
割込みを使いますので、Interruptモジュールの設定をします。
Pin moduleで一応ウィークプルアップにチェックを入れます。
I2CのSDA1は、9番ピンにSCL1は、10番ピンに割り当てられます。
ここで、今までとの違いにもう一つ気が付きました。
WPU enableの設定がありません。これまでですと、WPUにチェックを入れるとWPUEにチェックを入れろという注意がされたのですが、ありません。
回路図です。
これでいいのかな・・・・と思いつつ、プログラミングに進みます。
プログラムです。
printf()関数を使っていますので、projectのpropertiesで、XC8 Global OptionsのC standerdをC90にしてコンパイルします。
--------------------------------------------------------------------------
/*
* PIC16F18326 MCC AQM0802A test
* 2021.09.20
* JH7UBC Keiji Hata
*/
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#define I2CLCD_AQM0802A 0x3e
//-------- send character ------------------------
void LCD_dat(char chr)
{
I2C1_Write1ByteRegister(I2CLCD_AQM0802A, 0x40, chr);
__delay_us(30); // 30us
}
//-------- send command -------------------------
void LCD_cmd(char cmd)
{
I2C1_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);
}
//-------- 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(void){
// initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
LCD_init();
printf("Hello!");
unsigned char count = 0;
while (1){
LCD_cursor(2,1);
printf("%3d",count);
count++;
__delay_ms(1000);
}
}
* PIC16F18326 MCC AQM0802A test
* 2021.09.20
* JH7UBC Keiji Hata
*/
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#define I2CLCD_AQM0802A 0x3e
//-------- send character ------------------------
void LCD_dat(char chr)
{
I2C1_Write1ByteRegister(I2CLCD_AQM0802A, 0x40, chr);
__delay_us(30); // 30us
}
//-------- send command -------------------------
void LCD_cmd(char cmd)
{
I2C1_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);
}
//-------- 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(void){
// initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
LCD_init();
printf("Hello!");
unsigned char count = 0;
while (1){
LCD_cursor(2,1);
printf("%3d",count);
count++;
__delay_ms(1000);
}
}
--------------------------------------------------------------------------
ブレッドボードです。
無事、表示されました。