• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:H8マイコンで割り込みが任意の周期で設定できない)

H8マイコンで割り込みが任意の周期で設定できない

このQ&Aのポイント
  • H8マイコンで割り込みの任意の周期を設定する方法がわかりません。
  • タイマーVを使用して割り込み周期を設定しようとしましたが、うまくいきません。
  • H8の3694マイコンを使用しています。

質問者が選んだベストアンサー

  • ベストアンサー
  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.9

こんにちは。 PWMの動作につきましては、近いですが違います。 キャリアとコンペア(と呼んでいるのですね)が直接比較されるわけではありません。 が、PWMの話はスレ違いなので置いておきまして。 本題の、なぜ1KHzにならないかについては、申し訳ないですが正直わかりません。 設定値を見る限り、正しいように思います。 PWMで確認するのがまずい、と書きましたが、それが1250Hzになる理由かどうかはわかりません。 I/Oにしても直らなかった場合、私が考え付く可能性としては、 ・設定抜け(データシートの読み落とし) ・挙げられているソース部分以外で何かしている ・ハードウェアが変(25MHzのクリスタルが付いている?) ・その他、初歩的ミスの見落とし といったところでしょうか。 長々と引っ張ったのにすみません。 I/Oにしてみて、何かわかったら補足なりに挙げていただければ幸いです。。。

その他の回答 (8)

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.8

こんにちは。 逆にお聞きしたいのですが、PWMを使った現在のプログラムで、なぜ出力が変化するのか、理解されていますか? 周波数を確認する方法としては、全く適さないと思いますが・・・。 I/Oポートの操作は、PWM出力よりはるかに基礎的な事ですので、データシートを調べて、頑張ってみてください。 あと、前の方に書きました、「25MHzでブン回す」とは、プログラムは20MHzのクロックを想定して書かれていますが、実際には25MHzの水晶発振子が基板に実装されていたりしませんか?という事です。 まさかそんな事はないと思いますが、もしそうなら、プログラムの設定で1250Hzになるのも合点がいくのです。 念のためハード担当者にご確認されてみてはいかがでしょうか。 また、万一そうだとすると、オーバークロックってことでもありますし。

ash719
質問者

お礼

ありがとうございます。 TCNT 400でタイマーwのキャリアの周期を決定しています。400がキャリアのピーク値です。 割り込みが入るごとにcountを1つずつ増やし,コンペア値を0か400しています。 そしてコンペア値とキャリアを比較させてパルスを生成しています。この際0か400にしているのでキャリアの周期に依存せずに割り込み周期毎にHi,Lowが出力すると考えて作成しました。 I/Oポートの操作,また基本的なことから勉強してみます。

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.7

こんばんは。 ありがとうございます。 あまり深くは解析しておりませんが、確認の仕方に問題がある事は間違いなさそうです。 タイマーWのPWM出力ではなく、空いているポートを出力ポートにし、それをint_ad()内でパタパタさせるなどするように変更してみて下さい。 多分、タイマーv自体はちゃんと動いているんじゃないかなぁ、と思います。

ash719
質問者

お礼

ありがとうございます。 なぜダメなのか分りません... 今までPWM出力しか行っていない物で, 確認するプログラムも書いていただけたら幸いです。

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.6

こんにちは。 ありがとうございます。 1250Hz、つまり1.25KHzという事ですね? まず考えられるのは、ひょっとして25MHzのクロックでブン回していませんか? という事ですが。。。 ただ、先の補足にありましたが、タイマの設定を変えても周期が変化しなかった、というのがすごく引っかかります。普通に考えて、絶対変化するはずです。 ここはひとつ、『~~~』の部分もドドンと公開してもらえませんか? もちろん、本番用ではなく、現在確認用にポート出力している分です。 できればノーカットで、int_timerv()とかmain()とかもそのままつけてもらえるとありがたいです。

ash719
質問者

お礼

ありがとうございます。 25MHzのクロックでブン回すとはどうゆうことですか? ざっとこんな感じです。根本的に間違っているかも知れませんがよろしくお願いします。 #include <3694.h> #include <stdio.h> #define TCNT 400 //(PWM周期=50kHz) unsigned int AdcResult1; // 出力電圧のAD変換出力の16bit変数 int Vc0, Vc1; // 制御信号 int count = 0; void InitH8(void) { // A/Dコンバータ設定 AD.ADCSR.BYTE = 0; // A/D変換停止 AD.ADCSR.BIT.ADIE = 1; // A/D変換割り込み許可 AD.ADCSR.BIT.SCAN =1; // スキャンモード AD.ADCSR.BIT.CKS = 1; // 高速変換 AD.ADCSR.BIT.CH = 0; // AN0-1 //タイマV設定 TV.TCRV0.BIT.CCLR = 0; // コンペアマッチAでTCNクリア TV.TCRV0.BIT.CKS = 3; TV.TCRV1.BIT.ICKS =1; // 上記CKS = 2 と併用 20MHz / 128 = 1.25MHz TV.TCRV0.BIT.CMIEA = 1; // タイマVのコンペアAによる割り込み許可 TV.TCNTV = 0; // タイマカウンタクリア TV.TCORA =156; // タイムコンスタントレジスタA設定 250 / 1.25MHz = 200us // タイマW 設定 TW.TMRW.BIT.CTS = 0; // TCNTカウント停止 TW.TCRW.BIT.CCLR = 1; // コンペアマッチAによりTCNTをクリア TW.TIOR0.BIT.IOB = 1; // コンペアマッチBによりFTIOB端子へ0出力 TW.TCRW.BIT.CKS = 0; // 内部クロックφ/1 = 20MHzでカウント TW.TMRW.BIT.PWMB = 1; // FTIOB端子の出力モード = PWM TW.TCRW.BIT.TOB =1; // 最初のコンペアマッチAが発生するまでの端子出力値 = Low // PWM周期決定 PWM1デューティ初期化 TW.GRA = TCNT - 1; // PWMの周期 20MHz / TCNT TW.GRB = 0; // PWM1出力設定 デューティー0% TW.TMRW.BIT.CTS = 1; // Wタイマ TCNTカウント開始 } void int_ad (void) { AD.ADCSR.BIT.ADST = 0; // AD変換停止 AdcResult1 = AD.ADDRA; // 出力電圧のAD変換出力レジスタ値をRAMにコピー AdcResult1 = AdcResult1 >> 6;// 10bit結果を右に6bitシフトして16bit値に変換 count++; if (count <= 1) Vc1 = 0; if (1< count && count <=2 ) Vc1 = 400; if (count >= 2)count =0; TW.GRB =Vc1; void int_timerv(void) { TV.TCSRV.BIT.CMFA = 0; // タイマV割込みフラグクリア AD.ADCSR.BIT.ADST = 1; // AD変換開始 } void main(void) { DI; InitH8(); // H8_3694設定 EI; while(1); // 割込み待ち }

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.5

こんにちは。 えー何度もすみません。 状況は何となくわかってきました。 それで、現状の周期は、1KHzにならず、何Hzになっているのでしょうか?

ash719
質問者

お礼

TV.TCRV0.BIT.CKS = 3; TV.TCRV1.BIT.ICKS = 1 ; TV.TCORA =156-1 の設定で1250Hzになっています。

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.4

こんにちは。 ちょっとやりたい事と問題点を整理させてもらいたいのですが、 やりたい事は、次のような感じでしょうか。 ・1msごとにADコンバータを起動し、AD変換を行い、結果を取得。 ・現在はデバッグのため、チャネルAのみリードし、取得した値は捨てている。 これで正しいですか? 次に、問題点は、どっちですか? 1) ADコンバータ自体が動いていない 2) AD変換は行われるが、周期が期待通りでない。 1だとすると、挙げられたソース以外の部分が重要です。 2だとすると、どのくらいずれているのかという事が問題です。 計算上、タイマの周期は1001.6Hzとなりますが、まさかこれの事では、ないですよね・・・? そもそも、「任意の周期にならない」というのは、どうやって確認されているのでしょうか?

ash719
質問者

お礼

回答ありがとうございます。 問題は2番の周期が期待通りでないです。AD変換はできています。 今の現状として TV.TCRV0.BIT.CKS =3; → TV.TCRV0.BIT.CKS =1 TV.TCRV1.BIT.ICKS =1; TV.TCORA =156; に変更しても変化がありません。また1msにもなりません。 確認のためAD変換は行わずに以下のことをしております。 ~~~の部分にカウントを設けて1回読み込んだらPWM出力をHiに,2回読み込んだらPWM出力をLowにしてパルス時間を見て確認しています。

回答No.3

ここに掲載されたコードは、自分で書いたものですか? 理解されていないのなら、よく調べることをお薦めします。 H8は使ったことがないので、完全に説明することはできませんが、一般にAD変換をするシステムは、次のようになっているはずです。 main()  CPU全体の割り込みを禁止する。  AD変換の設定をする。  割り込みの設定をする。(割り込みベクトルなどの設定)  CPU全体の割り込みを許可する。  AD変換をスタートする。  while(1)  表示など。 int_ad() //これは、割り込みベクトルか、そこから呼ばれる。  ADを読む。  mainで表示したりする為のAD値を橋渡しする。  AD変換を再スタート // 今回はスキャンモードなので、不要のはず。 掲載のコードでは、AD変換をスタートする処理が、int_timerv(void)に書かれていますが、 何処からも呼ばれていません。あと、int_adは、明示的に割り込みベクトルに設定するようなことをしていませんが、名前が決められている関数とか、これは処理系がやってくれるとかいうことでいいんですかね?

ash719
質問者

お礼

細かな説明ありがとうございます。 コードは先輩のプログラム参考にして自分で作成したものです。 何分初心者なものですみません。 指摘して頂いたint_timerv(void)を重点的に プログラムの流れ,関数を見直してみます。

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.2

こんにちは。 『~~~』の中に、ADSTをクリアするコードは含まれていますでしょうか。 スキャンモードでADコンバータを一度スタートさせると、ソフトでADSTをクリアしない限りAD変換を実行し続けるようですが。。。

ash719
質問者

お礼

回答ありがとうございます。 『~~~』の中に以下のコードを書いています。 AD.ADCSR.BIT.ADF = 0;// AD変換後割込みフラグクリア AdcResult = AD.ADDRA;// AD変換出力レジスタ値をRAMにコピー AdcResult = AdcResult >> 6;// 10bit結果を右に6bitシフトして16bit値に変換 でADコンバータを停止させて書き込んでいます。

回答No.1

int_timerv()が呼ばれてないのでは?

ash719
質問者

お礼

回答ありがとうございます。 int_timerv()が呼ばれてないとはどうゆうことですか? またどう設定せればいいのですか? すみません。

関連するQ&A