Tumblrへおひっこしして
URLを張るのを忘れてた
↓
うなすけのたんぶら
Tumblrへおひっこし
したいなー
なぜ?
広告が邪魔
帰ってきたGRUB
#Windows7installbattle
↓
アップデート失敗するうううう
↓
ようやく終わった……
↓
あれ、デュアルブートのubuntuどこ行った?
そう!ブートローダがwindowsのやつに上書きされてしまったアアアッ
GRUBの再インストール
もともとのubuntuの起動
まずはCDとかUSBから何とかしてubuntuを起動
そしたら「ディスク」(ちょっと前まで「ディスクユーティリティ」って名前だったはず……変わったのか?)を起動して元々のubuntuがどこにインストールされているかメモる。たとえば/dev/sdaだったり、僕は/dev/sdb6だった。
メモったらもう一度なんとかしてubuntuを起動。その時に、紫色の画面の下の方に丸の中の人とキーボード?が表示されてるうちにESCキーを押す。
すると起動オプションの項目が出てくるのでF6を押して起動オプションを変更する。オプションの中に
boot=casper
と書いてある部分があるので、そこを
root=さっきメモったやつ
たとえば
root=/dev/sdb6
H8/3664FでタイマA割り込みできたよ!!!やったね!!!
何がいけなかったのか?
昨日上げたソースコードから1行ずつコメントを外して検証した結果、Count関数を用いないと(NOP();を一定回数ループさせないと)7セグメントLEDが点灯しないことが判明した。ただし判明した時点での点灯状況は数字が表示されるというものではなく、ただランダムに点灯しているような状況だった。この時は、グローバル変数の値を参照して数値を表示させるようにしており、割り込み関数内でそのグローバル変数をインクリメントしている状態だった。その後、割り込みはできたが数字として表示されない状態に。
隣の班と情報交換をし、どうやらグローバル変数が悪さをしているようだが、構造的にグローバル変数を用いずに実現させるのは難しいと考え、別の解決策をググった。
コンパイル時に、プログラムは最適化される。しかし組み込み用途では、最適化が思わぬ動作を引き起こすことがあり、無効化することが望ましい場合があるとのこと。google:h8 volatile
そこでグローバル変数をvolatile修飾子を付けて宣言しなおしたところ、正常に動作するようになった。
長い
グローバル変数にはvolatile付けろ。配列はダメな。
現時点でのソースコード
動いたver
時計表示のための60進数実現部分でif文が入れ子になっており、これ、なんとか短くできそう。関数化するとか。
/* * H8/3664F 7セグメントLEDのダイナミック点灯制御実験 */ #include "3664.h" //7セグメントLEDの各数字表示 #define ZERO 0x80 //10000000 //0 #define ONE 0xF1 //11110001 //1 #define TWO 0x44 //01001000 //2 #define THREE 0x60 //01100000 //3 #define FOUR 0x31 //00110001 //4 #define FIVE 0x22 //00100010 //5 #define SIX 0x2 //00000010 //6 #define SEVEN 0xB0 //10110000 //7 #define EIGHT 0x0 //00000000 //8 #define NINE 0x20 //00100000 //9 //7セグメントLEDの格桁に対応するポート #define DIGIT0 0x1 #define DIGIT1 0x2 #define DIGIT2 0x4 #define DIGIT3 0x8 #define DIGIT4 0x10 #define DIGIT5 0x20 #define DIGIT6 0x40 //タイマAの割り込み要求フラグが立っている状況 #define IRRTA 0x70 //タイマAの割り込み要求を許可するflug #define IENTA 0x40 //グローバル変数(最適化対象でない) volatile short int disp0; volatile short int disp1; volatile short int disp2; volatile short int disp3; /*入力された数値に対応する7セグメントLEDを *負論理で点灯させるポート出力用の数値を返す */ int LightNumber( int num ) { int led[10] = { ZERO , ONE , TWO , THREE , FOUR , FIVE , SIX , SEVEN , EIGHT , NINE , }; return led[num]; } /*入力された数値に対応する桁をトランジスタのスイッチングによって *点灯させるようにポートをセットする */ int LightDigit( int num ) { int dig[] = { DIGIT0 , DIGIT1 , DIGIT2 , DIGIT3 , DIGIT4 , DIGIT5 , DIGIT6 , }; return dig[num]; } /*ダイナミック点灯を行う関数 *表示する数値はグローバル変数と割り込みで更新 */ void Count( void ) { int wait; //1桁目の点灯 PDR5 = LightDigit( 0 ); PDR8 = LightNumber( disp0 ); //僅かな時間点灯させる for( wait = 0; wait < 10000; wait++ ) { NOP(); } //2桁目の点灯 PDR5 = LightDigit( 1 ); PDR8 = LightNumber( disp1 ); //僅かな時間点灯させる for( wait = 0; wait < 10000; wait++ ) { NOP(); } //3桁目の点灯 PDR5 = LightDigit( 2 ); PDR8 = LightNumber( disp2 ); //僅かな時間点灯させる for( wait = 0; wait < 10000; wait++ ) { NOP(); } //4桁目の点灯 PDR5 = LightDigit( 3 ); PDR8 = LightNumber( disp3 ); //僅かな時間点灯させる for( wait = 0; wait < 10000; wait++ ) { NOP(); } } /*タイマーAを使用して1秒毎に割り込みを行う関数 *これにより1秒毎にカウントアップができるようになった *できた *まあまあ理解した *帰れた */ #pragma interrupt void int_timera( void ) { IRR1 &= ~IRRTA; //タイマAの割り込み要求をクリア disp0++; } /*7セグメントLEDを0から9の順に点灯させるプログラム*/ int main() { CLI(); //初期化操作のため割り込みを禁止 disp0 = 0; disp1 = 0; disp2 = 0; disp3 = 0; /*ポート1は7セグメントLEDの数値表示に用いる ポート1は接触不良のため使用不可 PMR1 = 0x00; //汎用入出力ポートに設定 PCR1 = 0xff; //ポート1を全ビット出力用に使用 PDR1 = 0x00; //ポート1をクリア */ //ポート5はどの7セグメントLEDを点灯させるかのトランジスタでのスイッチングに用いる PMR5 = 0x00; /*汎用入出力ポートに設定*/ PCR5 = 0xff; /*全ビット出力用に設定*/ PDR5 = 0x00; /*ポート5をクリア*/ //ポート8は7セグメントLEDの数値表示に用いる //PMR8 = 0x00; /*ポートBは出力専用なのか?*/ PCR8 = 0xff; /*ポートBを全ビット出力用に使用*/ PDR8 = 0x00; /*ポートBをクリア*/ TMA = 0x8; //タイマーAを低速時計用クロック、速度は1秒間隔に設定 STI(); //初期化操作終了とともに割り込みを許可 IENR1 |= IENTA; //タイマAの割り込みを許可 IRR1 &= ~IRRTA; //タイマAの割り込み要求をクリア for( ; ; ) { //60進数制御if文の羅列 //もっとスマートな書き方があるはず。関数化してしまうとか。 if( disp0 > 9 ) { disp0 = 0; disp1++; if( disp1 > 5 ) { disp0 = 0; disp1 = 0; disp2++; if( disp2 > 9 ) { disp0 = 0; disp1 = 0; disp2 = 0; disp3++; if( disp3 > 5 ) { disp0 = 0; disp1 = 0; disp2 = 0; disp3 = 0; } } } } //ダイナミック点灯 Count(); } }
あとはレポート書くだけ
マイコンの実験がうまくいかない
更新サボりがちなのは大目に見て
実験内容
秋月電子のAKI-H8/3664Fキット(URL)を使ってなんか作れというもの。うちの班は秒カウンタ、もし出来ればストップウォッチや時計などを作れたらいいなーなんて話し合ってた。
甘 か っ た
基本的にうまくいかない
断線
初っ端のアクシデントは断線。ジャンパワイヤの特定の色が全部断線。で、新しくもらった1セットも赤いジャンパワイヤが全て断線していたという強運っぷり。なんでや。
ポート死んでる
故障したので、新しいマイコンをもらったが、あるポートが使えない。死んでいる。回路とプログラム書き直し。大した痛手じゃなかったけれどもへこむ。
書いたとおりにすら
「プログラムは思ったとおりには動かない。書いたとおりに動く」という名言があるが、なんべんやっても書いたとおりにすら動いてないんじゃないか?という状況。締め切りはもうすぐ。
何をどんな感じでやっているのか
2桁の7セグメントLEDをダイナミック点灯制御でカウントアップ。その後はタイマAによる割り込みで1秒毎に表示を更新。起動時からの秒数カウンタ(00秒から99秒まで)が完成した後に随時機能追加。
行き詰まっていることろ
基本的に動作が不安定である
突然CPUからの応答がなくなったり、点灯しなくなったりする。
割り込みができない
なんでだーーまったくわからんーーーーー
現時点でのソースコード
バックアップ代わりに。もしかしたら優しい伊達直人が間違いを指摘してくれるかもという希望を抱いて。
/* *H8/3664F 7セグメントLEDのダイナミック点灯制御実験 */ #include "3664.h" /* P11をLEDに接続、P52をSWに接続 */ #define P1OUT 0x2 /* P11:0000,0010 */ #define P5IN 0x4 /* P52:0000,0100 */ //7セグメントLEDの各数字表示 #define ZERO 0x80 //10000000 //0 #define ONE 0xF1 //11110001 //1 #define TWO 0x44 //01001000 //2 #define THREE 0x60 //01100000 //3 #define FOUR 0x31 //00110001 //4 #define FIVE 0x22 //00100010 //5 #define SIX 0x2 //00000010 //6 #define SEVEN 0xB0 //10110000 //7 #define EIGHT 0x0 //00000000 //8 #define NINE 0x20 //00100000 //9 //7セグメントLEDの格桁に対応するポート #define DIGIT0 0x1 #define DIGIT1 0x2 #define DIGIT2 0x4 #define DIGIT3 0x8 #define DIGIT4 0x10 #define DIGIT5 0x20 #define DIGIT6 0x40 //タイマAの割り込み要求フラグが立っている状況 #define IRRTA 0x70 //タイマAの割り込み要求を許可するflug #define IENTA 0x40 int count = 0; /*入力された数値に対応する7セグメントLEDを *負論理で点灯させるポート出力用の数値を返す */ int LightNumber( int num ) { int led[10] = { ZERO , ONE , TWO , THREE , FOUR , FIVE , SIX , SEVEN , EIGHT , NINE , }; return led[num]; } /*入力された数値に対応する桁をトランジスタのスイッチングによって *点灯させるようにポートをセットする */ int LightDigit( int num ) { int dig[] = { DIGIT0 , DIGIT1 , DIGIT2 , DIGIT3 , DIGIT4 , DIGIT5 , DIGIT6 , }; return dig[num]; } /*2桁でカウント *00から始まって99まで進む……すすめたらいいな */ void Count( void ) { int disp[2] = { 0 , 0 }; int i; int j; int k; int wait; for( ;; ) { for( j = 0; j < 100; j++ ) { //1桁目の点灯 PDR5 = LightDigit( 0 ); PDR8 = LightNumber( disp[0] ); //僅かな時間点灯させる for( wait = 0; wait < 10000; wait++ ) { NOP(); } //2桁目の点灯 PDR5 = LightDigit( 1 ); PDR8 = LightNumber( disp[1] ); //僅かな時間点灯させる for( wait = 0; wait < 10000; wait++ ) { NOP(); } } //桁制御 disp[0]++; if( disp[0] > 9 ) { disp[0] = 0; disp[1]++; if( disp[1] > 9 ) { disp[0] = 0; disp[1] = 0; } } } } /*タイマーAを使用して1秒毎に割り込みを行う関数 *これにより1秒毎にカウントアップができるようになる気がする *できてほしい *まだよくわかってない *帰りたい */ #pragma interrupt void int_timera( void ) { IRR1 &= ~IRRTA; /*タイマAの割り込み要求をクリア*/ count++; } /*7セグメントLEDを0から9の順に点灯させるプログラム*/ int main() { int wait; //CLI(); //初期化操作のため割り込みを禁止 //ポート1は7セグメントLEDの数値表示に用いる //ポート1は接触不良のため使用不可 //PMR1 = 0x00; /*汎用入出力ポートに設定*/ //PCR1 = 0xff; /*ポート1を全ビット出力用に使用*/ //PDR1 = 0x00; /*ポート1をクリア*/ //ポート5はどの7セグメントLEDを点灯させるかのトランジスタでのスイッチングに用いる PMR5 = 0x00; /*汎用入出力ポートに設定*/ PCR5 = 0xff; /*全ビット出力用に設定*/ PDR5 = 0x00; /*ポート5をクリア*/ //ポート8は7セグメントLEDの数値表示に用いる //PMR8 = 0x00; /*ポートBは出力専用なのか?*/ PCR8 = 0xff; /*ポートBを全ビット出力用に使用*/ PDR8 = 0x00; /*ポートBをクリア*/ //この下の4行はコメントを外すと動かないことから怪しいがこれがないと割り込みできない //TMA = 0x8; //タイマーAを低速時計用クロック、速度は1秒間隔に設定 //STI(); //初期化操作終了とともに割り込みを許可 //IENR1 |= IENTA; //タイマAの割り込みを許可 //IRR1 &= ~IRRTA; //タイマAの割り込み要求をクリア //この関数ならカウントアップ可能 //Count(); //このへんから割り込みなど行いたいがうんともすんとも。 while( 1 ) { if( count > 9 ) { count = 0; } PDR5 = LightDigit( 0 ); PDR8 = LightNumber( count ); //僅かな時間点灯させる for( wait = 0; wait < 10000; wait++ ) { NOP(); } } }
台湾でのパケット通信と心配事
台湾に行く事になり、一番心配しているのが現地でのパケット通信料。
だってインターネット依存症だし。
WORLD WING
海外でのパケット通信だが、機種と使用可能な国はまあ置いといて、docomoの場合はWORLD WINGを契約していれば「海外パケ・ホーダイ」が適用され、パケット通信料が1日最大2980円になるとのこと。
WORLD WINGの月額使用料金は無料だからたいてい契約してる。だから何も考えなくても良かったかというと……ちょっとちがう
データローミング
これをONにしないとダメ。逆に、これをOFFにしたままなら海外でのパケット通信は発生しない。念の為SIM抜いたり電源切っておけばなお安心だけど。
あと、日本に帰ってきたらデータローミングはOFFること。
充電
あー
パソコン
重い