ちょっとTea Time!? PICO(RP2040)を思い出してみる(備忘録) 2024.2.15
Raspberry Pi PICOなるものが出て、飛びついたものの、
いまだにPICばかりつかっています。というのも、PICでできることが
PICOで出来ないとソフト移植もままならないので、そこが完全に
確認できていなかったからです。まずはPICOでも出来るでしょうが、
課題はやり方を知らないということです。
そこで、ここでは備忘録として、PICOの使い方についてすこし調べてみました。
<過去の記事>
ちょっとTea Time !? Raspberry Pi のPICOを動かしてみる。 2021.8.5
ちょっとTea Time!? PICOの開発環境を揃える(備忘録) 2022.7.10
ちょっとTea Time!? 秋月のRP2040マイコンボードを動かしてみる! 2023.3.1
こちらも備忘録がわりに貼り付けておきました。
1.インターバルタイマ割り込みは止められるの?
インターバルタイマー割り込みはタクトスイッチやエンコーダの接点を定期的に調べるために
1ms間隔で必ずといっていいほど使っているのですが、赤外線リモコンの受信ONを確認すれば、
そこからは割り込みを停止して、赤外線受信に専念するようにしています。というのも、赤外線の
リモコンコードは少なくとも数10msありますので、再帰的に割り込みがかかるとややこしいからです。
PICOでは disable_interrupts(INT_TIMER0) enable_interrupts(INT_TIMER0) で
タイマー割り込みの停止、再開の関数がありました。
PICOではどうすればいいのだろう?
ということで、あれこれ調べると、 ありました。
まずは、割り込みの種類で番号は割り当てられています。
そして、割り込みの停止、再開は
irq_set_enabled(割り込み種類の番号,0:停止 1:再開)
という関数で行えるようです。
サンプルプログラムで100usでタイマー割り込みをかけますが、
割り込みルーチンの中で、50usの処理と割り込みを止めて200usほどの処理を行うような
ことをしてみました。
GPIOの出力を観察すると、100us毎の割り込みですが、250us毎の
処理になっており割り込みが停止していることがわかりました。
なお、割り込みから復帰すると、すでにタイマー割り込みのトリガが
かかっている状態になっている様子なので、直ぐに再度割り込み処理が行われるようです。
// サンプルプログラム |
上:GPIO0、下:GPIO1 |
2.FLASHの書き込み速度は?
PICで設定値を記録・読み出しするときはEEPROMを使います。
関数は
write_eeprom(int16 adrs, int data)
read_eeprom(int16 adrs)
です。write関数は1バイトあたり概ね数msかかりますが、PICOの場合はどうだろう?
PICOではeepromの代わりにflashメモリーを使いますが、書き込みの前に
消去をする必要があります。そして消去の単位が4096byteと、書き込みの単位が
256byteと大きいです。どのくらいの時間がかかるのかな?
あまり時間がかかるようだと、どこかにバッファーをもたせて、適当な
タイミングでまとめて書くようなことをしなければなりません。
一度調べておきましょう。
まずはflashメモリをつかうために、CMakeLists.txt を一部編集(追記)します。
下記のように1024Byte分の領域を仮定して、書き込む時間を測定してみました。
書き込みにかかっているときのGPIOをONにしてオシロで時間を計測です。
で、結果は1024Byteの書き込みで35msほどかかりました。
こりゃ、PICとおなじようにEEPROMのように扱うためには、ちょっとした
サブルーチンをつくる必要がありそうです。
#include <stdio.h> #include "pico/stdlib.h" #include "hardware/pio.h" #include "hardware/interp.h" #include "hardware/timer.h" #include "hardware/watchdog.h" #include "hardware/clocks.h" #include "hardware/flash.h" #define GPIO_00 (0) #define FLASH_TARGET_OFFSET (0x1f0000) uint8_t write_data[1024]; void main( void ) { gpio_init( GPIO_00 ); gpio_set_dir( GPIO_00, GPIO_OUT ); while( true ) { gpio_put(GPIO_00,1); flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE); flash_range_program(FLASH_TARGET_OFFSET, write_data, FLASH_PAGE_SIZE * 4); gpio_put(GPIO_00,0); busy_wait_us_32(1000); } } |
リハビリ〜 2024.8.12
しばらく半田ゴテもソフトも組んでいなかったので、リハビリがてら再開です。
手始めにPICOでのソフトを充実させようかと思っていますが、過去に調べたことが
色々と間違ったことがわかりました。
1.タイマ−割り込みの停止番号は3
最初はCLOCK_IRQの17と思い込んでいましたが、実際に動かしてみても割り込みが停止しません。
で、色々と調べるとTIMER_IRQ_3の3番が該当することがわかりました。
ただ、新たにわかったことは割り込みの停止は素直に動きますが、割り込みを再開するとなぜか、
ある一定時間の間に頻繁に割り込みがかかってしまいます。そのため、一定時間(1ms程度)は
割り込みを再開しても、割り込み処理は単にすぐにリターンするようにしたほうが良さそうです。
まあ、あくまでもその場しのぎの処理ですが。
2.GPIOの入力はプルダウンがデフォルト?
GPIOに赤外線リモコンの受光モジュールを接続してもうまく動きません。
調べてみると、信号端子のレベルが1.6Vと中途半端です。どうやら、GPIOを
入力設定にしたときに、開放時の電圧レベルが0Vになっています.ひょっとして、
プルダウンがかかっているのかもしれません。
ということで、GPIOを設定したときには、プルダウンあるいはプルアップを明示的に
示したほがいいかもしれません。
PICOをつかってソフト作成のリハビリ中です。
念のため、GPIOのプルアップ、プルダウン抵抗値を調べてみました。抵抗値はどちらもおよそ30kΩ程度のようです。
いづれにしても、単に入力設定しただけではプルダウンになっているようです。
GPIO | 定義 | 開放時 電圧 |
47kΩ 負荷(GND) |
47kΩ 負荷(VCC) |
備考 |
11 | 入力 | 約70mV | 0V | 1.250V | 入力設定だけではプルダウンになっている。 |
12 | 入力+プル禁止 | 約1.2V | 20mV | 3.247V | プル禁止にすると入力はフロート状態 |
13 | 入力+プルアップ | 3.3V | 1.973V | プルアップ抵抗は31kΩ程度 | |
14 | 入力+プルダウン | 0V | 1.242V | プルダウン抵抗は28kΩ程度 |
(つづく?)