昇降圧DCDC SC8721モジュールをPIC12Fで電圧設定

カテゴリー: PIC  タグ:

ストロベリーリナックスで販売しているSC8721 可変型昇降圧DC-DCコンバータモジュールは2.7~22V入力で2.7~22V最大5A出力可能な優れモノです。

多回転トリマに交換してみたSC8721モジュール

基板上のトリマかI2Cで電圧設定できます。実装のトリマでは設定が荒いので多回転トリマに付け替えてみたりしていましたが、正確な電圧設定はI2Cを勧めているのでそっちにすることにしました。ネット上で実例が見当たらないので自分でやってみよう。

最初はESP32でつないでみた

電圧設定値は記憶されない

最初にESP32に試しにつなげてサクッと設定できたのでハイOK!と喜んだのですが、どうやら設定値は記憶しない、というか「記憶する」なんてどこにも書いていない。ただの早合点orz。

トリマを使わない場合は、電源ON毎にI2Cでセットするのだ。

↓はESP32、arduinoモードのコード

#include <Arduino.h>
#include <Wire.h>

#define LED_BUILTIN 19

void setup() {
	pinMode(LED_BUILTIN, OUTPUT);
	Wire.begin(); //I2Cをマスターとして動作させる
}

uint8_t	address = 0x62;
int	setvol = 530;	// 5.3V * 100

void loop() {
	int MSB = ((setvol-500)/2) >> 2;
	int LSB = ((setvol-500)/2) & 0x3;
	Wire.beginTransmission(address);
	Wire.write(0x3);		// regaddr:03
	Wire.write(MSB);		// reg03:0x64>>2
	Wire.write(0x18+LSB);	// reg04:0x18+0x64&mask(0x03)
	Wire.write(0x02);		// reg05:load
	Wire.write(0x80);		// reg06:I2C active
	Wire.endTransmission();  //送信を完了
	for(;;) {
		digitalWrite(LED_BUILTIN, HIGH);
		delay(100);
		digitalWrite(LED_BUILTIN, LOW);
		delay(100);
	}
}

PIC12F1822に変更して電源とセットにして使うことにする

電源ごとにESP32をセットにするわけにもいかないので、手元にあるMCUで小さいパッケージのPIC12F1822にしました。ハードウエアI2C持っていて、コスト面でも多回転トリマと大して変わらない。

PICのプログラミング中

というわけで配線図。I2C用MCUの電源5VはDCDCから出ていて便利。

I2Cのプルアップですが、PICの場合はポート入力して内蔵プルアップを使うという反則技が使える場合がありますが、抵抗値が高いので外付けでつけたほうが良いです。

そしてPICのファーム。設定電圧は5.3V。ちょっと余計なものも入っています。ESP32のWireと違うところはアドレス指定が8ビットなので左シフト必要。あとはほぼ同じ。

#include <htc.h>
#include <stdio.h>
#include <stdlib.h>

// Config1
#pragma config FOSC     = INTOSC	// 内部クロック
#pragma config WDTE     = OFF		// WDT OFF
#pragma config PWRTE    = ON		// 64ms startuptimer
#pragma config MCLRE    = ON		// MCLR pin ON
#pragma config CP       = OFF		// Code Protect off
#pragma config CPD      = OFF		// Data Prorect off
#pragma config BOREN    = ON		// BrawnOut ON
#pragma config CLKOUTEN = OFF		// RA4 on
#pragma config IESO     = OFF		// IESO off
#pragma config FCMEN    = OFF		// FCM off

// Config2
#pragma config WRT    = OFF			// Flash protect off
#pragma config PLLEN  = OFF			// PLLはOSCCONで設定する
#pragma config STVREN = ON			// スタックフローリセット
#pragma config BORV   = HI			// BO電圧:2.5V
#pragma config LVP    = OFF			// LVP off

#ifndef _XTAL_FREQ
	#define _XTAL_FREQ 32000000
#endif

void mloop();
void wait_timec(unsigned int n);
void strcopyr(volatile char *s, char *d);

volatile unsigned int	timec;

void __interrupt ISR() {    // 1ms timer
	if (TMR0IF == 1) {
		TMR0 = 6;
		if (timec != 0) timec--;
		TMR0IF = 0;			// TMR0割込みをクリア
	}
}

uint8_t	address = 0x62;     // SC8721 addr
int16_t	setvol = 530;       // 設定電圧5.3V * 100

// I2Cバス初期化
void i2c_enable(void) {
    SSP1STAT = 0b10000000;	// I2C 100kHz
    SSP1ADD = 79;			// I2Cバス Baud rate,  32MHz/(79+1)/*4 = 100kHz
    SSP1CON1 = 0b00111000;	// I2C enable,Master
}

// スタートコンディション
void i2c_start(void){
    SSP1CON2bits.SEN = 1;	//  Start Condition Enabled bit
	while(SSP1CON2bits.SEN);// Start condition 確認
}

// ストップコンディション
void i2c_stop(void){
    SSP1CON2bits.PEN = 1;	// Stop Condition Enable bit
    while(SSP1CON2bits.PEN);// Stop condition 確認
}

// 1byte write
void i2c_send_byte(const unsigned char data){
	PIR1bits.SSP1IF = 0;	// 終了フラグクリア
	SSP1BUF = data;			// データセット
	while(!PIR1bits.SSP1IF);// 送信終了待ち
}

void mloop() {
	int16_t MSB = ((setvol-500)/2) >> 2;    // 電圧値MSB
	int16_t LSB = ((setvol-500)/2) & 0x3;   // 電圧値LSB

	__delay_ms(50);
	i2c_enable();					// I2C初期化
	i2c_start();					// スタートコンディション
	i2c_send_byte(0x62<<1);			// ADDR write
	i2c_send_byte(0x03);			// reg0x3指定(ここから連続アドレス)
	i2c_send_byte((int8_t)MSB);		// MSB write(0x3)
	i2c_send_byte(0x18+(int8_t)LSB);// LSB write(0x4)
	i2c_send_byte(0x02);			// 0x2 write(0x5)
	i2c_send_byte(0x80);			// 0x8 write(0x6)
	i2c_stop();						// スタートコンディション
	
	for(;;) {   // 書き込み終了Lチカ(不要)
		LATAbits.LATA5=1;
		wait_timec(100);
		LATAbits.LATA5=0;
		wait_timec(100);
	}
}

void main(void) {
    OSCCON = 0b11110000;		// 外部オシレーター 8MHz×4=32MHz(PLLはここで設定)
	LATA = 0;
    TRISA  = 0b00000110;		// RA1,2inにしてI2Cのpullup
	ANSELA = 0b00000000;		// All digital

	// TMR1 set
//	T1CON = 0b00110001;			// Timer1:FOSC/4/8,T1on
//	TMR1H = 0;
//	TMR1L = 0;
	// TMR0 set
	OPTION_REG = 0b000000100;   // TMR0:int,1/32
	TMR0 = 0x6;                 // 1kHz
//	PIE1bits.TMR1IE = 1;
	INTCONbits.TMR0IE = 1;      // TMR0 interrupt
	INTCONbits.PEIE = 1;
	GIE = 1;
	mloop();
}

void wait_timec(unsigned int n) {
	timec = n;
	while(timec != 0);
}

ソフトウェアI2Cにしてさらにコストダウン(未定)

設定5.3Vに対し実際の出力は5.34V。

I2C通信といっても、アドレス含めて6バイト、それも送信のみなので、PIC10Fにすればさらにローコスト。

いつかやろう。

お気軽にコメントをどうぞ。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)