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なんかは、屁のツッパリはいらんですよ。 次あたりはテスト回路くらい動かせるかな??? あ、いつもの台詞忘れてた・・・ プレス屋の息子をなめんなよ〜 まぁプログラム書くのはむしろ本業ですから・・・(^^;;; |