I2C で温度センサ TMP102 を接続
まずは I2C を使った外部デバイスとの接続を試してみます.接続するデバイスは、以前に Raspberry pi pico との接続を確認した TMP102 のモジュールとしました.ハードウェア接続
Longan Nano と TMP102 モジュール間の接続は、I2C と電源・GND 端子の4本のみになります.どちらの基板上にも端子名のシルク表示がありますので、それに従って TMP102 モジュールの SCL / SDA 端子を Longan Nano の B6 / B7 端子に、TMP102 モジュールの GND / 1.4-3.6V 端子を Longan Nano の G / 3V3 端子にそれぞれ接続します.ADD0端子はオープンとしていますので、I2C スレーブアドレスは 0x48 となります.ソフトウェア
Platform IO IDE で作成したプロジェクトの main.c に I2C 周りの関数を追加します.main() 内で定期的に上記関数を読んでセンサにアクセスし温度データを取得、LCD に表示しています.static void i2c0_config(void); static int i2c_write(uint8_t i2cAddress, const uint8_t *data, size_t size); static int i2c_read(uint8_t i2cAddress, uint8_t *data, size_t size); /* I2C の初期設定(I2C0, SCL = 100kHz) */ static void i2c0_config(void) { i2c_clock_config(I2C0, 100000, I2C_DTCY_2); i2c_mode_addr_config(I2C0, I2C_I2CMODE_ENABLE, I2C_ADDFORMAT_7BITS, 0); i2c_enable(I2C0); i2c_ack_config(I2C0, I2C_ACK_ENABLE); } /* I2C 書き込み */ static int i2c_write(uint8_t i2cAddress, const uint8_t *data, size_t size) { while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) ; // wait until I2C bus is idle i2c_start_on_bus(I2C0); // send a start condition to I2C bus while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)); // wait until SBSEND bit is set i2c_master_addressing(I2C0, i2cAddress << 1, I2C_TRANSMITTER); // send slave address to I2C bus while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) ; // wait until ADDSEND bit is set i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); // clear ADDSEND bit while(!i2c_flag_get(I2C0, I2C_FLAG_TBE)); // wait until the transmit data buffer is empty for(size_t i = 0 ; i < size ; i++) { i2c_data_transmit(I2C0, data[i]) ; // data transmission while(!i2c_flag_get(I2C0, I2C_FLAG_TBE)); // wait until the TBE bit is set } i2c_stop_on_bus(I2C0); // send a stop condition to I2C bus while(I2C_CTL0(I2C0) & 0x0200); // wait until stop condition generate return 0; } /* I2C 読み出し */ static int i2c_read(uint8_t i2cAddress, uint8_t *data, size_t size) { while(i2c_flag_get(I2C0, I2C_FLAG_I2CBSY)) ; // wait until I2C bus is idle i2c_start_on_bus(I2C0); // send a start condition to I2C bus while(!i2c_flag_get(I2C0, I2C_FLAG_SBSEND)); // wait until SBSEND bit is set i2c_master_addressing(I2C0, i2cAddress << 1, I2C_RECEIVER); // send slave address to I2C bus while(!i2c_flag_get(I2C0, I2C_FLAG_ADDSEND)) ; // wait until ADDSEND bit is set i2c_flag_clear(I2C0, I2C_FLAG_ADDSEND); // clear ADDSEND bit for(size_t i = 0 ; i < size ; i++) { if(i == (size - 1)) // wait until the second last data byte is received into the shift register { while(!i2c_flag_get(I2C0, I2C_FLAG_BTC)); i2c_ack_config(I2C0, I2C_ACK_DISABLE); // disable acknowledge } while(!i2c_flag_get(I2C0, I2C_FLAG_RBNE)) ; // wait until the RBNE bit is set data[i] = i2c_data_receive(I2C0) ; // read a data from I2C_DATA } i2c_stop_on_bus(I2C0); // send a stop condition to I2C bus while(I2C_CTL0(I2C0) & 0x0200) ; // wait until stop condition generate i2c_ack_config(I2C0, I2C_ACK_ENABLE); // enable acknowledge return 0; }
int main(void) { u8 data[2]; u8 buf[12]; longan_led_init(); Lcd_Init(); // LCD を初期化 LCD_Clear( CYAN ); // LCD をクリア BACK_COLOR = BLACK; // 文字の背景色 rcu_periph_clock_enable(RCU_I2C0); gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7); //I2C0 i2c0_config(); while(1) { i2c_read(0x48, data, 2); snprintf(buf, 12, "Temp = %d.", data[0]); LCD_ShowString( 5, 10, buf, GREEN ); /* turn on builtin led */ longan_led_on(); delay_1ms(100); /* turn off uiltin led */ longan_led_off(); delay_1ms(100); } }
実行結果
参考
プログラムの作成にあたっては、以下を参考とさせていただきました.デバイスビジネス開拓団
MuellerA /LonganNanoTest
1件のコメント