PSoC 3 で多重割り込みを試す [PSoC]

PSoC 3 は、 8051 という CPU を搭載しています。 他の CPU と同じように 8051 も割り込みという仕掛けをもっていて、 PSoC 3 の場合には、複数の割り込み要求に対して 8 レベルの優先順位を割り当てることができます。 この記事では、優先順位を設定することによって、多重割り込みの実験を行います。
実験プロジェクト
今回の実験では、このような回路を作成しました。 回路は、二つの周期割り込みと状態表示用の LED 出力と LCD 出力から構成されており、 CY8CKIT-030 でそのまま試すことができます。
周期割り込み ISR_slow は、 1Hz 周期のクロック Clock_slow の立ち上がりで駆動されます。 また、周期割り込み ISR_fast は、 10Hz 周期のクロック Clock_fast の立ち上がりで駆動されます。
クロックの設定
これらのクロックは、バスクロックに比べるとはるかに遅い周波数のクロックです。 デフォルトの設定にすると、 Internal Low-speed Oscillator (ILO) と呼ばれる 1kHz のクロックを使用することになりますが、 ILO クロックは精度が著しく低くなっています。 そこで、 Design-wide クロックと呼ばれる 60kHz のクロックを作成して、このクロックを分周して 1Hz と 10Hz のクロックとしています。 こうすると、比較的高精度な Internal Main Oscillator (IMO) をクロック源とするクロックを得ることができます。 クロックは、 CYDWR ファイルの Clock タグから設定することができます。
ソースコード
ソースコードは、二つの Interrupt Service Routine (ISR) と main 関数で構成されています。
/* ========================================
*
* Copyright noritan.org, 2012
* All Rights Reserved
* UNPUBLISHED, LICENSED SOFTWARE.
*
* CONFIDENTIAL AND PROPRIETARY INFORMATION
* WHICH IS THE PROPERTY OF NORITAN.ORG.
*
* ========================================
*/
#include <device.h>
uint16 n_ISR_slow = 0;
uint16 n_ISR_fast = 0;
CY_ISR(ISR_slow_func) {
n_ISR_slow++;
LED4_Write(1);
CyDelay(500); // Stay for 500msec
LED4_Write(0);
}
CY_ISR(ISR_fast_func) {
n_ISR_fast++;
LED3_Write(1);
CyDelay(10); // Stay for 10msec
LED3_Write(0);
}
void main()
{
/* Place your initialization/startup code here (e.g. MyInst_Start()) */
ISR_slow_StartEx(ISR_slow_func);
ISR_fast_StartEx(ISR_fast_func);
LCD_Start();
CyGlobalIntEnable; /* Uncomment this line to enable global interrupts. */
for(;;)
{
/* Place your application code here. */
LCD_Position(0, 0);
LCD_PrintDecUint16(n_ISR_slow);
LCD_PrintString(" ");
LCD_Position(1, 0);
LCD_PrintDecUint16(n_ISR_fast);
LCD_PrintString(" ");
}
}
/* [] END OF FILE */
割り込み処理ルーチン ISR_slow_func と ISR_fast_func は、割り込みが受付られた時に呼び出されます。 割り込みが実行されると、変数 n_ISR_slow または n_ISR_fast がインクリメントされ、割り込みが受け付けられた回数を示します。 ISR では、特別な処理を行っていませんが、処理を行うかわりに CyDelay 関数を呼び出して、時間稼ぎをおこなっています。 ISR_slow_func の場合、 CyDelay の処理時間は 500ミリ秒に設定されていますので、 CPU の実行時間の 50% を消費するということになります。 同じように、 ISR_fast_func は 10ミリ秒に設定されていますので、 10% の CPU 時間を消費します。 さらに、これらの ISR では、処理中に LED3 または LED4 を点灯させる処理を行っています。 LED の点灯状態をみると、割り込み処理の状態を知ることができます。
main 関数では、初期設定を行った後は、延々と LCD に変数 n_ISR_slow と n_ISR_fast の値を表示しています。 main 関数に許された CPU 時間は全体の 40% ですが、 LCD に数値を表示するには、十分な時間です。
デフォルトの優先順位を使った場合
デフォルトの状態では、二つの割り込みの優先順位はどちらも "7" に設定されています。 これは、片方の割り込みが処理されているときには、もう片方の割り込みは受け付けられないということを意味します。
この状態での処理をシーケンス図に描くとこのようになります。 ISR_slow が処理されている 500ミリ秒の間、 ISR_fast は受け付けられません。 そのため、一秒間に10回、 ISR_fast 割り込みの要求があるにもかかわらず、実際に受け付けられるのは、5回だけです。
LCD の表示を見ると、下段の n_ISR_fast が上段の n_ISR_slow の5倍の値を示します。 これは、一秒間に5回分の割り込みが受け付けられなかったことを示しています。
LED の点灯状態を見ると、 LED4 が消灯している時にかぎり、 LED3 が点灯(点滅)することがわかります。 また、 LCD の表示は main 関数本体で行っているため、 LED4 が消灯している時に更新されています。
以上のように、 ISR_slow の処理時間が長くなると、 ISR_fast が受け付けられず、割り込み要求をとりこぼしてしまうことがわかりました。
ISR_fast の優先順位を上げた場合
このままでは、 ISR_fast が想定通りに実行されないので、 ISR_slow が処理されている間でも ISR_fast 割り込みが受け付けられるようにします。 そのためには、 ISR_fast の優先順位を ISR_slow よりも高くしてやります。
この優先順位の割り当ては、もちろん PSoC Creator の GUI から行います。 CYDWR ファイルの Interrupt タグを開くと、優先順位を設定するための画面が現れます。 デフォルトの状態では、優先順位は "7" になっています。 数字が小さいほうが優先順位が高くなりますので、ここでは ISR_fast の優先順位を一つ上げて "6" に設定します。
すると、 ISR_slow 割り込みの実行中でも、さらに ISR_fast 割り込みの処理が行われるようになります。 ISR_fast の処理は、一秒間に10回受け付けられます。
LCD の表示を見ると、下段の n_ISR_fast が上段の n_ISR_slow の10倍の値を示します。 これは、 ISR_fast 割り込みが 10Hz の周期で受け付けられたことを示しています。 また、 LED4 が点灯している間でも LED3 が点滅する様子がわかります。 ISR_slow 割り込みの処理中でも ISR_fast 割り込みが受け付けられているからです。
本日の結論
以上のように、割り込みの優先順位を変更することで、割り込み処理中でもほかの割り込みが受け付けられる様子が観測できました。
しかしながら、本来は、割り込み処理に今回の例のように重い処理を書くことは推奨されません。 それは、 ISR_slow が受けつけられている間、 LCD の表示が更新されなかったことからわかるように、割り込みが受け付けられると、メインループの処理が完全に止まってしまうからです。
こういった問題点を解決するための方法については、また、いずれ。
プロジェクト・アーカイブ
関連文献
![トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌] トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌]](http://ecx.images-amazon.com/images/I/51LkFlElOmL._SL160_.jpg)
トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌]
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2012/04/19
- メディア: 雑誌
続・PSoC 3 で RS フリップフロップを作ろう [PSoC]

コメント欄で質問をもらいましたので、今回は、その解答編です。
質問: Verilog 記述に assign を使ったらどうなりますか。
前回の記事では、ゲートレベルは回路図で、 RTL レベルは Verilog で記述しました。 Verilog にも、ゲートレベルで記述する機能はあります。 この時に使用される構文が、 assign を使う continuous assignment と呼ばれる代入文です。 この代入文は、 wire に対して値を割り当てますので、事実上組み合わせ論理として合成されることになります。 具体的には、以下のような記述になります。
//`#start header` -- edit after this line, do not edit this line
// ========================================
//
// Copyright noritan.org, 2012
// All Rights Reserved
// UNPUBLISHED, LICENSED SOFTWARE.
//
// CONFIDENTIAL AND PROPRIETARY INFORMATION
// WHICH IS THE PROPERTY OF NORITAN.ORG.
//
// ========================================
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
module RSFF (
q,
qb,
rb,
sb
);
//`#start body` -- edit after this line, do not edit this line
output q;
output qb;
input rb;
input sb;
assign qb = ~(q & rb);
assign q = ~(qb & sb);
//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line
この記述を使って論理合成を行うとこのような構成の Look Up Table (LUT) が生成されました。 これは、前回、ゲートを使って回路図を書いた場合と同じ結果です。 論理合成では、回路図でも、 Verilog でも、内部で論理式を生成して、その論理式と等価な回路を合成していきます。 そのため、論理的に等価な内容であれば、回路図でも Verilog 記述でも同じ結果が得られます。
前回と今回の記事に作成したアーカイブは、このリンクにあります。
関連文献
![トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌] トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌]](http://ecx.images-amazon.com/images/I/51LkFlElOmL._SL160_.jpg)
トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌]
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2012/04/19
- メディア: 雑誌
PSoC 3 で RS フリップフロップを作ろう [PSoC]

ひょんなことから、 Verilog HDL で RS フリップフロップを記述してみました。
記事を書くのは、久しぶりだね。 ちゃんと、書けるかな。
Verilog で RS フリップフロップを書きたい
Twitter で、「 Verilog で書いた RS フリップフロップが、うまく合成できない。」という声があがりました。 非同期順序回路を論理合成するのは、苦労ばかり多いのですが、試しに挑戦してみます。 使用する論理合成ツールは、大人の事情により、 PSoC Creator です。
ゲートで書いてみた
お題は、 Verilog の HDL で記述することだったのですが、まずは、 RS フリップフロップをゲートで書いて、どんな回路が合成されるのかを確認してみました。 ハードウェアには、 CY8CKIT-030 を使用しています。 二つのタクトスイッチを入力に、二つの LED を出力にしています。
合成中に以下のような警告が表示されました。
Warning-1361: The design contins a combinational loop. Check the design for unintentional latches. Breaking the loop at QB/main_2 --> QB/q
The static timing analyzer reported a warning. See the warning message for details. Additional information may be available in the timing report file.
これは、組み合わせ回路にループが存在するから、意図しないラッチが合成されるかも知れない、という警告です。 今回は、 RS-FF というラッチを合成するために書いたのですから、もちろん「意図しない」というわけではありません。 論理合成ツールは、ループが存在するままでは、タイミング制約を解決することができません。 そのため、勝手にループを切って処理してくれたようです。
合成された回路は、 Look Up Table (LUT) で実装され、その論理式は RPT ファイルにレポートされます。 この論理式を Programmable Logic Array (PLA) 形式に書き起こすと、このような回路になっています。 もとの回路からみると、かなり無駄に見えますが、論理積項数 (product term: pterm) は、 2 で収まっているので、良い合成結果と言えるでしょう。
HDL で書いてみた
では、本題に戻って、 Verilog HDL で RS フリップフロップを記述してみます。 最上位の回路図は、こんな風になっています。 箱の中身は、 Verilog で記述されています。
//`#start header` -- edit after this line, do not edit this line
// ========================================
//
// Copyright noritan.org, 2012
// All Rights Reserved
// UNPUBLISHED, LICENSED SOFTWARE.
//
// CONFIDENTIAL AND PROPRIETARY INFORMATION
// WHICH IS THE PROPERTY OF NORITAN.ORG.
//
// ========================================
`include "cypress.v"
//`#end` -- edit above this line, do not edit this line
module RSFF (
q,
qb,
rb,
sb
);
//`#start body` -- edit after this line, do not edit this line
output q;
output qb;
input rb;
input sb;
reg q;
reg qb;
always @(rb or sb or q or qb) begin
casez ({rb,sb})
2'b01: {q,qb} = 2'b01; // Reset
2'b10: {q,qb} = 2'b10; // Set
2'b11: {q,qb} = {q,qb}; // Hold
2'b00: {q,qb} = 2'b11; // Prohibited
endcase
end
//`#end` -- edit above this line, do not edit this line
endmodule
//`#start footer` -- edit after this line, do not edit this line
//`#end` -- edit above this line, do not edit this line
端子名を大文字で書くと、定数と認識されてしまったので、小文字で書きました。 動作記述のキーになっている部分は、 casez 構文です。 入力 rb と sb の値によって、 RS-FF の動作が変わります。
動作のうち、 Reset と Set は、わかりやすいので説明は不要でしょう。 Hold の場合には、出力 q と qb の値をフィードバックします。 このため、 always のリストには、 q および qb も追加してあります。 Prohibited は、通常の RS-FF では使用不可の組み合わせです。 この回路では、 NAND を使った場合の動作に合わせて、 q および qb の双方が 1 になるとしました。
論理合成すると、やはり、組み合わせ回路がループしている旨の警告が表示されます。 しかも、今回は2か所の警告が出てきます。 ループが二つできているということですが、二つもループがありましたっけ?
論理合成した結果、こうなりました。 ありゃ? なんだか余分な回路が付いていますね。 どうやら、 Q と QB に対して、個別にラッチを合成してくれたようです。
この回路、ラッチが二つあるために、問題が発生する可能性があります。 それは、二つのラッチが独立しているために、別々の状態をとることがあるということです。 電源投入直後は、電源の立ち上がり方によって、初期状態が異なってきます。 また、 rb と sb がほぼ同時に立ち上がる場合には、内部遅延の差によって、二つのラッチの動作が異なってくる可能性があります。
いずれにしても、これでは、 RS フリップフロップとしては使えないと考えられます。
本日の結論
Verilog HDL で記述した RS フリップフロップを PSoC Creator に合成させてみましたが、ラッチが二つ合成されてしまいました。 このままでは、実際の RS フリップフロップと同じ動作にはなりません。 やはり、ゲートで記述するか、別のロジックで実現するか、考えたほうがよさそうです。
関連文献
![トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌] トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌]](http://ecx.images-amazon.com/images/I/51LkFlElOmL._SL160_.jpg)
トランジスタ技術増刊 シリーズ最強!PSoC (ピーソック) 3ボード+デバッグボード 2012年 05月号 [雑誌]
- 作者:
- 出版社/メーカー: CQ出版
- 発売日: 2012/04/19
- メディア: 雑誌
PSoC 3 Kit Exchange Program やってます [PSoC]

Cypress は、 "PSoC 3 Kit Exchange Program" という活動を行っています。 これは、 PSoC3 ES チップが搭載された評価キットを量産版の PSoC3 が搭載された評価キットと無償で交換するというものです。 古い CY8CKIT-003 PSoC First Touch Kit が、最新の CY8CKIT-030 PSoC3 Development Kitに交換してもらえるそうです。 これは、利用せねば。
新しいキットが選べません
おや? "Replacement kit" のリストに何も出てきません。 これでは、受け付けてもらえません。 困ったな。
日本語に対応し損なっていた
何が起こっているのか、調査したところ、 WEB ページが読み込んでいる JavaScript ファイルが日本語に対応していないことがわかりました。 どこから見ても、中国語に見えます。
日本語設定がまずいのだから、と、日本語でない設定にしてみることにしました。 私が使っている FireFox の場合、メニューの Tools→Options→Content→Languages から Choose... ボタンをクリックして、言語設定を変更します。 English [en] をリストの最上位に持ってきて、 OK をクリックします。 これで、英語優先の設定になりました。
リストにキットが並びました
もう一度、 "PSoC 3 Kit Exchange Program" を開くと、みごとに "Replacement kit" のリストに交換先キットが並びました。 これで、申し込みができます。
無償で交換といっても、送料は請求されます。 さて、先に進んでみますか。
関連文献
いちおう、 PSoC なので。

はじめてのPSoCマイコン―PSoC‐Programmable System‐on‐Chip‐Primer (マイコン活用シリーズ)
- 作者: 桑野 雅彦
- 出版社/メーカー: CQ出版
- 発売日: 2010/04
- メディア: 単行本
PSoCマイコン・スタートアップ[PSoC基板&書き込み器付き]─LEDの点滅からタッチ・センシングの応用まで マイコン活用シリーズ
- 作者: 栗川 洋平
- 出版社/メーカー: CQ出版
- 発売日: 2009/11/11
- メディア: 単行本
周期割り込みなんて、簡単ですよ [PSoC]

本日の話題は、PSoC3を使って、周期割り込みを実現する方法です。 今回の例を見ていただけると、PSoCって、普通言われるようなマイコンじゃあないんだなと理解していただけると思います。
周期割り込みって、何だ?
唐突に周期割り込みという言葉が出てきました。 周期割り込みは、周期的に発生する割り込みのことです。 たとえば、1m秒ごとに周期的に割り込みを発生させてとある処理ルーチンを実行させます。 すると、割り込みの回数を数えるだけで、ミリ秒単位の時間を知ることができます。 また、割り込み周期が一定なので、処理ルーチンの処理時間に関係なく、各処理の開始間隔を一定にすることできます。
一定時間ごとに処理ができるようになると、A/D変換のサンプリングやD/A変換の出力タイミングも精確になるので、より性能が高くなります。
周期割り込みといえば、タイマを使うでしょう
従来のマイコンで、周期割り込みを実現しようとすると、通常はタイマモジュールを使用します。 今どきのタイマには、周期が設定できて、タイマカウンタが周期レジスタの値に達したらタイマカウンタを0に戻します。 このときに、出力を変化させたり、割り込みを発生させたりすることができます。 PSoC3にも、タイマがあり、「周期レジスタ」で周期的に割り込みを発生することができます。
| Parameter | Value |
|---|---|
| Resolution | 8-bit |
| Period | 250 |
| Trigger Mode | None |
| Capture Mode | None |
| Enable Mode | Software Only |
| Run Mode | Continuous |
| Interrupts | On TC |
タイマには、1kHzのILO (Internal Low-frequency oscillator)が接続されています。
このクロック・パルスを250個数えることによって、250m秒ごとにinterrupt出力をアサートしています。
interrupt出力の信号は、isr_1インスタンスに伝わり、割り込み処理ルーチンを起動します。
Pin_1は、ハードウェア接続の無い、出力専用端子として定義されています。
使用したリソースは、ざっとこんなところです。
Resource Type : Used : Free : Max : % Used
============================================================
Macrocells : 1 : 191 : 192 : 0.52%
Unique Pterms : 1 : 383 : 384 : 0.26%
Total Pterms : 1 : : :
Datapath Cells : 1 : 23 : 24 : 4.17%
Status Cells : 1 : 23 : 24 : 4.17%
Control/Count7 Cells : 1 : 23 : 24 : 4.17%
Sync Cells : 1 : 91 : 92 : 1.09%
Interrupts : 1 : 31 : 32 : 3.13%
main.cの中核は、このようになっています。
CY_ISR(isr_1_isr) {
(void)Timer_1_ReadStatusRegister(); // to clear flag
Pin_1_Write(Pin_1_Read()?(0):(1));
}
void main()
{
Timer_1_Start();
isr_1_StartEx(isr_1_isr);
CYGlobalIntEnable;
for(;;)
{
// Nothing to do
}
}
isr_1インスタンスとTimer_1インスタンスは、回路図上で接続されていますが、それぞれ独立した存在です。
しかしながら、Timer_1のinterrupt出力が自動的にクリアされないため、割り込み処理ルーチンから割り込みフラグをクリアする関数Timer_1_ReadStatusRegister()を呼び出さざるを得ませんでした。
う~ん、美しくない。
処理ルーチンの中では、LEDが接続されたPin_1の出力を反転させています。 250m秒ごとに反転するので、LEDが2Hzで点滅する様子が観測できます。
無理にinterrupt出力を使うことないじゃん
上の例は、interrupt出力を使ったために、割り込み処理ルーチンでフラグをクリアしなくてはなりませんでした。
isr_1インスタンスは、エッジをつかまえて割り込みを発生させることができるので、隣にあるtc (Terminal Count) 出力を接続しても、同じ動作をするはずです。
しかも、フラグをクリアする必要がありません。
| Parameter | Value |
|---|---|
| Resolution | 8-bit |
| Period | 250 |
| Trigger Mode | None |
| Capture Mode | None |
| Enable Mode | Software Only |
| Run Mode | Continuous |
| Interrupts | - |
すでに、interrupt出力は、まったくアサートされなくなりました。
Resource Type : Used : Free : Max : % Used
============================================================
Macrocells : 2 : 190 : 192 : 1.04%
Unique Pterms : 1 : 383 : 384 : 0.26%
Total Pterms : 2 : : :
Datapath Cells : 1 : 23 : 24 : 4.17%
Status Cells : 1 : 23 : 24 : 4.17%
Control/Count7 Cells : 1 : 23 : 24 : 4.17%
Sync Cells : 1 : 91 : 92 : 1.09%
Interrupts : 1 : 31 : 32 : 3.13%
消費したリソースは、マクロセルがひとつ増えました。 割り込み出力が必要なくなったので、減るかと期待していたんですけどね。
CY_ISR(isr_1_isr) {
Pin_1_Write(Pin_1_Read()?(0):(1));
}
プログラムは、割り込み処理ルーチンからフラグのクリアが消えました。 このプログラムも、2Hzで出力を反転させます。
周期的な信号とそれを受ける割り込み機能があれば十分
これまで、周期割り込みにタイマを使ってきましたが、タイマの機能を十分に使っているとは言えません。 単なる分周器でも十分です。 いっそのこと、クロックを直接つないでしまったら、どうでしょう。 というわけで、4Hzのクロックをつないでみました。
Resource Type : Used : Free : Max : % Used
============================================================
Digital domain clock dividers : 1 : 7 : 8 : 12.50%
Interrupts : 1 : 31 : 32 : 3.13%
必要なリソースも、4Hzのクロックを生成するための分周器と割り込みモジュールだけです。
CY_ISR(isr_1_isr) {
Pin_1_Write(Pin_1_Read()?(0):(1));
}
void main()
{
isr_1_StartEx(isr_1_isr);
CYGlobalIntEnable;
for(;;)
{
// Nothing to do
}
}
プログラムも、さらに簡単になりました。
Timer_1は、Start()を呼び出して起動する必要がありますが、Clock_1は、最初から起動しているからです。
このプログラムでも、2HzでLEDが点滅します。
余談1:割り込みコストって、高すぎる
で、よせばいいのに、コンパイル結果を見てしまいました。
; FUNCTION isr_1_isr (BEGIN)
0000 C0E0 PUSH ACC
0002 C0F0 PUSH B
0004 C083 PUSH DPH
0006 C082 PUSH DPL
0008 C085 PUSH DPH1
000A C084 PUSH DPL1
000C C086 PUSH DPS
000E 758600 MOV DPS,#00H
0011 C000 E PUSH ?C?XPAGE1SFR
0013 750000 E MOV ?C?XPAGE1SFR,#?C?XPAGE1RST
0016 C0D0 PUSH PSW
0018 75D000 MOV PSW,#00H
001B C000 PUSH AR0
001D C001 PUSH AR1
001F C002 PUSH AR2
0021 C003 PUSH AR3
0023 C004 PUSH AR4
0025 C005 PUSH AR5
0027 C006 PUSH AR6
0029 C007 PUSH AR7
; SOURCE LINE # 14
; SOURCE LINE # 15
002B 120000 E LCALL Pin_1_Read
なんですか?これは。 割り込み処理ルーチンの入口に、これでもかっていうぐらいにレジスタをスタックに押し込む命令が並んでいます。 もちろん、出口にも同じだけスタックからレジスタの値を復帰させる命令が並んでいます。
これは、レジスタの本数が増えたからにほかならないのですが、理由はもう一つあります。 それは、割り込み処理ルーチンの中で関数を呼び出したことです。 このコンパイラは、割り込み処理ルーチンの中で関数を呼び出した場合には、無条件で全レジスタを退避させるコードを生成するらしく、関数の処理内容にかかわらず、このように大げさなスタック操作が行われるようになります。
余談2:オーバヘッドを減らすためにポーリングを使う?
これに対する解決策が、サイプレス社のアプリケーションノートAN60630 - Optimizing 8051 Code in PSoC® 3に書かれています。 解決方法は、割り込み処理ルーチンの中では、フラグをセットするだけにして、実際の作業は、メインルーチンの中で行わせることだそうです。 えっと、つまり、それは、ポーリングってことですか?
uint8 isr_1_flag = 0;
CY_ISR(isr_1_isr) {
isr_1_flag = 1;
}
void main()
{
isr_1_StartEx(isr_1_isr);
CYGlobalIntEnable;
for(;;)
{
if (isr_1_flag) {
isr_1_flag = 0;
Pin_1_Write(Pin_1_Read()?(0):(1));
}
}
}
コンパイル後のコードは、こうなりました。
; FUNCTION isr_1_isr (BEGIN)
0000 C0E0 PUSH ACC
0002 C083 PUSH DPH
0004 C082 PUSH DPL
0006 C085 PUSH DPH1
0008 C084 PUSH DPL1
000A C086 PUSH DPS
000C 758600 MOV DPS,#00H
000F C000 E PUSH ?C?XPAGE1SFR
0011 750000 E MOV ?C?XPAGE1SFR,#?C?XPAGE1RST
; SOURCE LINE # 16
; SOURCE LINE # 17
0014 900000 R MOV DPTR,#isr_1_flag
0017 7401 MOV A,#01H
確かにスタッキングの数は減りましたが、まだまだ多いようです。
余談3:フラグに最適な変数クラスがある
アプリケーションノートAN60630 - Optimizing 8051 Code in PSoC® 3には、続きがあります。 フラグには、bitクラスを使え。
PSoC3に使われているCPU 8051 は、ある限られたメモリ空間で、低コストにビット操作を行うことができます。 そのときに使用される変数クラスが、bitです。
bit isr_1_flag = 0;
変更したのは、ここだけです。 コンパイルしてみると、こんなコードが生成されていました。
; FUNCTION isr_1_isr (BEGIN)
; SOURCE LINE # 16
; SOURCE LINE # 17
0000 D200 R SETB isr_1_flag
; SOURCE LINE # 18
0002 32 RETI
; FUNCTION isr_1_isr (END)
今までの嵐のようなスタッキングは、何だったんだろうという簡単さです。 スタッキングを一切必要としていません。 フラグをセットしたら、割り込み処理ルーチンから戻ります。 ただ、それだけです。
これで、割り込み発生からの遅延が少なくなりますが、ポーリングを使っている時点で、遅延が発生するようにも思います。 はてさて、どっちがお得なんでしょうね。
PSoC® 3/5実習形式のワークショップ開催決定! [PSoC]

ワークショップ会場と日程
- 大 阪: 2011年2月3日(木) 10:00~17:00
- ブリーゼプラザ 7F 小ホール
- (〒550-0004 大阪府大阪市北区梅田2丁目4番9号)
- http://www.breeze-plaza.com/
- 東 京: 2011年2月9日(水) 10:00~17:00
- 富士ソフト アキバホール
- (〒101-0022 東京都千代田区神田練塀町3)
- http://www.fsi.co.jp/akibaplaza/cont/hall/index.html
参考サイト
http://www.cypress-japan.co.jp/megaworkshop2/
大阪行くなら、PiTaPaを持とう [ざれごと]

本日の話題は、電子工作とはまったく関係のない、大阪の公共交通の支払いに関する話題です。
東京には、Suicaがある。では、大阪には?
東京で電車やバスを使うときには、非接触型カードである、JR東日本のSuicaやパスモのPASMOが有ると便利です。どちらかを一枚持っていれば、首都圏の鉄道やバスに乗ることができます。自動販売機で誰でも買うことができます。
では、大阪にはどんな非接触型カードがあるかというと、JR西日本のICOCAが有ります。このカードは、Suicaの適用範囲でも使用できるカードで、自動販売機で入手可能です。そして、本日の話題として取り上げた、スルッとKANSAIのPiTaPaが有ります。
大阪暮らしを始めるにあたって、ひとまず、駅の券売機でPiTaPaを買おうとしたのですが、PiTaPaは、券売機でも窓口でも売られていない事を教えられました。駅員さんによると、「申し込んでから、4週間かかります。」だそうです。えぇ~、なんで?
と、いうわけで、PiTaPaに関する調査を開始したのでありました。
PiTaPaは、ポストペイである
PiTaPaが、ほかのカードと最も異なっているのは、他のカードが事前にチャージを必要とするのに対して、PiTaPaは事前のチャージが必要がないということです。では、どうやって支払うかというと、一月分の乗車実績が集計されて、後払い(Post-Pay : ポストペイ)で対応します。つまり、PiTaPaというのは、クレジットカードと同じ仕組みでできているのです。
クレジットカードと同じなので、PiTaPaを持つためには、信用調査が必要です。「申し込んでから、4週間」というのは、この審査期間を指しているようです。もちろん、審査の結果、発行を拒否されることもありますし、信用の無い未成年者が単独でPiTaPaを持つことはできません。
PiTaPaは、JR西日本のICOCAのエリアでも使用することができますが、このときには、事前にチャージが必要です。ただ、オートチャージという仕組みも用意されているので、不便を感じることはないでしょう。このオートチャージ分の支払いも、もちろんポストペイです。
また、Suica同様に駅の売店や飲料の自動販売機などでも使用することができます。もちろん、これらの支払いもポストペイです。
集計するときに割引がある
PiTaPaは、後払いなので、集計が終わるまで支払いを先延ばしすることができます。これは、キャッシュフローの観点から見るとありがたいことです。しかも、PiTaPaには、それだけではない、ありがたいことが有るのです。
それは、集計される時に割引が受けられる可能性があるということです。主に以下のような割引が各交通機関ごとに定められています。
- 利用回数割引
- 乗車回数に応じて割引が決まる制度です。多くの交通機関では、11回目からの乗車から一割引きになる、回数券のような制度になっています。
- 利用額割引
- 利用金額に応じて割引が決まる制度です。多くの交通機関では、金額がある程度にならないと割引率が0%のままなのですが、大阪市営地下鉄は、0円から10%割引があります。乗車回数の少ない出張者にもうれしい制度です。
- 区間指定割引
- 多く乗車する区間を事前に指定しておくと、その区間の定期券料金をその区間の利用額の上限とする制度です。事実上、定期券と同じように利用することができます。たまにしか使わない出張者には、使う機会はないでしょう。
大阪から東京に来た人に「Suicaが有ると東京の交通機関を使うときに便利だ。」と紹介したのですが、PiTaPaみたいに割引が無いということを伝えたら、「割引が無いのなら、大阪人には、うけない。」と返されてしまいました。そういう、ものなんですかね。
PiTaPaを手に入れるには
自動販売機では入手できなかったPiTaPaですが、どうやって入手すればよいのでしょうか。PiTaPaを発行しているのは、「スルッとKANSAI」なのですが、その裏付けとなる信用を与えている会社が、複数に分かれていて、それぞれが提携カードを発行しています。そのため、提携カードを持つ場合には、発行会社を選ぶ必要があります。カードラインナップのページをみると、どんなカードがあるかがわかります。
PiTaPaベーシックカードは、PiTaPaの機能だけをとりいれたカードで、出張の時にしか使わないということであれば、これで十分でしょう。他には、交通機関が発行している提携カードというものがあります。通勤などで多く使用する路線が決まっているのなら、その交通機関が発行しているカードを持っていると、追加のポイントが加算される場合があるのでお得です。私が持っているのも、沿線の交通機関が発行するカードです。
提携カードには、クレジットカードにPiTaPa機能を組み込んだ一体型カードと、クレジットカードとは別にPiTaPaカードを発行する「2枚でひと組」のカードがあります。カードの枚数を増やしたくないなら、一体型のカードを選ぶのもよいでしょう。
で、最終的にどこカードを選ぶべきかということになるのですが、一発勝負でどれかを選ぶしかないでしょう。PiTaPaカードは、年会費無料とされていますが、一年間に一回も利用しないと維持管理費1050円が課金されます。そのため、複数のPiTaPaを持つことは得策ではありません。
交通費の精算にも便利
Suicaの場合、どこでいくら使ったかは、PCにカード読み取り機を付けてデータを取り込む、駅の券売機で履歴を印字させる、という方法があります。どちらも、ひと手間必要なので、少々不便です。
一方、PiTaPaの場合には、「PiTaPa倶楽部」というサイトがあり、利用履歴をWEBページから確認することができます。このサイトのデータは、利用翌日には更新されているので、交通費を精算する際にデータを利用することもできます。
大阪行くなら、PiTaPaを持とう
大阪でPiTaPaを持つ事の利点がお判りいただけたでしょうか。東京でSuicaを持つように、大阪でPiTaPaを持つのであれば、審査に時間がかかるので、あらかじめ準備が必要です。さっそく、資料を取り寄せましょう。
むすび
と、さんざんPiTaPaを勧めてきましたが、私自身はPiTaPaの利害関係者でもなんでもありません。まあ、非接触型カードの新しい使い方を見せられて、カブレテいるのだと理解してください。
IS03用テレビ台の製作 [非電子工作]

縁あって、Androidオペレーティング・システム搭載携帯電話である、IS03を入手しました。ワンセグ受信機を使うには、台が欲しくなりますね。
Androidをワンセグ受信機として使うという動機
IS03には、ワンセグ受信機が搭載されています。他にテレビを持っていない私には、唯一のテレビ受像機となりました。ところが、IS03でワンセグ放送を見ようとすると、色々と不都合が出てきます。
- 据え置き受像機にするには、本体を立てなくてはならない。
この携帯電話は、平面型の携帯電話なので、何もしないで机に載せると、画面が上空を向いてしまいます。これでは、普通に番組を見るには不便です。机の上に立てた状態で保持させる仕掛けが欲しくなります。
- IS03を横にするとUSBが邪魔になる
IS03は、縦にすると、番組画面が小さくなって、下のほうに文字放送がでしゃばってきます。横にすると、全画面で番組を見ることができますが、このとき、画面の下から電源代わりのUSBケーブルがはみ出します。USBケーブルを邪魔しないようにするためには、ある程度の高さのところでIS03を保持しなくてはなりません。
ありあわせの箱などで、なんとか本体を立てようとしましたが、うまくいきません。ここは、本格的に、テレビ台を作ってしまいましょう。
中身は、こうなっている
本格的に作ると言ったわりには、材質は、段ボールです。近くのスーパーマーケットから持ち帰った段ボール箱をカッターナイフで切り出して、組み上げます。接着剤もテープも使わず、本当に組み上げました。
台は、中空です。この隙間にUSBケーブルを通すことで、電源供給をしていてもケーブルが隠れるので、すっきりと見えます。
設計図は、コレダ
テレビ台は、ちゃんと設計図を引いて、作成しています。手元に定規もなかったので、1行6mmのB罫ノートが定規の代りです。このため、すべての寸法が6mm単位になっています。
破線を山折りに、一点鎖線を谷折りにして、最後に後ろの切り込みに反対側の出っ張りを差し込んで出来上がりです。設計図には、後ろ側にUSBケーブルを通す穴が描いてありませんが、これは、組み上げてから現物合わせであけました。
今後の課題
このテレビ台は、第一作目なので、最終的には、現物合わせで作成しました。そもそも、段ボールの厚みを計算に入れていない設計図なので、破たんしてあたりまえでした。
二作目は、寸法を設計しなおして、作成しようと考えています。また、背面に付いているIS03のスピーカ出力の音が、前のほうに反射するような仕掛けも作ろうかと考えています。
いや、その前に、二台目の需要が、あるのか?
参考文献?

できるポケット au IS03をスマートに使いこなす基本&活用ワザ150
- 作者: 法林岳之
- 出版社/メーカー: インプレスジャパン
- 発売日: 2010/12/17
- メディア: 単行本(ソフトカバー)







