フランクリンモーターとムーアのモーター
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
PIC16F84Aを使った,3分間を計測できるラーメンタイマーを作ってみました。
とは言っても,これをそのまんま作っただけなんですけどね(^^;)
それにしても,これはよくできてますね。WebサイトにはHEXファイルしか置いてなかったけど,アセンブラだとどうなってるんでしょうなあ。
この基板には,LEDやブザーがついてるから,このままPICお勉強用のテストボードとしても使えますね。「LEDピカピカ」にも飽きてきたから,今度はブザーやスピーカーを鳴らしてみようかな。
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
昨日のプログラムを見てたら,変数を1つ減らせることに気づきました。
CYCLEという変数を削ったソースはこれ→ lesson12.asm
メインプログラムはこんな具合です。
;==============================================
MAIN
INCF COUNT,F ; COUNT+1 → COUNT
MOVF WIDTH,W ; WIDTH → Wレジスタ
SUBWF COUNT,W ; COUNT-WIDTHの引き算。
BTFSC STATUS,C ; COUNT
CALL TIMELOOP1
INCF COUNT,F ; COUNT+1→ COUNT
MOVLW 50 ; 1サイクルの時間=50
SUBWF COUNT,W ; COUNT-50の引き算。
BTFSS STATUS,C ; COUNT>50なら次行をスキップ
GOTO MAIN
;1サイクル終わった時の処理
CLRF COUNT
BSF PORTA,2 ; RB2のLEDを点灯
INCF WIDTH,F ; WIDTHを+1 → WIDTH
MOVLW 50 ; WIDTHの上限=50
SUBWF WIDTH,W ; WIDTH-50の引き算。
BTFSC STATUS,C ; WIDTH<50なら次行をスキップ
CLRF WIDTH
GOTO MAIN
;==============================================
変数COUNTにも変数CYCLEの役割を持たせているわけです。
こっちのほうがスッキリしてるんじゃないかな?
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
PWM制御(Pulse Width Modulation)でLEDをじわ~っと点灯させてみました。
ソースはこれ → lesson11.asm
まあこのサイトのプログラムをマネしただけですが,メインのプログラムはこうなっています。
;====================================================
MAIN
INCF COUNT,F ; COUNT+1 → COUNT
MOVF WIDTH,W ; WIDTH → Wレジスタ
SUBWF COUNT,W ; COUNT-WIDTHの引き算。
BTFSC STATUS,C ;STATUSレジスタのCビットが0(つまり
;COUNT<WIDTH)なら次行をスキップ
BCF PORTA,2 ; RB2のLEDを消灯
CALL TIMELOOP1
INCF CYCLE,F ; CYCLE+1 → CYCLE
MOVLW 50
SUBWF CYCLE,W ; CYCLE-50の引き算。
BTFSS STATUS,C ;STATUSレジスタのCビットが1(つまりCYCLE>=50)
;なら次行をスキップ
GOTO MAIN
;1サイクル終わった時の処理
CLRF CYCLE
CLRF COUNT
BSF PORTA,2 ; RB2のLEDを点灯
INCF WIDTH,F ; WIDTHを+1 → WIDTH
MOVLW 50
SUBWF WIDTH,W ; WIDTH-50の引き算。
BTFSC STATUS,C ;STATUSレジスタのCビットが0(つまりWIDTH<50)なら
:次行をスキップ
CLRF WIDTH
GOTO MAIN
;=====================================================
3つのカウンタ,COUNT(LED点灯後の時間を測る),WIDTH(点灯継続時間),CYCLE(1サイクルの時間)を用意し,WIDTHを徐々に増やしながらLEDを点滅させます。これでじわ~っと明るさが変化するわけです。
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
カウントアップだけでなくて,カウントダウンもできるようにしてみました。
ソースはこれ→lesson10.asm
プログラムはこんな感じです。
;============================================================
MAIN
BTFSS PORTA,1 ;RA1のスイッチがOFF(1)なら次行をスキップ
GOTO COUNTUP ;カウントアップへ
BTFSS PORTA,0 ;RA0のスイッチがOFF(1)なら次行をスキップ
GOTO COUNTDOWN ;カウントダウンへ
GOTO MAIN
COUNTUP
BTFSS PORTA,1 ;RA1のスイッチがOFF(1)になったら次行をスキップ
GOTO $-1 ;上の行へ戻る
CALL TIMELOOP1 ;チャタリング対策
INCF COUNT,F ;COUNT値を1増やして、
MOVF COUNT,W ;Wレジスタに書き込み、
MOVWF PORTB ;PORTBへ送る。
GOTO MAIN
COUNTDOWN
BTFSS PORTA,0
GOTO $-1
CALL TIMELOOP1
DECF COUNT,F ;COUNT値を1減らして、
MOVF COUNT,W ;Wレジスタに書き込み、
MOVWF PORTB ;PORTBへ送る。
GOTO MAIN
;=============================================================
RA0とRA1の2つのスイッチを監視していて,ONになったらCOUNTUPまたはCOUNTDOWNのサブルーチンへ分岐します。
押されたスイッチがOFFになるのを確認してからCONT値を+1または-1して,その値をPORTBへ送るわけです。
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
ボタンを押すと,LEDが二進数でカウントアップ点灯するプログラムを作ってみました。ソースはこれ→lesson9.asm
メインプログラムは次のようになっています。
:========================================================
MAIN
BTFSC PORTA,1 ;RA1のスイッチがON(0)になったら次行をスキップ
GOTO $-1 ;上の行へ戻る
CALL TIMELOOP1 ;チャタリング対策
BTFSS PORTA,1 ;RA1のスイッチがOFF(1)になったら次行をスキップ
GOTO $-1 ;上の行へ戻る
CALL TIMELOOP1 ;チャタリング対策
INCF COUNT,F ;COUNT値+1をCOUNTに格納
MOVF COUNT,W ;COUNT値をWレジスタに代入
MOVWF PORTB ;PORTBをWレジスタ値(カウンタ値)で点灯させる
GOTO MAIN
;=========================================================
スイッチが押されると(正確に言うと押されたスイッチがOFFになると),COUNTという変数に1を加えて,PORTBへ送ります。
5桁めからのLEDの点き方がヘンに思えるかもしれませんが,ここからLEDが逆に並んでるので,これでいいのです。
【今日覚えた命令】 MOVF
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
前回のプログラムを少しいじって,残像を残しながら点灯LEDがぐるぐる回るナイトライダー風のフラッシャを作ってみました。
ソースはこれ→lesson8.asm
やってることはしょーもないことなんですが,紹介しておきます。
;======================================================
MAIN
CALL LED_PTN ;LED点灯パターンのサブルーチンへ
MOVWF PORTB ;LED点灯パターンをPORTBへ送る
CALL TIMELOOP1
INCF COUNT,F ;COUNTに1を足してCOUNTに格納
CALL LED_PTN
MOVWF PORTB
CALL TIMELOOP2
INCF COUNT,F
CALL LED_PTN
MOVWF PORTB
CALL TIMELOOP3
INCF COUNT,F
MOVLW D'33' ;LED点灯パターンの総数33個→Wレジスタに代入
SUBWF COUNT,W ;COUNT値-Wレジスタ値の引き算。
BTFSC STATUS,C ;STATUSレジスタのCビットが0なら次行をスキップ
CLRF COUNT ;COUNTを0に戻す
GOTO MAIN
;=========================================================
要するに,待ち時間を変えながら(長・中・短)3つで1セットのLEDの点灯パターンを読みに行ってるだけです。
これを11セット実行して,始めにもどります。まあなんとなく残像っぽく見えるでしょう?
ところでナイトライダーなんて,40~50代のオヤジしか知らないんじゃないの? 僕はオヤジだから,懐かしく思い出しましたけどね(笑)
【今日覚えた命令】 なし
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
拙著「高校物理雑記帳
」のフォロー記事を書きます。
これは,FUJIの使い切りカメラ基板を使ったコッククロフト・ウォルトンの回路です。
本で紹介したのは,コンデンサを4個使ったものでしたが,これは16個も使ってありますからスタンガン並にDC10,000Vの高電圧を作り出すことができます。
コンデンサは耐圧4kVの1000pFセラミックコンデンサ,ダイオードは1N4007という耐圧1kVの整流用のもので,いずれも秋月電子通商で安価に手に入れることができます。 まず,使い切りカメラを分解して,基板を取り出します。電解コンデンサに電気量が残っている場合がありますから,注意してください。ドライバーの先でコンデンサの足をショートさせて,放電させるとよいでしょう。
電解コンデンサとキセノン管は使いませんから,基板から取り外します。この写真に示した場所に3Vの電源を繋ぐと,ダイオードのところから交流650Vを取り出せますから,これを利用します。基板を裏から見た写真がこれです。
AとBは充電用スイッチのランドで,これはスズメッキ線等でショート配線しておきます。トリガスイッチの部分も要りませんからニッパで切り取ります。
ずいぶん以前に手に入れた基板ですから,現在の製品とは基板が少し異なっているかもしれませんが,この写真と比較しながらテスターを当てて調べれば,きっと分かると思います。 ダイオードとコンデンサで作ったコッククロフト・ウォルトンの回路の作り方は,本に書いた通りです。分からない人は本を買ってくださいね(笑)
10,000Vと言っても,電流は少ないので感電しても命を落とすようなことはないと思いますが,やはりケースに入れておきましょう。僕は百均で買ったプラ製の筆箱に入れてみました。
高電圧が必要な実験にコレがあるとなかなか便利ですよ。くれぐれも悪用しないでくださいね(笑)
この回路を使って,フランクリンモーターやムーアのモーターを回すこともできます。こちらをごらんください。
コッククロフト・ウォルトンの回路でどうして昇圧できるのか知りたい人は,2011年度の東京大学の物理の入試問題を解いてみるといいと思います。これはなかなか良くできた問題ですよ。
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
テーブルを使って,LEDをにぎやかにピカピカさせてみました。
ソースはこれ→lesson7.asm
メインプログラムは以下のようになっています。
;============================================================
MAIN
CALL LED_PTN ;LED点灯パターンを決めるサブルーチンへ
MOVWF PORTB ;LED点灯パターンをPORTBへ送る
CALL TIMELOOP1
INCF COUNT,F ;COUNTに1を足してCOUNTに格納
MOVLW D'34' ;LED点灯パターンの総数34をWレジスタに代入
SUBWF COUNT,W ;COUNT-Wレジスタの引き算。
BTFSC STATUS,C ;STATUSレジスタのCビットが0なら次行をスキップ
CLRF COUNT ;COUNTを0に戻す
GOTO MAIN
;=============================================================
まず最初にLEDの点灯パターン(34種類作りました)を決めるサブルーチンへ飛んで,点灯パターンのデータをひとつ貰ってきて,PORTBへ送ってLEDを点灯させます。
1回目はCOUNT(LED点灯パターンカウント値)は0で,34種類中の1番目のデータを貰い,2回目は2番目のデータを貰ってきますが,このサブルーチンについては後述します。
INCF(Increment F)でCOUNTの値に1を足して,COUNTに格納します。
SUBWF(Subtract W from F)でCOUNT値-34の計算をしてWレジスタに格納します。
次にBTFSC(Bit Test F,Skip if Clear)で,STATUSレジスタのCビット(キャリービット)の値をチェックします。
上でやった計算,COUNT値-34の値が負なら(つまりCOUNT値<34なら)Cビットは0になるので,次行をスキップしMAINに戻ります。逆にCOUNT値>=34だとCビットは1になるので,COUNT値が34になったら(つまり34種類の点灯パターンを実行し終わると)COUNT値を0にリセットし,最初にもどります。ああややこしい。
;=============================================================
LED_PTN ;LEDの点灯パターンを決めるサブルーチン
MOVF COUNT,W ;COUNTの数値をWレジスタに代入
ADDWF PCL,F ;「PCL(今のアドレス値)+Wレジスタ値」のアドレスへ
RETLW B'00000000' ;1 Wレジスタに00000000を代入してRETURN
RETLW B'00000001' ;2
RETLW B'00000011' ;3
RETLW B'00000111' ;4
RETLW B'00001111' ;5
RETLW B'00011111' ;6
RETLW B'00111111' ;7
RETLW B'01111111' ;8
RETLW B'11111111' ;9
中略
RETLW B'00000111' ;31
RETLW B'00000011' ;32
RETLW B'00000001' ;33
RETLW B'00000000' ;34
;=============================================================
このサブルーチンでやってることは,次のことです。
ADDWF(ADD W with F)で,実行アドレスにCOUNT値を足して,その結果のアドレスの点灯パターンデータを拾い上げているのです。つまり,COUNTが0だと00000000のデータ,COUNTが1だとその下の00000001のデータを拾うことになるわけです。
【今日覚えた命令】 CLRF,INCF,SUBWF,ADDWF,RETLW
| 固定リンク | 0
| コメント (0)
| トラックバック (0)
あけましておめでとうございます。まだPICマイコンで遊んでます(^-^)
今度は,RLFとRRLのビットシフト命令を使って,LEDを順送り点灯させながら,左→右,右→左へと往復させてみました。
ソースはこれ→lesson6.asm
ポイントは次の通りです。
;================================================
LEFT
RLF PORTB,F ;PORTBの内容を1ビット左にシフトする
CALL TIMELOOP1
BTFSS PORTB,7 ;RB7のLEDが点灯したら次行をスキップ
GOTO LEFT
RIGHT
RRF PORTB,F ;PORTBの内容を1ビット右にシフトする
CALL TIMELOOP1
BTFSS PORTB,0 ;PB0のLEDが点灯したら次行をスキップ
GOTO RIGHT
GOTO LEFT
;=================================================
はじめ,00000001という点灯パターンのデータを左に順にシフトしていき,RB7が1になったら今度は逆にデータを右にシフトしていきます。で,RB0が1になったらまたシフトの方向を反転させるわけです。
よしよし,なんだか少しずつアセンブラの感覚が身に付いてきたような気がするぞ(^^)
ついでに前回より速く点灯LEDを動かしています↓
【今日覚えた命令】 RRF
| 固定リンク | 0
| コメント (0)
| トラックバック (0)