keiske-hongyoのアイコン画像
keiske-hongyo 2025年04月20日作成 (2025年04月20日更新) © CC BY-SA 4+
製作品 製作品 閲覧数 351
keiske-hongyo 2025年04月20日作成 (2025年04月20日更新) © CC BY-SA 4+ 製作品 製作品 閲覧数 351

I2C制御による2桁7セグメント表示器の製作

I2C制御による2桁7セグメント表示器の製作

はじめに

秋月電子で販売されたいるCH32V003を使用して、I2C通信、特にスレーブを活用について調べたいと思い、I2Cのスレーブ用の7セグメントの表示器を製作に取り組みました。

部品について

部品については表1の部品を使いました。7セグメントLEDの点灯制御にはダイナミック点灯制御を使用しています。

部品名 型番・値 備考
マイコン CH32v003J4M6 8ピン
トランジスタアレイ TBD62783AFG 8ch ソースタイプ DMOS
トランジスタアレイ TBD62083AFG 8ch シンクタイプ DMOS
赤色7セグメントLED A-2301SRD-A アノードコモン
チップ抵抗 100Ω,270Ω 7セグメント電流制限用
チップ抵抗 4.7kΩ I2Cプルアップ抵抗用
チップ抵抗 1kΩ 電源確認用LED電流制限用
チップLED OSO50805C1C オレンジ 7セグメント電源確認
チップLED OSY50805C1C 黄色 マイコン用電源確認
コネクタ S3B-XH-A 制御プログラム書込み用
コネクタ S4B-XH-A I2Cデータ用
コネクタ S2B-XH-A 7セグメント電源用

回路図

回路図は下の図のようになります。
回路図
I2Cで受け取った7セグメントの表示データを74HC595でシリアル出力にして、ソース型のトランジスタアレイとシンク型のトランジスタアレイを使用して7セグメントLEDをダイナミック点灯をできるように回路を製作しています。
今回製作した回路を基板業者に発注して基板を製作しました。しかし、私の確認不足で設計にミスがあり、ジャンパををして修正しました。(回路図の回路は今回修修正したものの回路図です。)
製作した基板
パターン修正

プログラムについて

今回のCH32V003J4M6を利用したプログラム作成にはPlatformIOとFrameworkにch32v003funを利用して作成しました。CH32V003J4M6をI2Cのスレーブで動作させ、マスタから7セグメントの表示データを受け取り、1msごとに割込を入れて、7セグメントLEDをダイナミック点灯させています。メインの部分だけを掲載しています。プログラム全体は私のGitHubのリポジトリに置いてあるので見ていただけたらと思います。

メインプログラム

#include "ch32v003fun.h" #include <stdint.h> #include <stdio.h> #include <systick.h> #include <vcruntime.h> #include "i2c_slave.h" #define SER PC4 // シリアルデーア #define RCLK PA2 // 書き込み #define LATCH PA1 // ラッチ #define DIGIT 2 // 桁数 volatile unsigned int timer1; volatile unsigned char dig; volatile uint8_t i2c_registers[32] = {0x00}; // 74HC595 データ出力処理 void shiftOut(unsigned short data){ unsigned char i; // LATCH OFF funDigitalWrite(LATCH, FUN_LOW); // Write Data for(i=0;i<16;i++){ //if((data >> i) & 0x01){ // LSB First if((data << i) & 0x8000){ // MSB First funDigitalWrite(SER, FUN_HIGH); } else { funDigitalWrite(SER, FUN_LOW); } // Clock HIGH funDigitalWrite(RCLK, FUN_HIGH); // Clock LOW funDigitalWrite(RCLK, FUN_LOW); } // LATCH ON funDigitalWrite(LATCH, FUN_HIGH); } int main(void) { // システム初期化 -> 必ずいる! SystemInit(); // 待機時間(ブートローダ待ち) //Delay_Ms(100); // // SysTick初期設定(1ms割込設定) systick_init(); // Enable GPIOA,GPIOC, GPIOD and TIM1 RCC->APB2PCENR |= (RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC); // PA1 is 10MHz Output alt func, push-pull(PWM CH2N) funPinMode(PA1, GPIO_CFGLR_OUT_10Mhz_PP); funPinMode(PA2, GPIO_CFGLR_OUT_10Mhz_PP); funPinMode(PC4, GPIO_CFGLR_OUT_10Mhz_PP); funPinMode(PC1, GPIO_CFGLR_OUT_10Mhz_AF_OD); // SDA funPinMode(PC2, GPIO_CFGLR_OUT_10Mhz_AF_OD); // SCL SetupI2CSlave(0x9, i2c_registers, sizeof(i2c_registers), NULL, NULL, false); while (1) { } } /* * SysTick ISR - must be lightweight to prevent the CPU from bogging down. * Increments Compare Register and systick_millis when triggered (every 1ms) * NOTE: the `__attribute__((interrupt))` attribute is very important */ void SysTick_Handler(void) __attribute__((interrupt)); void SysTick_Handler(void) { // Increment the Compare Register for the next trigger // If more than this number of ticks elapse before the trigger is reset, // you may miss your next interrupt trigger // (Make sure the IQR is lightweight and CMP value is reasonable) SysTick->CMP += SYSTICK_ONE_MILLISECOND; // 割込フラグクリア SysTick->SR = 0x00000000; // タイマ値更新 timer1++; // ダイナミック点灯制御 if((dig++) >= DIGIT) dig = 0; switch (dig) { // 1の位 case 0x00: shiftOut( 0x0200 | (unsigned short)i2c_registers[dig]); break; // 10の位 case 0x01: shiftOut( 0x0400 | (unsigned short)i2c_registers[dig]); break; default: break; } }

最後に

今回はCH32V003のI2Cスレーブで動作させる実験を兼ねて7セグメントLEDの表示器を製作しました。価格が安いマイコンで簡単にI2Cが利用できるので、制御系の回路を作るときには役に立つと思います。皆さんの何か参考になれば嬉しいです。

keiske-hongyoのアイコン画像
マイコンを活用した電子工作に取り組んでいます。 もしよかったら、色々とアドバイスをいただけたらと思います。
ログインしてコメントを投稿する