32kHzの水晶振動子を用いて
1. ADC (1秒間に数十回の計測)
2. 1秒ごとの処理用のタイマーイベント
を同時に行いたいと考えています。
ADC10_VECTORとTIMER0_A0_VECTORがそれぞれことなる周波数で
動くようにTA0CCR1を1にしてADC10DIV_7としているのですが、
どうも両者は同じ周波数になっている模様です。(g_cntADCとg_cntTimer
が同じ増加率です。)
一つのクロックソースを2つの異なる周波数で用いるのはできないのでしょうか?
以下がテストしているプログラムです。
-------------------------
#include <msp430.h>
int g_cntTimer, g_cntADC;
int main( void ){ WDTCTL = WDTPW + WDTHOLD;
g_cntTimer = 0; g_cntADC = 0; ADC10CTL1 = SHS_1 + CONSEQ_2 + ADC10SSEL_1 + ADC10DIV_7; ADC10CTL0 = SREF_1 + ADC10SHT_1 + REFON + ADC10ON + ADC10IE; for(volatile int i0=0;i0<10000;i0++); // delay to allow Ref to settle ADC10CTL0 |= ENC; // ADC10 Enable ADC10AE0 |= 0x01; // P2.0 ADC10 option select
//--- ADC用クロック設定 TA0CCTL0 &= ~CCIE; // Disable timer Interrupt TA0CCR0 = 32767; // PWM Period TA0CCTL1 = OUTMOD_3; // TACCR1 set/reset TA0CCR1 = 1; // TACCR1 PWM Duty Cycle TA0CTL = TASSEL_1 + MC_1; // ACLK, up mode
TA0CCTL0 = CCIE; // TA0CCR0 interrupt enabled
__bis_SR_register(LPM3_bits + GIE);
}
#pragma vector=ADC10_VECTOR__interrupt void ADC10_ISR(void){ g_cntADC++;
#pragma vector=TIMER0_A0_VECTOR__interrupt void Timer_A (void){ g_cntTimer++;}
OKYさん、今晩は。
結論は「出来ます」です。
でも、ADC10DIV_7は変換の速度を制御するレジスタなので、サンプルの速度には影響しません。そのため、このプログラムでは一回のタイマ割り込みで一回のADを行います。ですから、割り込み回数はADと同じ回数になります。
CCR0はそのままで、CCR1の割り込みを利用して、コンペアモードを使いながら、
TA0CCR1 += 4096;
としながら制御をすれば、タイマカウントの8倍の速度でサンプリングができますよ。
タイマの使い方は結構複雑なので、よりご研究を。行き詰ったらまたお問い合わせください。
Massaさん
回答ありがとうございました。
ADC10DIV_7は分周するレジスタだと思っていたのですが、違うのでしょうか? ADC側での分周を行い、
タイマー処理と異なる周波数での処理を検討していました。
TA0CCR1 += 4096;に関してまだ理解不足ですが、サンプルを作ってテストしてみようと思います。
>タイマの使い方は結構複雑なので、よりご研究を。行き詰ったらまたお問い合わせください。
ありがとうございます。
OKYさん
ADC10DIV_7で制御されるクロックは、SAR型ADCの変換クロックを制御するもので、サンプル間隔とは関係がありません。データがホールドされAD変換が始まってから終わるまでの時間の長さを制御するものです。
お示しのサンプル間隔はTA1で制御され、タイマの周期が1秒なのでサンプリングは1秒になります。
そこでコンペアレジスタを利用して、4096カウントアップするたびにTA1を変更してやれば、32768÷4086=8で、一秒に8回、CCR1のインクリメントを2048にすれば16回サンプルさせることが出来ます。
是非サンプルを作って実験されることをお勧めします。なお、コンペア割り込みフラグは、ソフトでクリアする必要がありますのでご注意を。
詳細な説明ありがとうございます。
実際にサンプルを作って、タイマー処理の理解を深めようと思います。
ありがとうございました。
その後、CCR0とCCR1での異なる周期での処理用サンプルプログラムを作成してみまして、おかげさまで、異なる周期の設定
方法については多少理解が深まりました。
ただ、F2112用のドキュメント(slau144e.pdf page 404)を見ていますと、ADC10をトリガーするTimer_A Output Unit1は
CCR1のカウント値でセットされ、CCR0でリセットされるようです。
この場合、CCR0でリセットされるまではTimer_A Output Unit1はセットされたままの状態で、結局ADC10がトリガー
されるのはCCR0で一度リセットされた後、つまり、CCR0の周期となってしまうような気がします。
ADC10 ISRでCCR1 += 2048のようにするのに加えて、Timer_A Output Unit1をリセットするような処理が
必要なのでしょうか? その場合、Timer_A Output Unit1をリセットするにはどのレジスタを変更することになるのでしょうか?
OKYさん、こんにちは。
一週間あわただしくてレスできませんでした。相変わらず誰も答えてくれないですね(涙)。
ご指摘のとおり、セット/リセットモードでは割り込みがかかるたびにADすることはできません。ADは出力ユニット1の出力の立ち上がりで開始されるからです。
そのため、少々トリッキーなコードを書いて、OUTMOD1をいじる必要があります。しかし、そういったタイマの使い方は余りメリットがありません。でも、トライしてみてください。
一般的な方法は変換開始を、TA1出力ではなく、出力ユニット1のコンペア割り込みISRでADC10SCビットをたたいてソフト的に開始する方法で、少ないステップ数で変換が可能です。これなら、複数周期を扱えれば、すぐにできるでしょう。
試してみてください。
Massa様
再度の回答ありがとうございます。
>一般的な方法は変換開始を、TA1出力ではなく、出力ユニット1のコンペア割り込みISRでADC10SCビットをたたいてソフト的に開始する方法で、少ないステップ数で変換が可能です。これなら、複数周期を扱えれば、すぐにできるでしょう。
こちらの方法を試してみようと思います。
本サイトの全てのコンテンツ及び素材は、「現状有姿のまま」提供されております。 日本テキサス・インスツルメンツ株式会社及びその親会社であるTexas Instruments Incorporated (以下、TIと総称します)、並びにTIに当該コンテンツや素材を提供した者は、当該コンテンツ若しくは素材が何らかの目的に適合しているかどうかについて、いかなる表明もいたしませんし、また、当該コンテンツ若しくは素材について、当該コンテンツ若しくは素材に商品性があることの保証、特定の目的に適合していることの保証、TI若しくは当該提供者に何らかの権原が有ることの保証及び当該コンテンツ若しくは素材が第三者の知的財産権を侵害していないことの保証その他、黙示の保証であろうと明示の保証であろうと、いかなる保証も一切いたしません。 TI は、明示のライセンスであろうと、黙示のライセンスであろうと、禁反言によるライセンスであろうと、ライセンスは一切いたしません。 本サイト上にある情報を使用する場合は、別途、第三者もしくはTI から、ライセンスを取得しなければならない場合があります。 本サイト上にあるコンテンツには、特別な使用上の注意事項もしくは制限事項が含まれているか、又はそれらの注意事項もしくは制限事項に従う限りにおいて使用できる場合があります。 本サイト上の全ての投稿及びコンテンツの使用は、本サイトの「使用条件」に従ってなされるものとし、当該コンテンツを使用する第三者は本サイトの「使用条件」の制限、注意事項に拘束され、且つそれらに従わなければならないものとします。 TI 及びコンテンツ、素材等を提供した者は、いつでも、コンテンツ、素材、製品、プログラム及びサービスを訂正、削除、修正、増加、改良その他の変更をし、かつ、いかなるコンテンツ、製品、プログラム若しくはサービスも、通告無しに移動、中止する権利を留保します。