teacup. [ 掲示板 ] [ 掲示板作成 ] [ 有料掲示板 ] [ ブログ ]

 投稿者
  題名
  内容 入力補助画像・ファイル<IMG> youtubeの<IFRAME>タグが利用可能です。(詳細)
    
 URL
[ ケータイで使う ] [ BBSティッカー ] [ 書込み通知 ] [ 検索 ]


下記,自己解決

 投稿者:matsu  投稿日:2014年11月10日(月)21時44分59秒
返信・引用
  下記,なんとか自己解決できそうです。
糸口はつかめましたので,なんとかがんばってみます。
ありがとうございました。
 
 

pic timer0

 投稿者:matsu  投稿日:2014年11月10日(月)09時29分51秒
返信・引用
  > No.655[元記事へ]

すみません。ターゲットを書き忘れました。
PIC16F1823です。
よろしくお願いいたします。
 

pic timer0

 投稿者:matsu  投稿日:2014年11月10日(月)09時27分26秒
返信・引用
  初めまして。
このような掲示板を開設してくださり,ありがとうございます。ネット検索して見つけました。

picのプログラミングで,煮詰まってしまいました。
どなたか,アドバイスいただけませんでしょうか?
これまで,H8の開発はたくさんしてきましたが,初めてpicに乗り換えています。

mplab x ide 2.25, xc8 1.33
で,プログラミングしていますが,
timer0がカウントアップしかできないことに戸惑ったのですが,オーバーフローで0になった後も,カウント初期値を
代入するまでの間,カウントが進んでしまいます。そのため正確なタイミングで割り込みができないので,
下記のようにTMR0の書き換えを行わないで,256カウントさせています。1秒経過毎に二つのLEDを交互に点滅していますが,
どうしても2秒経過毎に交互点滅してしまっているようです。
(Foscを16MHzとして,(Fosc/4)でTIMER0を使用しています)

#define TMR0cnt 0  //for 256/4=64us interrpt
void initTimerForRC_MODE(void)
{
    OPTION_REG = 0b00001111;//p177
    // 弱プルアップWPUxラッチによる,RB0/INTピン立下りエッジで割り込み,(Fosc/4)でTIMER0を使用,
    //立ち上がりインクリメント,プリスケーラOFF,プリスケーラカウント値 1:2使用せず
    //4MHzクロックカウントのはず,16MHz/4,Time0は勝手に走る?みたい
    TMR0   = TMR0cnt;    // 255-TMR0cnt+1カウントごとに割り込み,64usごとに割り込み発生のはず
    TMR0IF = 0 ;         // タイマー0割込フラグ(T0IF)を0にする, p93 INTCON
    TMR0IE = 1 ;         // タイマー0割込み(T0IE)を許可する, P93 INTCON

//    T1CON = 0b00100000;  // Fosc/4, 1:4, オシレータ無効,外部クロック無視,Timer1停止 ,1MHzカウント
    GIE    = 1 ;         // 全割込み処理を許可する
}

volatile unsigned long timeus=0;
void interrupt interruptFunc(void)
{
     if(TMR0IF==1) {        // タイマー0の割込み発生か?
          //TMR0   = TMR0cnt+3; // タイマー0の初期化・・・なし
          TMR0IF = 0 ;      // タイマー0割込フラグをリセット
     }
     timeus+=64;
     if((timeus%1000000)<64){
         toggleLed();
     }
}

試しに,
    while(1){
        toggleLed();
        __delay_ms(1000);
    }
としてみると,ほぼ正確に1秒ごとに切り替わっていますので,Foscは16MHzであることは間違いないようなのですが・・・。
64us毎に割り込むはずが,どうもそうならないようで,戸惑っています。どこに原因があるのか,
アドバイスをいただけませんでしょうか。よろしくお願いいたします。


config bits関係は下のようになっています。

#define _XTAL_FREQ 16000000
#define waitus __delay_us
#define waitms __delay_ms

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>

// CONFIG1
#pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF       // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF      // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
#pragma config BOREN = ON       // Brown-out Reset Enable (Brown-out Reset enabled)
#pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
// CONFIG2
#pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
#pragma config PLLEN = OFF      // PLL Enable (4x PLL enabled)
#pragma config STVREN = ON      // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON         // Low-Voltage Programming Enable (Low-voltage programming enabled)

 

Re: タイマーですか。

 投稿者:初心者  投稿日:2014年11月 9日(日)21時10分47秒
返信・引用
  nekosanさん様

いつもすみません。 どつぼにはまっております。

>
> ジムカーナの様に、一度に1台だけ走る感じなんでしょうかね?
> 光電管で複数台走る方法だと、各車のスタートとストップを
> 車ごとに管理する必要があるので。

はい、この後で16F648Aでカウンター組むかストップウォッチを改造するか2パターンで考えています。

> スタートとゴールの2箇所からの信号(両方光電管?)であれば、
> 入力信号は2本(1本に共用してもok?)と、あとはせいぜい
> 必要に応じてリセット信号(リセットピンでもGPIOでもどちらでも)
> 程度で、計1~3本の入力があれば足りそうですかね…。
>
> 残ったピンから1~2本をストップウォッチ操作の出力(スタート、
> ストップ、リセット)にまわす感じで。
>
>
> よく考えると、マイコン自体で時間を計測するわけではない
> ので、タイマー割込みとか使わなくても、1回信号が入って
> 来たら、その都度1秒前後(?)空回しで入力を無視するように
> して、それ以降は入力があったら出力に即反映…というような、
> 時間的なフィルター処理でも用を足すのかな、という気がしました。

その通りです! それをやりたいんです。
説明が足りなくて申し訳ありません。

ですが、入力が入ったと同時(目標0.001秒以内・・・マイコンではかなり長そうですが)に出力信号が立ち、3秒位後に(こちらはばらつきがあっても問題なし)出力信号が消えればいいんです。

問題はそれを2回路で平行して一個のPICでやりたいんです。

前々回のプログラムだと、片方の回路の処理が終わるまでもう一方の回路は信号を受け付けないのです。

> (そのくらいの機能なら、12F629や675、場合によってはNE555の
> ワンショットタイマ+論理回路でも)

NE555で回路を組んだこともあるんですが、あといくつか作ることになりそうなので部品点数が多いのは老眼できついです。

>
> ちなみに、光電管ではない方式について、以前見つけた情報が
> ありました。Tsukuba2000とかで使われてるP-LAPという方式で、
> 路面に埋め込んだ磁石の磁気を拾う方式のものです。

たいていのサーキットはどうやら磁石を埋め込んであるようです。 私もサーキットを走ったことはあまりないしレースで走ったことはないので詳しくは知りませんが。

サーキットではなくて空き地(勝手に走るわけではないですけど)でパイロンたてて練習するときなどを考えてます。

現在12F629でTMR0でカウントアップ後に出力信号を消せないか試しています。
結果がでたらお知らせします。
 

Re: タイマーですか。

 投稿者:nekosan  投稿日:2014年11月 8日(土)19時28分31秒
返信・引用
  > No.652[元記事へ]

> 回路はスタート、ゴールの二か所だけです。 センサーは自作なのでこちらでタイマーを持たせようと思っています。 この回路の出口でストップウォッチに入力します。
> バイクで測定しようと思っていますので、数秒の保持時間がないと、前輪で切って復帰して次にエンジンで切って今度は後輪で・・・となってしまいます。
> まあスタート直後にゴールしないようなコース設定?にしておけば済む話ではありますが・・・
>
> とにかく、センサーを切って割り込みが発生したら直ちにタイマーを動作させてすぐMAINループに戻り、もう一方のセンサーが切れるかタイマーアップするのを待つことが目標です。
>
> 案1:タイマー割り込み・・・複数でも拾ってくれればありがたいですね。
> 案2:12F63でCCP機能・・・まったく初耳です。手持ちがあるので調べてみます。
>
> もう少し悩んでみます。 ありがとうございます。
>



光電管の場合、車体の数箇所で信号が発生するので、確かに
その辺の処理が必要になるのでしょうね。

ジムカーナの様に、一度に1台だけ走る感じなんでしょうかね?
光電管で複数台走る方法だと、各車のスタートとストップを
車ごとに管理する必要があるので。


http://homepage3.nifty.com/mitt/pic/pic683_1.html
http://ktsite.ddo.jp/PIC/12f683/CCP.html

CCPのコンペア機能については、このあたりを眺めると、
多分他のPICの様に、コンペアマッチイベントの割り込み間隔
を任意サイクルにセット出来るようです。
多分他のPICと大体同じ機能が載っているかと思います。


スタートとゴールの2箇所からの信号(両方光電管?)であれば、
入力信号は2本(1本に共用してもok?)と、あとはせいぜい
必要に応じてリセット信号(リセットピンでもGPIOでもどちらでも)
程度で、計1~3本の入力があれば足りそうですかね…。

残ったピンから1~2本をストップウォッチ操作の出力(スタート、
ストップ、リセット)にまわす感じで。


よく考えると、マイコン自体で時間を計測するわけではない
ので、タイマー割込みとか使わなくても、1回信号が入って
来たら、その都度1秒前後(?)空回しで入力を無視するように
して、それ以降は入力があったら出力に即反映…というような、
時間的なフィルター処理でも用を足すのかな、という気がしました。
(そのくらいの機能なら、12F629や675、場合によってはNE555の
ワンショットタイマ+論理回路でも)


ちなみに、光電管ではない方式について、以前見つけた情報が
ありました。Tsukuba2000とかで使われてるP-LAPという方式で、
路面に埋め込んだ磁石の磁気を拾う方式のものです。

製品版は高いですが、自作している人がいました。

http://www.asahi-net.or.jp/~tw8i-ysd/CAR/MAKE/plap-modoki.htm
http://www.asahi-net.or.jp/~tw8i-ysd/CAR/MAKE/sens.htm

センサーや機器類は車体に積んで走るので、同時走行しても
個々の車体のタイム計測が可能です。

サーキットの様に、スタートとストップが同じセンサーで
拾うことになるので、ラップタイム計測などには便利ですが、
ジムカーナの様にスタート-ストップ間を1回だけ計測する
のには向かないかも知れません。


あと、この方式だとアナログ周りの調整とかが色々面倒では
あります。強力磁石をダイソーとかで買ってきて、スタートと
ゴールの地面に並べておくとか、磁気センサーはハードオフ
とかで中古カセットプレイヤーとか…

自分では実験していないので、詳しいことはわからないですが。
 

タイマーですか。

 投稿者:初心者  投稿日:2014年11月 8日(土)09時40分7秒
返信・引用
  nekosan様
いつもアドバイスをいただきありがとうございます。

回路はスタート、ゴールの二か所だけです。 センサーは自作なのでこちらでタイマーを持たせようと思っています。 この回路の出口でストップウォッチに入力します。
バイクで測定しようと思っていますので、数秒の保持時間がないと、前輪で切って復帰して次にエンジンで切って今度は後輪で・・・となってしまいます。
まあスタート直後にゴールしないようなコース設定?にしておけば済む話ではありますが・・・

とにかく、センサーを切って割り込みが発生したら直ちにタイマーを動作させてすぐMAINループに戻り、もう一方のセンサーが切れるかタイマーアップするのを待つことが目標です。

案1:タイマー割り込み・・・複数でも拾ってくれればありがたいですね。
案2:12F63でCCP機能・・・まったく初耳です。手持ちがあるので調べてみます。

もう少し悩んでみます。 ありがとうございます。


 

Re: もう一つおしえてください。

 投稿者:nekosan  投稿日:2014年11月 8日(土)00時56分44秒
返信・引用
  > No.650[元記事へ]

> ストップウォッチのゲート回路に使うつもりですが、入出力2回路を1個のPICに入れています。以前は疑似割り込み回路を使っていたのですが、最近USBロジアナを安価(500円!)で手に入れて調べてみたら結構反応時間にばらつきがあります。
> で、何とか割り込みをつかって動くようにしたのですが、チャタリング防止のため遅延を入れると片側が反応している間、もう一方の反応がブロックされます。
> 当たり前といえば当たり前ですが、なんとか並行して動くようにできないのでしょうか。
> 長いですがコードを書いてみます。



周辺の回路などが分らないので、全体の動きは詳しく
分らないのですが、光電管からの信号をトリガに、
経過時間を計測するストップウォッチで、その他いくつか
の入力(ボタン操作?)を元に、クリアとかラップタイム
とかの操作が出来るもの、と簡単に仮定して考えました。


この世代のPICは、確か複数割り込み要因の処理が苦手
(出来なくはないけど、割り込み要因の区別がハード的に
 付かないので、割り込みルーチン内で振り分け処理が
 必要だったりなど、かなり面倒)だったと思うので、
そもそも複数割り込み要因が発生する構造にすると、
色々面倒なことになるかと思います。

また、ピンチェンジ割り込みも、複数ピンが同時に変化
した場合に、ソフトウェア上は、それらを1個1個を
シーケンシャルに処理する必要があります。PICか
どうかに関わらず、複数のピンチェンジ割り込みを使う
と、かならずズレが生じてしまうので、この点が問題と
いうご指摘かと思います。


ストップウォッチの精度をどのくらいに仕上げるかという
ことに繋がるかと思うのですが、一般的なストップウォッチ
の用途であれば、せいぜい1/1000秒で計測できれば、大抵
は用が足りるものかと思います。せいぜい、1/10000秒まで
精度がでれば、充分かと。(←前提)

で、ピンチェンジ割り込みを使うのではなく、1/1000秒ごと
とかで、タイマー割込みをフリーランさせておいて、割り込み
が発生するごとに

 (1)カウンタアップ(経過時間の計測)
 (2)入力処理(ポート単位で入力すれば、最大8信号まで)
 (3)各入力ポートの内容に合わせて内部処理(カウンタ
    リセットとか)

で、メイン処理側では、カウンタ値の表示処理を行ったり
という具合にすれば、1/1000秒の精度で、複数の信号を
処理できるのではないかと思います。ちなみに、光電管からの
入力も、この(2)の入力ピンのうちの1本に含めます。
光電管以外に最大7信号まで並列に処理できます。
(もちろん、GPIO端子がそれだけ載っていれば)


このくらいの処理負荷(特に割り込み処理内)であれば、
C言語コンパイラを使っても、充分な処理速度が出るのでは
と思います。

チャタリング防止は、外部回路でLPF+シュミットトリガを
組むか、もしくは、割り込み処理内にて、一度変化をしたら、
そのあと1/100秒程度は変化がおこっても取り込まないという
処理を組んでおくことが考えられます。後者の方が、部品代
にしても、定数の調整にしても、後々楽になるかと思います。


12F629や675は、持ってるんですが、めったに使わないので、
内部のことがあまりよく解ってません。特にタイマー割込み
関係とか。

ザックリ、データシートのタイマー周りを見てみたんですが、
CCP機能がなさそうですね。
タイマー関係の割り込みは、オーバーフロー割り込みしか
使えなさそうなので、正確に1/1000秒とかで割り込みかける
ためには、オーバーフロー割り込み発生時に、タイマカウンタ
の値を補正する必要がありそうです。
(その場合、プリスケーラを大きめにしておかないと、
 処理落ちが生じて、計測がズレる恐れがあるかと)

12F683だと、CCP内蔵なので、もうちょっとプログラムが楽
出来るんですけどね。


こんな感じで、要件は足りますかね?
 

もう一つおしえてください。

 投稿者:初心者  投稿日:2014年11月 7日(金)17時13分33秒
返信・引用
  TCXOの件はひとまずおいといて(なんと、奇跡的に京セラの18S-03A-4をまとめてゲットできました)
今度は12F629についてお知恵をお借りできればと思いまして。
ストップウォッチのゲート回路に使うつもりですが、入出力2回路を1個のPICに入れています。以前は疑似割り込み回路を使っていたのですが、最近USBロジアナを安価(500円!)で手に入れて調べてみたら結構反応時間にばらつきがあります。
で、何とか割り込みをつかって動くようにしたのですが、チャタリング防止のため遅延を入れると片側が反応している間、もう一方の反応がブロックされます。
当たり前といえば当たり前ですが、なんとか並行して動くようにできないのでしょうか。
長いですがコードを書いてみます。

; PIC12F629
; clock:INTOSCIO 4MHz
;   GP0⑦ → GP5②
;   GP1⑥ → GP2⑤
;   GP3④ → ディレイ
;ボタン押すと変化
LIST P=12F629
INCLUDE P12F629.INC

__CONFIG _CPD_ON & _CP_ON & _BODEN_ON & _PWRTE_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF


save_st EQU 020h ; STATUSのセーブ領域
save_w EQU 021h ; W-regのセーブ領域
CNT1    EQU     022H
CNT2    EQU     023H
W_TEMP  EQU     024H
STATUS_TEMP EQU 025H
CNT3    EQU     026H
CNT4    EQU     027H
DELAY1  EQU     028H
DELAY2  EQU     029H
GP0FLG  EQU   030H
ICNT    EQU   031H
icnt EQU 033h ; ピン変化割り込みカウンタ
GP1FLG  EQU   034H
CNT5    EQU   035H
CNT6    EQU   036H

; ==============================================================
ORG 0
GOTO INIT
; ==============================================================
ORG 4
; 割込み処理(ピン変化割り込み)
WARIKOMI_START
MOVWF save_w ;W-regセーブ
SWAPF STATUS,W
MOVWF save_st ;STATUSレジスタセーブ
BCF INTCON,GPIF ;ピン変化割込みフラグクリア

WARIKOMI_GP0
BTFSC GPIO,0 ;0→1の変化のみ拾う
BSF GP0FLG,0 ;ピン変化割り込みフラグON
    BTFSC  GP0FLG,0
    GOTO  WARIKOMI_GP1
    BSF   GPIO,5

WARIKOMI_GP1
BTFSC GPIO,1 ;0→1の変化のみ拾う
BSF GP1FLG,0 ;ピン変化割り込みフラグON
    BTFSC  GP1FLG,0
    GOTO  WARIKOMI_END
    BSF   GPIO,2

WARIKOMI_END
SWAPF save_st,W
MOVWF STATUS ;STATUSレジスタロード
SWAPF save_w,F
SWAPF save_w,W ;W-regロード
RETFIE ;割込み許可リターン

; ==============================================================
; PICの初期化
INIT
    ; GPIOをデジタルI/Oに設定
CLRF GPIO
MOVLW 07h
MOVWF CMCON
BSF STATUS,RP0 ;■バンク1に切替え

    CALL 3FFh ;OSCCAL Valueの読み込み(12C509Aと異なり自動的に読みに行ってくれない)
    MOVWF OSCCAL ;読み込んだ校正値をOSCCALレジスタにセット

MOVLW  B'00011011'   ;0と1と3と4を入力にする
MOVWF TRISIO
    MOVLW b'00000000' ;bit7=0内部プルアップEnable。出力時にプルアップは無効となる
    MOVWF OPTION_REG
    ; ピン変化割り込み設定
MOVLW B'00010011'   ;0と1と4を割り込み可能にする
MOVWF IOC ; GP0:ピン変化割り込み有効
BCF STATUS,RP0 ;■バンク0に切替え
MOVLW 088h ; GIE,GPIE on
MOVWF INTCON
CLRF GP0FLG
CLRF icnt
; ==============================================================
;    メイン処理

MAIN
BTFSS GP0FLG,0 ;ピン変化割り込み発生?
    GOTO   ACT_GP1 ; No
    CALL     TIME_1mSEC
    BTFSC    GPIO,3
    CALL  SET1
    BCF      GPIO,5
  BCF GP0FLG,0 ;ピン変化割り込みフラグクリア

ACT_GP1
BTFSS GP1FLG,0 ;ピン変化割り込み発生?
    GOTO   MAIN ; No
    CALL     TIME_1mSEC
    BTFSC    GPIO,3
    CALL  SET2
    BCF      GPIO,2
BCF GP1FLG,0 ;ピン変化割り込みフラグクリア
GOTO MAIN
SET1
    CALL     TIME_250mSEC
    RETURN

SET2
    CALL     TIME_250mSEC
    RETURN
;********************************************************
TIME_250mSEC
        MOVLW   0FAH      ;250
        MOVWF   CNT1      ;書き込み
DLP1;1mS
        MOVLW   0FAH      ;250をCNT2に書き込み
        MOVWF   CNT2      ;

DLP2
        NOP
        DECFSZ  CNT2,F
        GOTO    DLP2      ;CNT2がゼロになるまで繰り返す
        DECFSZ  CNT1,F    ;CNT1がゼロになったらDLP1へ
        GOTO    DLP1

        RETURN

TIME_10mSEC
        MOVLW   014H      ;20
        MOVWF   CNT3      ;書き込み
DLP1A
        MOVLW   0FAH      ;250をCNT2に書き込み
        MOVWF   CNT4      ;

DLP2A
        NOP
        DECFSZ  CNT4,F
        GOTO    DLP2A     ;CNT2Aがゼロになるまで繰り返す
        DECFSZ  CNT3,F    ;CNT1AがゼロになったらDLP1へ
        GOTO    DLP1A

        RETURN

TIME_1mSEC
        MOVLW   002H      ;20
        MOVWF   CNT5      ;書き込み
DLP1B
        MOVLW   0FAH      ;250をCNT2に書き込み
        MOVWF   CNT6      ;

DLP2B
        NOP
        DECFSZ  CNT6,F
        GOTO    DLP2B     ;CNT2Aがゼロになるまで繰り返す
        DECFSZ  CNT5,F    ;CNT1AがゼロになったらDLP1へ
        GOTO    DLP1B

        RETURN

  END

MAINの中でGPIO3を使って遅延をかけているわけですが、遅延中にもう一方に信号が入っても直ちに反応するようにしたいのです。(遅延が思い切り長いのは、光電センサーを使うため)

お知恵をお借りできれば幸いです。
 

Re: コンフィグです。

 投稿者:nekosan  投稿日:2014年10月21日(火)01時14分40秒
返信・引用
  > No.646[元記事へ]

初心者さんへのお返事です。

> お返事ありがとうございます。
> 英語は苦手なんですが、斜め読みした感じでは、おっしゃる通りHSでは使えないようです。
> RAについては、入力ビットなんでそのまま行けると思うんですが反応しません。
> まだ罠があるのか、たんにビット指定を間違えただけなのか・・・。
>



RAのほかのポートが正常に動いているのであれば、
多分TRISレジスタ周りもちゃんと設定できている
と思ってよいですよね。

とすると、やっぱり、同じ端子に重畳している
別の機能で、SFRの設定をなにか他の設定に切り替え
するように上書きされているとか、ですかねぇ?
 

続きです。

 投稿者:初心者  投稿日:2014年10月19日(日)22時17分4秒
返信・引用
  ハードはそこそこ?やるんですけどソフトは苦手です。
参考書のソフトいじったりしてますが、基礎がないんで頭痛いです。
 

レンタル掲示板
/79