0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

BluePill(STM32F103C)でデータを保存する(EEPROMエミュレート)

Posted at

BluePill(STM32F103C)でデータを保存する

BluePill はこれ
https://www.amazon.co.jp/dp/B01CZL6RGC/ref=cm_sw_em_r_mt_dp_U_OMcgFbSNZDFBN

以下、やったこと

BluePillのArduino化

こちらのサイトを参考にしました。
https://ht-deko.com/arduino/stm32f103c8t6.html

で、ST-link使ってブートローダも入れました。

Arduinoでデータ保存ができるか調べた

Arduinoは、EEPROMにデータを保存して電源が切れてもデータを維持できるらしい。
でも、BluePillには無いらしい。
かわりにチップ内のフラッシュメモリを利用してEEPROMをエミュレートできるらしい。

やってみた。

基本的なことは、
hardware>Arduino_STM32>STM32F1>libraries>EEPROM>EEPROM_example
にサンプルがあったので、それをちょっといじるだけでした。

Arduino

# include <EEPROM.h>

int ledPin =  PC13;    // LED connected to digital pin 13
const char HELP_MSG[] = "Press :\r\n" \
			" 0 display configuration\r\n" \
			" 1 set configuration to 0x800F800 / 0x800FC00 / 0x400 (64k flash)\r\n" \
			" 2 set configuration to 0x801F800 / 0x801FC00 / 0x400 (128k flash)\r\n" \
			" 3 write/read variable\r\n" \
			" 4 increment address\r\n" \
			" 5 display pages top/bottom\r\n" \
			" 6 initialize EEPROM\r\n" \
			" 7 format EEPROM\r\n" \
			" 9 read variable\r\n";
uint16 DataWrite = 0;
uint16 AddressWrite = 0x10;

void setup()
{
	// initialize the digital pin as an output:
	pinMode(ledPin, OUTPUT);
  Serial.begin(115200);
  delay(10000);
	Serial.print(HELP_MSG);

}

void loop()
{
	uint16 Status;
	uint16 Data;

	while (Serial.available())
	{
		char cmd = (char)Serial.read();
		Serial.println(cmd);
		if (cmd == '0')
		{
			DisplayConfig();
		}
		else if (cmd == '1')
		{
			EEPROM.PageBase0 = 0x800F800;
			EEPROM.PageBase1 = 0x800FC00;
			EEPROM.PageSize  = 0x400;
			DisplayConfig();
		}
		else if (cmd == '2')
		{
			EEPROM.PageBase0 = 0x801F800;
			EEPROM.PageBase1 = 0x801FC00;
			EEPROM.PageSize  = 0x400;
			DisplayConfig();
		}
		else if (cmd == '3')
		{
			Status = EEPROM.write(AddressWrite, DataWrite);
			Serial.print("EEPROM.write(0x");
			Serial.print(AddressWrite, HEX);
			Serial.print(", 0x");
			Serial.print(DataWrite, HEX);
			Serial.print(") : Status : ");
			Serial.println(Status, HEX);

			Status = EEPROM.read(AddressWrite, &Data);
			Serial.print("EEPROM.read(0x");
			Serial.print(AddressWrite, HEX);
			Serial.print(", &..) = 0x");
			Serial.print(Data, HEX);
			Serial.print(" : Status : ");
			Serial.println(Status, HEX);

			++DataWrite;
		}
    else if (cmd == '9')
    {
      Status = EEPROM.read(AddressWrite, &Data);
      Serial.print("EEPROM.read(0x");
      Serial.print(AddressWrite, HEX);
      Serial.print(", &..) = 0x");
      Serial.print(Data, HEX);
      Serial.print(" : Status : ");
      Serial.println(Status, HEX);
    }
		else if (cmd == '4')
		{
			++AddressWrite;
		}
		else if (cmd == '5')
		{
			DisplayPages(0x20);
			DisplayPagesEnd(0x20);
		}
		else if (cmd == '6')
		{
			Status = EEPROM.init();
			Serial.print("EEPROM.init() : ");
			Serial.println(Status, HEX);
			Serial.println();
		}
		else if (cmd == '7')
		{
			Status = EEPROM.format();
			Serial.print("EEPROM.format() : ");
			Serial.println(Status, HEX);
		}
		else
			Serial.print(HELP_MSG);
	}
	digitalWrite(ledPin, HIGH);
	delay(500);
	digitalWrite(ledPin, LOW);
	delay(500);
}

void DisplayConfig(void)
{
	Serial.print  ("EEPROM.PageBase0 : 0x");
	Serial.println(EEPROM.PageBase0, HEX);
	Serial.print  ("EEPROM.PageBase1 : 0x");
	Serial.println(EEPROM.PageBase1, HEX);
	Serial.print  ("EEPROM.PageSize  : 0x");
	Serial.print  (EEPROM.PageSize, HEX);
	Serial.print  (" (");
	Serial.print  (EEPROM.PageSize, DEC);
	Serial.println(")");
}

void DisplayHex(uint16 value)
{
	if (value <= 0xF)
		Serial.print("000");
	else if (value <= 0xFF)
		Serial.print("00");
	else if (value <= 0xFFF)
		Serial.print("0");
	Serial.print(value, HEX);
}

void DisplayPages(uint32 endIndex)
{
	Serial.println("Page 0     Top         Page 1");

	for (uint32 idx = 0; idx < endIndex; idx += 4)
	{
		Serial.print  (EEPROM.PageBase0 + idx, HEX);
		Serial.print  (" : ");
		DisplayHex(*(uint16*)(EEPROM.PageBase0 + idx));
		Serial.print  (" ");
		DisplayHex(*(uint16*)(EEPROM.PageBase0 + idx + 2));
		Serial.print  ("    ");
		Serial.print  (EEPROM.PageBase1 + idx, HEX);
		Serial.print  (" : ");
		DisplayHex(*(uint16*)(EEPROM.PageBase1 + idx));
		Serial.print  (" ");
		DisplayHex(*(uint16*)(EEPROM.PageBase1 + idx + 2));
		Serial.println();
	}
}

void DisplayPagesEnd(uint32 endIndex)
{
	Serial.println("Page 0     Bottom      Page 1");

	for (uint32 idx = EEPROM.PageSize - endIndex; idx < EEPROM.PageSize; idx += 4)
	{
		Serial.print  (EEPROM.PageBase0 + idx, HEX);
		Serial.print  (" : ");
		DisplayHex(*(uint16*)(EEPROM.PageBase0 + idx));
		Serial.print  (" ");
		DisplayHex(*(uint16*)(EEPROM.PageBase0 + idx + 2));
		Serial.print  ("    ");
		Serial.print  (EEPROM.PageBase1 + idx, HEX);
		Serial.print  (" : ");
		DisplayHex(*(uint16*)(EEPROM.PageBase1 + idx));
		Serial.print  (" ");
		DisplayHex(*(uint16*)(EEPROM.PageBase1 + idx + 2));
		Serial.println();
	}
}

LEDのピン番号を修正したりした程度で、プログラムはあまり変えてません。(読み取りだけの機能は追加しました)
ただ、元のサンプルではアドレスが違っていたようで保存が出来なかったので、下記URLを参考に変えました。

フラッシュメモリはプログラムも書き込まれる場所なので、後ろの2ページ(2kバイト)を保存領域にするようです。

うちのBluePillは64kだったようなので、0x800F800と0x800FC00になるみたいでした。

上記プログラムを実行すると、HELPがシリアルモニタにでるので、64kの場合は1をセット、128kの場合は2をセットして、そのあと3をセットすることで保存と呼び出し(プラスデータの値を1加算)することができます。

あとは、電源を切って、もう一度起動して、1(または2)をセットしてから、9(呼び出しのみ)をするとちゃんとデータが保存できてました!

これで、サーボの初期パラメータを保存できる♪

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?