- ベストアンサー
処理時間の計算 PICアセンブラ
あるプログラムで、TIMERというサブルーチンを作りました。適当に数値を変えてうまく行った値を採用したのですが、実際に処理時間が何秒かかるのかが分りません。 TIMER MOVLW 0x40 ;この40が採用した値です MOVWF WC1 LOOPT DECFSZ WC2,F ;WC2はあらかじめCLRされてます GOTO LOOPT DECFSZ WC1,F RETURN 見難くてすいません(TIMER、LOOPTがラベルです) 使用ハードはPIC16F84Aでクロック周波数は20[MHz]です。 たしか通常は一つの命令にクロック4周期分だった気がするので、最初の二行で8/20M[s]なのは分るんですが、LOOPTのDECFSZとかは4周期分じゃなかったような気がして、混乱してしまいました・・・。 知りたいのはRETURNで戻るまで(メインルーチンに戻るまで)です。 わかる方ご教示願います。
- ZZR1200
- お礼率76% (127/167)
- その他(プログラミング・開発)
- 回答数2
- ありがとう数2
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
>DECFSZは2命令サイクル必要な時と1命令サイクルでいいときがあって混乱しています。 そんなに難しい話ではないと思いますが。 この種の条件が成立した時にスキップという命令の場合、 条件が成立しない場合は1サイクル(4クロック)、成立してスキップする場合2サイクルかかるだけです。 条件によって処理する量が違うので、スキップという処理を余分に行う分、余計なサイクルが必要なだけですから。 結局、こんな感じのサイクル数になると思います。 MOVLW 1サイクル MOVWF 1サイクル DECFSZ (1サイクル * 0xff + 2サイクル) * 0x40 GOTO (2サイクル * 0xff ) * 0x40 DECFSZ 1サイクル * 0x3f + 2サイクル GOTO 2サイクル * 0x3f RETURN 2サイクル 多分二重ループでしょうから LOOPTへのジャンプがあるはずとGOTOを一つ追加しております。 この合計を4倍すればクロック数がでます。 各命令のサイクル数は手元の「PICマイコン活用ハンドブック」で調べました。 ちなみに、まだPICでプログラム作ったことはありません(^^;
その他の回答 (1)
- haiji2004
- ベストアンサー率25% (48/187)
サイクル数が正確にわからないと答えようがないと思いますが、、、 オシロで測定してみるというのは無しですか?
お礼
回答ありがとうございます すいません。さらに補足です。 DECFSZは2命令サイクル必要な時と1命令サイクルでいいときがあって混乱しています。 言い回しが不適切で申し訳ありません
補足
1命令サイクルは20[MHZ]4周期分です。 これで計算できませんかね?
関連するQ&A
- PIC16F84Aから16F628Aの変換について
以前PIC16F84Aで問題なく動作しているプログラムを 初期設定を変えて(これでいいのか?も疑問)16F628Aで動かそうとしていますが サブルーチンに入り「タイマー」のルーチンから抜け出せないみたいです。 BILD ALL ではエラーは出ません。 割込みは正常に動作します。 どこがいけないのでしょうか? よろしくお願いいたします。 プログラムはこちらです。 ;------------------------------------------------------------------------- ; 初期設定 list P=pic16f628a include "p16f628a.inc" __CONFIG _HS_OSC & _CP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _LVP_OFF & _MCLRE_OFF ORG 0 GOTO MAIN ;----------------------------------------------------------------------- ; 割り込み処理 ORG 4 ;割り込みアドレス CLRW CLRF PORTB ;ポートBクリア GOTO MAIN ;----------------------------------------------------------------------- ; メインプログラム MAIN BCF STATUS,RP0 MOVLW B'00000111' MOVWF CMCON BSF INTCON,INTE ;割りこみ許可? BSF STATUS,RP0 ;ポートAを全て入力に設定 MOVWF TRISA MOVLW H'01' ;ポートBは0(ゼロ)以外は出力に設定 MOVWF TRISB MOVLW 90H ;INT割り込み許可 MOVWF INTCON BCF STATUS,RP0 ;ポートBをクリア CLRF PORTB CLRW ;---------------------------------------------------------------------- ; スイッチ入力チエック LOOP BTFSS PORTA,0 ;オープンSWがONか? GOTO OPEN ;ONだったら OPENへ GOTO LOOP ;----------------------------------------------------------------------- ; オープン動作 OPEN MOVLW 010H ;ポートB4番に5V出力(リレーON) MOVWF PORTB MOVLW D'250' ;動作時間 '250'設定 MOVWF 0EH ;アドレス0EHに250を入力 CALL LOOP3 ;サブルーチンLOOP3を呼び出す GOTO MAIN ;サブルーチンが終わったら MAIN に戻れ ;------------------------------------------------------------------------ ;----------------------------------------------------------------------- ; サブルーチン(タイマー) TIMER1 MOVLW D'220' MOVWF 0CH LOOP1 NOP DECFSZ 0CH,1 GOTO LOOP1 RETURN TIMER2 MOVLW D'100' ;アドレス0DHに100を入力 MOVWF 0DH LOOP2 NOP CALL TIMER1 ;TIMER1を呼び出し(行く) DECFSZ 0DH,1 ;アドレス0DH から1を引き算する GOTO LOOP2 ;結果が"0"でなかったら LOOP2に戻ってまた引き算 RETURN ;引き算の結果が"0"になったら「CALL」した「次に(下)」へ戻る LOOP3 NOP ;何もしない CALL TIMER2 ;TIMER2を呼び出す(行く) DECFSZ 0EH,1 GOTO LOOP3 RETURN END END
- ベストアンサー
- その他(ソフトウェア)
- PIC 簡単なプログラミングで行き詰まりました
PIC初心者です。よろしくお願いします。 PIC16F84Aを使って 「ポートA 0bIt 」 に入力があったとき(1になったとき) ラベルの「OPEN」に飛びポートBのLEDが一秒点灯。 「ポートA 1bit 」に入力があったとき ラベルの「CLOSE」に飛びポートBのLEDが一秒点灯。 これだけのプログラムなのですが MPLAB IDE v8.63で Debug all すると ;の記述のところで表記のエラーが出ます。 プログラムはこちらです。 list P=pic16f84a include "p16f84a.inc" __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF CNT1 EQU 0CH CNT2 EQU 0DH CNT3 EQU 0EH ORG 0 GOTO MAIN MAIN BSF STATUS,RP0 MOVWF TRISA CLRF TRISB BCF STATUS,RP0 CLRF PORTB CLRW LOOP BTFSC PORTA,0 GOTO OPEN BTFSC PORTA,1 GOTO CLOSE ;ここで「Symbol not previously defined (CLOSE)」 のエラー GOTO LOOP OPEN MOVLW 010H MOVWF PORTB CALL TIMER3 ;ここでSymbol not previously defined (TIMER3)エラー CLRF PORTB END CLOSE MOVLW 020H MOVWF PORTB CALL TIMER3 CLRF PORTB END TIMER1 MOVLW D'62' MOVWF CNT1 LOOP1 NOP DECFSZ CNT1,1 LOOP1 RETURN TIMER2 MOVLW D'100' MOVWF CNT2 LOOP2 NOP CALL TIMER1 DECFSZ CNT2,1 goto LOOP2 RETURN TIMER3 MOVLW D'100' MOVWF CNT3 LOOP3 NOP CALL TIMER2 DECFSZ CNT3,1 goto LOOP3 RETURN END 何日も堂々巡りをしてまして埒があかないので質問させていただきました。 どこが間違えているのでしょうか???? よろしくお願いいたします。
- ベストアンサー
- その他(インターネット・Webサービス)
- PIC 初心者で行き詰まりました(汗、、、)
PIC初心者です。よろしくお願いします。 PIC16F84Aを使って 「ポートA 0bIt 」 に入力があったとき(1になったとき) ラベルの「OPEN」に飛びポートBのLEDが一秒点灯。 「ポートA 1bit 」に入力があったとき ラベルの「CLOSE」に飛びポートBのLEDが一秒点灯。 これだけのプログラムなのですが MPLAB IDE v8.63で Debug all すると ;の記述のところで表記のエラーが出ます。 プログラムはこちらです。 list P=pic16f84a include "p16f84a.inc" __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF CNT1 EQU 0CH CNT2 EQU 0DH CNT3 EQU 0EH ORG 0 GOTO MAIN MAIN BSF STATUS,RP0 MOVWF TRISA CLRF TRISB BCF STATUS,RP0 CLRF PORTB CLRW LOOP BTFSC PORTA,0 GOTO OPEN BTFSC PORTA,1 GOTO CLOSE ;ここで「Symbol not previously defined (CLOSE)」 のエラー GOTO LOOP OPEN MOVLW 010H MOVWF PORTB CALL TIMER3 ;ここでSymbol not previously defined (TIMER3)エラー CLRF PORTB END CLOSE MOVLW 020H MOVWF PORTB CALL TIMER3 CLRF PORTB END TIMER1 MOVLW D'62' MOVWF CNT1 LOOP1 NOP DECFSZ CNT1,1 LOOP1 RETURN TIMER2 MOVLW D'100' MOVWF CNT2 LOOP2 NOP CALL TIMER1 DECFSZ CNT2,1 goto LOOP2 RETURN TIMER3 MOVLW D'100' MOVWF CNT3 LOOP3 NOP CALL TIMER2 DECFSZ CNT3,1 goto LOOP3 RETURN END 何日も堂々巡りをしてまして埒があかないので質問させていただきました。 どこが間違えているのでしょうか???? よろしくお願いいたします。
- 締切済み
- その他(プログラミング・開発)
- picアセンブラ ビルドは完了するのに動かない
なんとかかんとかMPLABでLEDが1秒間隔で交互に光るプログラムを 作ったんですが、全く動きません・・・ 考えてたら頭がこんがらがってきてしまいました。 PICは16F628Aです。 何処が悪いのか教えてください。 ポートBにつないだ8個のLEDが4個ずつ 1秒おきに交互に光るプログラムです。 なお、1秒の時間稼ぎですがこれまたこんがらがってきたので とりあえず適当に遅延させています。 ----------------------------- list p=pic16f628a include "p16f628a.inc" __config _boden_off & _cp_off & _pwrte_on & _wdt_off & _lvp_off & _mclre_off & _hs_osc time1 equ 020h time2 equ 021h time3 equ 022h time4 equ 023h org 0 goto start start bsf status,rp0 clrf trisb bcf status,rp0 main movlw b'00001111' movwf portb call jikan movlw b'11110000' movwf portb call jikan jikan movlw d'2' movwf time1 matu1 movlw d'10' movfw time2 matu2 movlw d'200' movfw time3 matu3 movlw d'200' movfw time4 matu4 nop nop decfsz time4,f goto matu4 decfsz time3,f goto matu3 decfsz time2,f goto matu2 decfsz time1,f goto matu1 return end
- ベストアンサー
- その他(プログラミング・開発)
- PIC アセンブラ TMR0の使い方がいまいちわかりません。
*文字数制限の為コメントや繰り返し処理プログラムの一部を省きました。解りにくくてすみません。ココに載せてくれとかあったらそっちに全部載せます。 目標としてはPICでデジタル時計を作りたいのですが、手始めに正確な1秒を作って7セグを0から9まで表示しそれを繰り返す。と言うものをやってみようと思いプログラムしましたがウンともスンとも言いません。 流れとしては 初期処理 ↓ TMR0割り込みが発生するまで無限ループ ↓ 割り込みが発生したら割り込み回数をカウントし(12,8MHzクロック、プリスケーラを256設定で1250回フラグをカウントすると1秒)1秒間分カウントが終わったら7セグの表示を切り替え無限ループに戻る どの数字まで表示したかは任意のレジスタに1を立てて判断する。PICはPIC16F628AなのでTMR1とかもあるんですが気分的にTMR0だけで時間を作ってみたかったのでTMR1とかは使ってません。で、3回くらいやり直してプログラムを作ったんですが全然動きません。 1、何処が悪いんでしょうか? 2、また、PIC16F628Aでは16番ピンがクロックの入力として使えますが その設定方法があってるかわかりません。 コンフィグ設定で OSCをHSにしてポートの設定でRA7を入力にしておけば良いんでしょうか?プログラム中の記述で合ってますでしょうか? 3,7セグをカウントアップするだけのプログラムなのに こんなに長くなる物なんですか? (プログラムが下手だから?アセンブラだから?) 4、1秒のカウント方法ですがプログラム中の記述で正確に1秒をカウントしてますか?(計算間違ってますでしょうか?) 以下、プログラムになります。 list p=pic16f628a include "p16f628a.inc" __CONFIG _LVP_OFF &_MCLRE_ON &_BODEN_OFF &_PWRTE_ON &_WDT_OFF &_HS_OSC time0 equ d'30' ;time4まで作る tcount equ d'43' count0 equ d'35' ;count7まで作る koko0 equ d'43' koko1 equ d'44' org 0 goto start org 4 goto wari start bcf intcon,gie movlw b'00000111' movwf cmcon bsf status,rp0 movlw b'00000111' movwf option_reg movlw b'10100000' movwf trisa clrf trisb bcf status,rp0 bcf status,z bcf intcon,t0if movlw b'00001000' movwf count0 ;この間に1から6の同じ処理が入ります。 movlw b'00000000' movwf count7 time movlw .30 movwf time0 bsf intcon,gie bsf intcon,t0ie clrf tmr0 roop btfsc tcount,0 call segout swapf count0,0 movwf portb swapf portb,0 movwf count0 ;この間に1から5が入ります swapf count6,0 movwf portb swapf portb,0 movwf count6 goto roop wari bcf intcon,t0ie bcf intcon,t0if incf time0,1 btfss status,z goto modori bcf status,z movlw .255 movwf time0 incf time1,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 incf time2,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 movlw .255 movwf time2 incf time3,1 bcf status,z goto modori bcf status,z movlw .255 movwf time0 movlw .255 movwf time1 movlw .255 movwf time2 movlw .255 movwf time3 incf time4,1 bcf status,z goto modori bcf status,z movlw .30 movwf time0 movlw b'00000001' movwf tcount modori bsf intcon,t0ie retfie segout clrf tcount btfss koko0,0 goto seg1 ;この中間にseg2からseg6が入ります。 btfss koko0,7 goto seg8 btfss koko1,0 goto seg9 nop goto seg0 seg1 bsfkoko0,0 movlw b'00000010' movwf count0 movlw b'00000100' movwf count1 movlw b'00000000' movwf count2 movlw b'00000000' movwf count3 movlw b'00000000' movwf count4 movlw b'00000000' movwf count5 movlw b'00000000' movwf count6 movlw b'00000000' movwf count7 nop return ;この中間にseg2からseg9が入ります seg0 clrf koko1 clf koko0 movlw b'00001000' movwf count0 movlw b'00000100' movwf count1 movlw b'00000010' movwf count2 movlw b'00000001' movwf count3 movlw b'10000000' movwf count4 movlw b'01000000' movwf count5 movlw b'00000000' movwf count6 movlw b'00000000' movwf count7 return end
- ベストアンサー
- その他(プログラミング・開発)
- このプログラムがどういう流れで動いてるか教えてください
PICのプログラミングで以下の課題が学校ででました。 PB0~PB5まで1秒ごとに交互に点灯するプログラムを書くというものです。 CNT1 EQU 20H CNT2 EQU 21H main MOVLW B'00010101' MOVWF PORTB CALL TIM2 MOVLW B'00001010' MOVWF PORTB CALL TIM2 GOTO main TIM1 MOVLW 0F9H MOVWF CNT1 TIMLP1 NOP DECFSZ CNT1,F GOTO TIMLP1 RETURN TIM2 MOVLW 08H MOVWF CNT2 TIMLP2 CALL TIM1 DECFSZ CNT2,F GOTO TIMLP2 RETURN END 上記のプログラムで動きました。 だけど、このプログラムの流れがわからないため 説明できません。 誰かこのプログラムの流れをわかりやすく説明してください。 特にCALLとRETURN、DECFSZがどう動くかわかりません。
- ベストアンサー
- その他(プログラミング・開発)
- PIC12F683 TMR2の割込がうまくいきませ
タイトルのPICを使ってTMR2の割込動作を確認しているのですが、割込が全く掛かりません。 TMR2は単独で割込を掛けないで動作することは確認できましたがエラーもあるわけでもなく あれこれやっても解決せず迷走中です。また、割込ルーチンはこれまで動作が確認できたプログラムを埋め込んで使っているので問題はないと思っています。 何方かお助け頂けませんでしょうか。宜しくお願い致します。 ;******************************************* ; PIC初期設定 ;******************************************* START_INI BCF STATUS,RP0 ;BANK【0】 MOVLW 07h MOVWF CMCON0 ;GP0-2はデジタルIO BSF STATUS,RP0 ;BANK【1】 MOVLW B'0000000' MOVWF ANSEL ;A/D変換クロックF/2 デジタルI/O BCF OPTION_REG,7 ;GPIO端子をプルアップ MOVLW B'001000' ;RESET端子有効 MOVWF TRISIO ;GP0,1,2,4,5:OUT GPO3:IN MOVLW B'1000000' ;40h MOVWF OSCCON ;クロック=1MHz ;******************************************* ; TMR2の設定 ;******************************************* BCF STATUS,RP0 ;BANK【0】 MOVLW B'000101' ;ポス=1:1 TMR2=ON プリ=1:4 MOVWF T2CON ; BCF PIR1,TMR2IF ;Timer2 割込み検出フラグをクリア BSF STATUS,RP0 ;BANK【1】 BSF PIE1,TMR2IE ;Timer2 有効 MOVLW H'FA' ;250 MOVWF PR2 ;TRM2カウントSET ;******************************************* BCF STATUS,RP0 ;BANK【0】 CLRF TMR2 BSF INTCON,GIE ;割り込み全体を有効
- ベストアンサー
- 電気設計
- PICでLEDを点滅させる
16F628Aを使ってLEDが点滅するプログラム作ることはできたのですが、それを16F873A用に組み替えてみたのですが点滅せずに点灯したままになります。ハード的な問題なのかそれともプログラム問題なのかがわかりません。マイコンの勉強をはじめたばかりなのでお教えいただければたすかります。 ちなみにプログラムは以下のようになっています。クロックは10MHzです。 開発環境はMPLABをつかっていて秋月のキットを使って書き込んでいます。 ; ; ; list p=pic16f873a #include <P16F873A.INC> __CONFIG _WDT_OFF & _HS_OSC & _CP_OFF & _PWRTE_ON & _LVP_OFF COUNT EQU 20H COUNT1 EQU 21H ORG 0 MAIN BSF STATUS,RP0 CLRF TRISA CLRF TRISB CLRF TRISC BCF STATUS,RP0 MOVLW B'11111111' MOVWF PORTC CALL LA CLRF PORTC CALL LA GOTO MAIN LA MOVLW B'11111111' MOVWF COUNT LOOP2 MOVLW B'11111111' MOVWF COUNT1 LOOP NOP NOP NOP NOP NOP NOP NOP DECFSZ COUNT1,1 GOTO LOOP DECFSZ COUNT,1 GOTO LOOP2 RETURN END
- ベストアンサー
- その他(プログラミング・開発)
- PIC16F84のプログラム
PIC16F84のプログラムでこのようなものを作りました。 revel1 movlw 75 movwf tm3 movlw 255 movwf tm4 no1_on mov rb,#11110000b ;(1) mov rb,#10000000b mov rb,#11000000b mov rb,#10100000b mov rb,#11000000b mov rb,#10000000b ;(2) decfsz tm4,1 goto no1_on decfsz tm3,1 goto no1_on これは、(1)~(2)の動作を75×255=19125回(多分)繰り返すという物です。 同様の処理を多数行ないたいのですが、プログラムしてみたところ、容量オーバーの為か?アセンブルできませんでした。これを同様の動作でもう少しシンプルに出来ないでしょうか?よろしくお願いします。
- ベストアンサー
- その他(プログラミング・開発)
- PIC、USART USART送信ができません
下記のプログラムでUSART接続してPICマイコンからPCに送信しようとしています。 PICマイコンはP16F877 アプリにはTera Term というアプリケーションを使用しています。 このプログラムはUSARTの送信とステッピングモータを交互に動作させるプログラムです。 このプログラムを実行したところ、ステッピングモータが微小に動作したままとまってしまいました。 Tera Termにも文字は出力されませんでした。 そのため、1周目だけTXREGレジスタにデータを格納するところまでは出来ていると思います。 しかし、データ送信が行われないため、2週目以降はTSRレジスタがBUSY状態となりプログラムが進行しないのだと考えています。 以下のサイトを参考に模索しましたが、原因が分かりませんでした。 http://www.kimurass.co.jp/pic/0625p.htm http://www.picfun.com/pic19.html どのように対処したらよろしいでしょうか? 原因やアドバイスなど教えていただけたら幸いです。 ~~プログラム~~ list p=16F877 #include <p16F877.inc> __CONFIG _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF& _LVP_OFF w_temp EQU 0x0C status_temp EQU 0x0D ;変数 cblock 020h CNT15mS ;15mSカウンタ CNT5mS ;5mSカウンタ CNT1mS ;1mSカウンタ CNT50uS ;50μSカウンタ USART_TEMP ;USARTのワークレジスタ POINT ;point of table BUFFER ;buffer endc ;*************************割り込み退避************************** ORG 0x000 goto MAIN ORG 0x004 movwf w_temp movf STATUS,w movwf status_temp movf status_temp,w movwf STATUS swapf w_temp,f swapf w_temp,w retfie ;************************************************************* MAIN ;-----------------------------設定---------------------------- ;BANK1 Setting bsf STATUS,RP0 clrf TRISA movlw B'11110000' clrf TRISB movlw B'01000000' movwf TRISC ;RXピンを入力に設定 movlw B'00100000' movwf TXSTA ;SET TX MODE movlw 0FH ;Set Baud Rate 19Kbps movwf SPBRG ;Set BRG ;BANK0 Setting bcf STATUS,RP0 clrf INTCON movlw 07H movwf ADCON1 ;------------------------------------------------------------ ;----------------------------初期化--------------------------- clrf PORTA clrf PORTB bcf STATUS,C bcf STATUS,Z ;------------------------------------------------------------ ;===========================MAIN_LOOP======================== MAIN_LOOP bsf STATUS,RP0 READY_CHECK btfss TXSTA,TRMT goto READY_CHECK bcf STATUS,RP0 movlw 'A' movwf TXREG call STEPPING_MOTTER goto MAIN_LOOP ;============================================================ ;================= STEPPING MOTORE ========================== STEPPING_MOTTER call wait1ms call wait1ms movlw B'00000001' movwf PORTB call wait1ms call wait1ms movlw B'00000010' movwf PORTB call wait1ms call wait1ms movlw B'00000100' movwf PORTB call wait1ms call wait1ms movlw B'00001000' movwf PORTB RETURN ;================= 15mS WAIT ================================ wait15ms MOVLW d'3' MOVWF CNT15mS wait15ms_loop CALL wait5ms DECFSZ CNT15mS,F GOTO wait15ms_loop RETURN ;================= 5mS WAIT ================================= wait5ms MOVLW d'100' MOVWF CNT5mS wait5ms_loop CALL wait50us DECFSZ CNT5mS,F GOTO wait5ms_loop RETURN ;================= 1mS WAIT ================================= wait1ms MOVLW d'20' MOVWF CNT1mS wait1ms_loop CALL wait50us DECFSZ CNT1mS,F GOTO wait1ms_loop RETURN ;================= 50μS WAIT ================================ wait50us ; 1サイクル(4クロック):0.2μS ; 50μS=0.2μS×250サイクル MOVLW d'82' ;1 MOVWF CNT50uS ;1 wait50us_loop DECFSZ CNT50uS,F ;1 GOTO wait50us_loop ;2 RETURN ;2+1 ;============================================================ ;------------------------------------------------------------ END
- ベストアンサー
- その他(プログラミング・開発)
お礼
あ、GOTO TIMER忘れてましたね…。ありがとうございます
補足
訂正。GOTO LOOPTですね。 なんかボケてますね ありがとうございました