2012/07/04(WED) 【Nチビ】ウインカーLED化(空想編)
さてウインカーリレーをPICマイコンで作ると決めた。
回路は妄想済
んじゃ、次はプログラムを空想する。

その前に、使うPICを決める。
まぁ出力が一つなんだから足は8本のでいいでしょ?
あとAD変換は必要ないからということでPIC12F629を選択。
8本足で、内部クロックもついているので、これで必要十分。
で、
PICのプログラムなんて書いたことないっすよ。
ネットで調べてみるとアセンブラとC言語の2種類で出来そう。
#アセンブラと聞くとアセンブラFXを思い出す。昔あった漫画だ。
#コンパイラとアセンブラね。古いなぁ〜
で、ついでにLEDの点滅のプログラムなんかも落ちているので
参考にする。
でね。LEDを点滅させるのは入門向きっぽくっていっぱいあるわけだ。
んじゃ、アセンブラでいいか?安易に決定。
まぁそもそもGPIOをピンを上げたり下げたりするだけでしょ?

さて、ネットで見つけたプログラムを見てみると
NOPで時間稼いでカウントしてGPIOをON/OFFするのが主流。
う〜む。なんかカッコワルイ。
さらに調べてみるとタイマー割込みが使えるらしい。
んじゃ、それを使おう!
と、いきなりハードルが高い方をチョイス・・・
まぁまぁ
そもそもプログラムってもんは天から降ってくるものであって
ソースプログラムは芸術であり・・・実行モジュールという名の・・・以下略

でだ。タイマー割込みね。
きっとISR(いんたーらぷと さーびす るーちん)を登録してタイマー走らせる
でタイマーが条件に達するとISRがコールされるわけだ。
きっと。
きっと。
だったらいいなぁ〜
そもそも書いたことないので知るわけがない(笑)

で、ネットで調べながら思考錯誤して書いたプログラムが↓これだ。
スペースがズレちゃうのはゆるしてくれ。
え?設計しないの?という戯言は嫌いだ。
そもそもプログラムってもんは天から降ってくるものであって・・・以下略

01       LIST   P=12F629    ;PICタイプ
02       INCLUDE P12F629.INC  ;インクルードファイル
03
04 CB = _CPD_OFF            ;データメモリーを保護しない
05 CB &= _CP_OFF            ;プログラムメモリーを保護しない
06 CB &= _BODEN_OFF          ;ブラウンアウトリセットを使わない
07 CB &= _MCLRE_OFF          ;3番ピンを外部リセット端子として使わない
08 CB &= _PWRTE_ON           ;パワーアップタイマーを使う
09 CB &= _WDT_OFF           ;ワッチドッグタイマーを使わない
10 CB &= _INTRC_OSC_NOCLKOUT      ;クロック発振モードを内部発振
11
12       __CONFIG CB      ;コンフィギュレーションビットを適用する
13
14       __IDLOCS H'0100'    ;プログラムのバージョンを4桁の16進数
15
16 MAX_CNT:  EQU    D'61'     ;256*32*61=499.712 ms
17 MASK:    EQU    B'11111110'  ;マスク値ビット反転に使う
18        
19       CBLOCK  H'20'     ;プログラム中で使う変数を定義
20       CNT1          ;カウンタ
21       W_TEMP         ;Wレジスタセーブ
22       S_TEMP         ;STATUSレジスタセーブ
23
24       ENDC
25 ;---------------------------------プログラムの先頭をアドレス
26       ORG    H'0'
27       GOTO   INIT
28 ;---------------------------------割込みハンドラ
29       ORG    H'4'
30       BCF    INTCON,T0IF  ;割込みフラグクリア
31       MOVWF   W_TEMP    ;Wレジスタのバックアップ
32       SWAPF   STATUS,W
33       MOVWF   S_TEMP    ;STATUSレジスタのバックアップ
34
35       DECFSZ  CNT1,F    ;カウントダウン
36       GOTO   INT_RET
37
38       MOVLW   MAX_CNT    ;カウンタ初期化
39       MOVWF   CNT1
40
41       MOVF   GPIO,W    ;GPIOレジスタをWレジスタへ
42       XORLW   MASK     ;マスクかける(ビット反転)
43       MOVWF   GPIO     ;GPIOレジスタへ書き込み
44
45 INT_RET:
46       SWAPF   S_TEMP,W   ;STATUSレジスタ復旧
47       MOVWF   STATUS
48       SWAPF   W_TEMP,F   ;Wレジスタ復旧
49       SWAPF   W_TEMP,W
50       RETFIE
51 ;---------------------------------初期化
52 INIT:
53       BSF    STATUS,RP0  ;→バンク1
54        
55       MOVLW   B'00001000' ;PORT 0,1,2 = OUT, PORT 3 = IN
56       MOVWF   TRISIO
57        
58       MOVLW   B'10000100' ;OPTIONレジスタ設定
59       MOVWF   OPTION_REG
60        
61       BCF    STATUS,RP0  ;→バンク0
62        
63       MOVLW   B'00000000'
64       MOVWF   GPIO     ;GPIOレジスタの初期値を設定
65        
66       MOVLW   B'00000111' ;SETUP DIGITAL I/O MODE
67       MOVWF   CMCON    ;CMCOMフラグを設定
68        
69       MOVLW   B'10100000' ;T0IE/GIEを立てる
70       MOVWF   INTCON
71        
72       MOVLW   MAX_CNT   ;CNT1にカウンタをセット
73       MOVWF   CNT1
74        
75       CLRF   TMR0     ;TMR0をクリア
76 ;---------------------------------メインループ
77 MAIN_LOOP:
78       GOTO   MAIN_LOOP
79 ;---------------------------------
80
81       END

で、ISRを登録するのかと思いきや
もうISRのアドレスが決まっているのね。
それが29行目ね。
で、普通ISRにはあんまり処理を書くもんでないというのがセオリー
ISRは優先的に動くし、そこで処理が長いと次の割込みが来ちゃうから
システムが成立しなくなるわけだ。
でもね。今回はカウントアップ(正確にはカウントダウン)と
判定とGPIOを上げたり下げたりするだけなんで
ISRに全部処理書いちゃった。
おかげでメインループ(77行目付近ね)処理空っぽです。
C言語だと怒られそうな処理である。
あとはGPIOを上げたり下げたりする処理は
マスクを使ってビット反転することによりトグルさせている。
41行目付近ね。
最初は状態を取得して条件分岐させてたんだけど・・・
なんかかっこ悪かったのでこうした。
そもそもソースプログラムは芸術であり・・以下略
あとはINITで各種初期設定して、そこで割込みOKにしてタイマーを走らせています。
多分・・・(笑)
で、内部のクロック周波数は4MHzらしい。
でPICマイコンは4周期で1命令処理するらしいので <4ストかっ!
1命令は約1μsecで処理される。
あ、1命令ってのは、ちょっと表現違うな。1サイクルと言った方がいいか?
命令によっては2サイクルのものもあるので。
でだ、タイマー割込みは256サイクルで発生する。
0からカウントして1バイト8ビットサイズで255まで数えて
桁あふれしたら割込みされるらしい。
256サイクル=256μsecなんだけど、設定で32倍の界王拳にしているので
#58行目くらいの設定ね。
256×32=8192μsecで割込みが発生するようにしている。
でだ、その割込みが61回発生したらGPIOをトグルしている。
8192μsec×61=499712μsec≒500msec ということである。
まぁ点滅が早かったり遅かったりしたらパラメータで調整すればいいかな?

これ動くかな???
まぁあくまで空想ってことで・・・(^^;;;

あ、そうそう
これが出来上がればウインカーもLEDにできて
そうすればハザードもできるかな?って。
今回つけた集合スイッチはハザードスイッチついているのね。
でも、現状、電気量が足らずハザードしてくれなくて・・・
LEDにするとうまく動くような気がする。
でだ、前に作ったインジケータ
フォト
これだとハザードにしたら18mA×2=36mAがLEDに掛かっちゃうような・・・
まぁやってみて駄目なら作り直します・・・

アセンブラも書けるじゃん>σ(^^;;;
アセンブラなんて情報処理のCASLか
その昔、MSXのROMを吸い出して
逆アセンブラしてゲームの改造くらいしか・・・

あ、あとプログラム書く際
PIC12F629のデータシートも参照しました。
この辺は英語だけど
こういうデータシート、仕事で見慣れてるからねぇ〜
まぁARMに比べればPICなんかは、屁のツッパリはいらんですよ。

次あたりはテスト回路くらい動かせるかな???

あ、いつもの台詞忘れてた・・・
プレス屋の息子をなめんなよ〜
まぁプログラム書くのはむしろ本業ですから・・・(^^;;;