8ピンの32ビットマイコンSTM32C011J4M7I2Cのカラーセンサー入力をLCD表示し,データをUARTでも出力してみました。


1.機材は以下です (I2Cアドレスは7bit表記)
 
MCU: STM32C011J4M7
Color Sensor:HAMAMATSU Color Sensor S11059-02DT(I2C 0x2A)
LCD: Grove-LCD RGB Backlight(I2C 0x3E, 0x62(Backlight) )
・プログラムの書き込みとシリアル通信はST-LINKを介しています。
・I2Cのプルアップはカラーセンサーの仕様書の2.2KΩです。





なお、今回はプリグラムメモリが公称16KBでも32KB使用可能な前提での試行です。
(正式?には32KBある"J6"などを使うのが良いでしょうね,,,)

このためArduino IDE のボード設定はメモリが32KBタイプの"C011F6"を選択し、またUARTは自前のソフトを使うのでメモリを消費するハードウェアシリアルは切っています。





・MPUのピン配置です。
 特別な機能を持つピンを避けるとぎりぎりですね(^^;;;;;。





2.動作結果

LCD表示とバックライト
 カラーセンサーのRGB値を表示し、バックライトもRGB値をもとに入力色に近づくようにしています(^^)。





UARTでのシリアルモニタ出力
 シリアルモニタ側の機能でデータ入力のタイムスタンプが打てるのも用途によっては役に立つでしょうね。







3.ソフトウェア
 I2Cで3台(カラーセンサー、LCD、LCDのバックライト色)の機器をつなぎ、UARTでシリアルモニタに出力しています。


I2Cの設定と使用開始
 I2Cの設定については次のWebページにお世話になりました。
STM32C011(SOP8)のI2Cで遊ぶ(準備編)(STM32C011J4M7)(そしてI2Cは、動いた)

I2C設定ピンは特別なピンを避けると、仕様書では
 I2C1_SCL PA9
 I2C1_SDA PA10
になりますが、STM32C011シリーズではハード的にはピンに出ていません。

そのためリマップ先が準備されていて
 PA11 → PA9
 PA12 → PA10
という関係性でつながり、PA11,PA12の場所でピンとして使用できます。
(ピン配置図を参照)

PA11,PA12の場所にリマップされたPA9,PA10のピン名は
 PA_9_R
 PA_10_R
という名前で呼ばれます(^^)。

名前さえしっかりすれば、後はライブラリをインクルードして、SCLとSDAピンをセットしてスタートできます。

#include <Wire.h>

void setup() {

/* Initializing I2C master */
Wire.setSCL(PA_9_R); // PA9:SCL
Wire.setSDA(PA_10_R); //PA10:SDA
Wire.begin();

}



UARTの設定
 UARTは自前なので、ボーレートの定数を選択して、出力ピンを設定するだけです(^^;;。

// uart Tx Pin :PB7 (STM32C011J Pin 1)
#define uTx_pin PB7

//const byte uTx_bms=104 ; // delay for 9600bps
const byte uTx_bms=7 ; // 115200bps


void setup() {

/* Set uart Tx Pin */
pinMode(uTx_pin, OUTPUT); // set pin as output
digitalWrite(uTx_pin, HIGH);

}




ま、何とか動きましたので良かったです。
ただ、”Wire"は結構大きいので16KBでは難しいですね。

22KBぐらいになった今回のプログラムを一応メモしておきます。


/* STM32C011, Test Program with I2C
* Color Sensor: HAMAMATSU Color Sensor S11059-02DT
* LCD: Grove-LCD RGB Backlight
*/

#include <Wire.h>

// uart Tx Pin :PB7 (STM32C011J Pin 1)
#define uTx_pin PB7

//const byte uTx_bms=104 ; // delay for 9600bps
const byte uTx_bms=7 ; // 115200bps

// I2C slave address of Color Sensor : 0b0101010,7bit
#define ColorSensor 0x2A

// I2C slave address of LCD (Character & Backlight)
#define cLCD 0x3E
#define bLCD 0x62

/* I2C Write Command */
void I2C_write( byte sAdr, byte reg, byte cmd){
Wire.beginTransmission(sAdr); // I2C slave address
Wire.write(reg); // Registor address or Control byte
Wire.write(cmd); // data or command value
Wire.endTransmission();
}

void setup() {

delay(3000); // waiting for upload

/* Initializing I2C master */
Wire.setSCL(PA_9_R); // PA9:SCL
Wire.setSDA(PA_10_R); //PA10:SDA
Wire.begin();


/* Set uart Tx Pin */
pinMode(uTx_pin, OUTPUT); // set pin as output
digitalWrite(uTx_pin, HIGH);

/* Initializing Color sensor (HAMAMATSU S11059-02DT) */
// Controll Registor:0x00
I2C_write(ColorSensor, 0x00, 0x8A); // Reset & Setting: 0b10001010
I2C_write(ColorSensor, 0x00, 0x0A); // Set & Start: 0b00001010
delay(24); // sensor warming up


/* Initializig Grove-LCD, Character (JHD1313) */
// Send command:0x80
I2C_write(cLCD, 0x80, 0x3C); // 2_lines display
I2C_write(cLCD, 0x80, 0x06); // increment mode on, shift off
I2C_write(cLCD, 0x80, 0x0C); // display on, cursor off, blink off
I2C_write(cLCD, 0x80, 0x01); // clear display

/* Initializing Grove-LCD, Backlight (PCA9633) */
// Send command
I2C_write(bLCD, 0x00, 0x00); // Mode1 register:0x00, 0b00000000
I2C_write(bLCD, 0x01, 0x00); // Mode2 register:0x01, 0b00000000
I2C_write(bLCD, 0x08, 0xAA); // LED Drive Mode On
// Send data, color: white
I2C_write(bLCD, 0x04, 0xFF); // R register: 0x04,0xFF
I2C_write(bLCD, 0x03, 0xFF); // G register: 0x03,0xFF
I2C_write(bLCD, 0x02, 0xFF); // B register: 0x02,0xFF

delay(100); // waiting for LCD starting up

Wire.beginTransmission( cLCD ); // Disp. title
Wire.write(0x40);
Wire.write(" [COLOR]");
Wire.endTransmission();

} //setup end


void loop() {

/* Read color data */
Wire.beginTransmission(ColorSensor);
Wire.write(0x03);
Wire.endTransmission(0);
Wire.requestFrom(ColorSensor, 6);
int RH=Wire.read(); // Red
int RL=Wire.read();
int GH=Wire.read(); // Green
int GL=Wire.read();
int BH=Wire.read(); // Blue
int BL=Wire.read();

int Red=RH*256+RL; // Set color data
int Green=GH*256+GL;
int Blue=BH*256+BL;


/* Display data values */
I2C_write(cLCD, 0x80, 0x89); // Red
Wire.beginTransmission( cLCD );
Wire.write(0x40); Wire.write("R:");
digit5Print(Red);
Wire.endTransmission();

I2C_write(cLCD, 0x80, 0xC1); // Green
Wire.beginTransmission( cLCD );
Wire.write(0x40); Wire.write("G:");
digit5Print(Green);
Wire.endTransmission();

I2C_write(cLCD, 0x80, 0xC9); // Blue
Wire.beginTransmission( cLCD );
Wire.write(0x40); Wire.write("B:");
digit5Print(Blue);
Wire.endTransmission();


/* Set Backlight color */
int mx_val=max(Red,Green); // Select Max_Value
mx_val=max(mx_val,Blue);
// set backlight color by the ratio of RGB
I2C_write(bLCD, 0x04, (byte)((float)Red/(float)mx_val*255.0)); // R
I2C_write(bLCD, 0x03, (byte)((float)Green/(float)mx_val*255.0)); // G
I2C_write(bLCD, 0x02, (byte)((float)Blue/(float)mx_val*255.0)); // B


/* UART print */
uTx_str("RGB: ");
uTx_digit5(Red);uTx_byte(','); //R,
uTx_digit5(Green);uTx_byte(','); //G,
uTx_digit5(Blue); //B
uTx_byte(0x0D); uTx_byte(0x0A); // CR,LF

delay(1000);

} //loop end

/* LCD Display 5_digit number, Ascii cord */
void digit5Print( int d){
Wire.write(d/10000+0x30);
Wire.write((d%10000)/1000+0x30);
Wire.write((d%1000)/100+0x30);
Wire.write((d%100)/10+0x30);
Wire.write(d%10+0x30);
}


/* uart Tx character string*/
void uTx_str( char d[]){
for(byte i=0; i < sizeof(d)+1; i++){
uTx_byte(d[i]);
}
}

/* uart Tx 5_digit number, Ascii cord */
void uTx_digit5( int d){
uTx_byte(d/10000+0x30);
uTx_byte((d%10000)/1000+0x30);
uTx_byte((d%1000)/100+0x30);
uTx_byte((d%100)/10+0x30);
uTx_byte(d%10+0x30);
}

/* uart Tx 1_byte */
void uTx_byte(byte d){
digitalWrite(uTx_pin, LOW); // start bit
delayMicroseconds(uTx_bms);
for (byte i=0; i < 8; i++){ // data bit0-7
digitalWrite(uTx_pin, bitRead(d,i));
delayMicroseconds(uTx_bms);
}
digitalWrite(uTx_pin, HIGH); // 1 stop bit
delayMicroseconds(uTx_bms);
}