PICでのOLED表示テストは、PIC16F1827を使って以前に行い、このブログに掲載しました。記事は
こちら。
PICとOLED間は、I2C通信でコントロールとデータ送信を行います。PIC16F18326の動作を確認するために、LEDをRA0に接続して点滅させます。電源は乾電池2個(3V)とします。OLEDモジュール内にプルアップ抵抗があるので、I2Cのプルアップ抵抗は省略しています。
回路図です。
プロジェクトを作成して、MCCを立ち上げます。System moduleの設定をします。HFINTOSC 32MHzとし、Clock Dividerは1とし、最高速で動作させています。Low-voltage programingのチェックを外します。
I2Cは、MSSP1モジュールを導入したので、10番ピン(RC0)がSCL1に、9番ピン(RC1)がSDA1になります。RA0はoutputに設定します。
pin moduleです。
MSSP1moduleです。I2C 100KHzに設定しました。
MCCのI2Cでは、割込みを使いますので、interrupt moduleを設定します。
MCCでは、i2c1_master_example.c内にある次のI2C関係関数を利用します。
1バイト(8bit)のデータを送信する関数
I2C1_Write1ByteRegister(i2c1_address_t address, uint8_t reg, uint8_t data)
2バイト(16bit)のデータを送信する関数
I2C1_Write2ByteRegister(i2c1_address_t address, uint8_t reg, uint16_t data)
Nバイトのデータを送信する関数
I2C1_WriteNBytes(i2c1_address_t address, uint8_t* data, size_t len)
font6.hとfont12.hは、Header ファイルとして、プロジェクトのヘッダフォルダに保存します。
以下、プログラムです。
printf()関数を使っていますので、projectのpropertiesで、XC8 Global OptionsのC standerdをC90にしてコンパイルします。
-------------------------------------------------------------------------------
/*
* PIC26F18326 MCC OLED
* 2021.10.20
* JH7UBC Keiji Hata
*/
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/examples/i2c1_master_example.h"
#include "font6.h"
#include "font12.h"
#define OLED_addr 0x3C
uint8_t Page;
uint8_t Column;
uint8_t Low_col;
uint8_t Hi_col;
uint8_t Size;
uint8_t CLR_cmd[] ={0x00,0x20,0x00,0x21,0x00,0x7F,0x22,0x00,0x07};
//コマンド連続送信,Horizontal addredding Mode,column start address,
//column end address,page start address,page end address
uint8_t Posi_cmd[] = {0x00,0x20,0x02,0xB0,0x00,0x00};
//コマンド連続送信,Page addressing Mode,Page(B0-B7),low column,high column)
uint8_t Font6_data[] = {0x40,0x00,0x00,0x00,0x00,0x00,0x00};
//データ連続送信,font6データ6個
uint8_t Font12_data[] = {0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
//データ連続送信,font12データ12個
//コマンド1byte送信
void OLED_cmd(uint8_t cmd){
I2C1_Write1ByteRegister(OLED_addr,0x80,cmd);
}
//データ1byte送信
void OLED_data(uint8_t dat){
I2C1_Write1ByteRegister(OLED_addr,0xC0,dat);
}
//OLED初期化
void OLED_init(){
OLED_cmd(0x8D); //Set charge pump
OLED_cmd(0x14); //Enable charge pump
OLED_cmd(0xAF); //Display ON
}
//OLED画面消去
void OLED_clr(){
I2C1_WriteNBytes(OLED_addr, CLR_cmd, 9);//Horizontal addressing mode
for(unsigned int i = 0;i < 1024 ;i++ ){ //0s00を1024個送信
OLED_data(0x00);
}
}
// 6x8dotフォントの表示開始位置指定
void font6_posi(uint8_t page, uint8_t column){
Size = 0; //printf で使用するputch のフォントサイズ指定
Page = page; // ページ情報をfont12用にグローバル変数に保存しておく
Column = column; // カラム情報をfont12用にグローバル変数に保存しておく
Posi_cmd[3] = 0xB0 + page; // ページ情報をコマンドにする為に 0xB0 を加算
Posi_cmd[4] = column & 0x0F; //low_column
column = column >>4;
Posi_cmd[5] = column + 0x10; //hi_column
I2C1_WriteNBytes(OLED_addr, Posi_cmd, 6); //Position コマンドをI2Cに送信
}
// 12x16dotフォントの表示開始位置指定
void font12_posi(uint8_t page,uint8_t column){
Size = 1; // printf で使用するputch のフォントサイズ指定
Page = page; // ページ情報をfont12用にグローバル変数に保存しておく
Column = column;// カラム情報をfont12用にグローバル変数に保存しておく
Posi_cmd[3] = page + 0xB0; // ページ情報をコマンドにする為に 0xB0 を加算
Posi_cmd[4] = column & 0x0F; //low_column
column = column >>4;
Posi_cmd[5] = column + 0x10; //hi_column
I2C1_WriteNBytes(OLED_addr, Posi_cmd, 6);
}
// 6x8dotフォントの1文字表示関数
void chr6(uint8_t c){
c = c - 0x20;
for(uint8_t i = 0; i<6; i++){
Font6_data[i+1] = font6[c][i];
}
I2C1_WriteNBytes(OLED_addr,Font6_data,7);
}
// 12x16dotフォントの1文字表示関数
void chr12(uint8_t c){
uint8_t temp;
uint8_t i;
c = c + 6 - 0x30;
Page = Page + 0xB0;
Low_col = Column & 0x0F;
temp = Column >> 4;
Hi_col = temp + 0x10;
Posi_cmd[3] = Page;
Posi_cmd[4] = Low_col;
Posi_cmd[5] = Hi_col;
I2C1_WriteNBytes(OLED_addr,Posi_cmd,6);
for(i = 0; i<12; i++){
Font12_data[i+1] = font12[c][i];
}
I2C1_WriteNBytes(OLED_addr,Font12_data,13);
Page = Page + 1;// グローバル変数ペーシ情報 Page を次の lower 12bytes 描画の為に 1 進める
Posi_cmd[3] = Page;
I2C1_WriteNBytes(OLED_addr,Posi_cmd,6);
for(i = 12; i<24; i++){
Font12_data[i-11] = font12[c][i];
}
I2C1_WriteNBytes(OLED_addr,Font12_data,13);
Page = Page - 1 - 0xB0;//グローバル変数ページ番号 Page を次の1文字描画の為、進めたページ番号を元に戻す (0xB0はコマンドをページ情報に戻す為)
Column = Column +12;// グローバル変数カラム情報を次の次の1文字描画の為、12アドレス進める
}
//printfで使用するputchの定義
void putch(uint8_t c){
if(Size){
chr12(c);
}else{
chr6(c);
}
}
void main(void)
{
// initialize the device
SYSTEM_Initialize();
// Enable the Global Interrupts
INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
INTERRUPT_PeripheralInterruptEnable();
OLED_init();
OLED_clr();
font6_posi(0,30);
printf("Hello World!");
font12_posi(2,0);
printf("0123456789");
while (1)
{
LATA0 = 1;
__delay_ms(500);
LATA0 = 0;
__delay_ms(500);
}
}
-------------------------------------------------------------------------------
ブレッドボードです。