
タイマーVで主にTV.TCRV0.BIT.CKS, TV.TCRV1.BIT.ICKS,TV.TCORAで設定すると思うのですが任意の周期になりません。
特に~~~に入る文がタイマーVによって設定した割り込み周期ごとに処理するように作成したのですが,うまくいきません。使用しているマイコンはH8の3694です。
作成したプログラムは以下の通りです。お気付きの点がございましたらご教授お願いいたします。
#include <3694.h> // H8 Tinyの内部I/O定義
#include <stdio.h>
#define TCNT 400 // TCNT = 20MHz / (PWM周期=50kHz)
#define Ref 240
#define pai 3.141519
unsigned int AdcResult1; // 出力電圧のAD変換出力の16bit変数
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 = 001; // AN0-1
//タイマV設定
TV.TCRV0.BIT.CCLR = 1; // コンペアマッチAでTCNクリア
TV.TCRV0.BIT.CKS = 3; //20GHz/128=15.6KHz
TV.TCRV1.BIT.ICKS =1; //
TV.TCRV0.BIT.CMIEA = 1; // タイマVのコンペアAによる割り込み許可
TV.TCNTV = 0; // タイマカウンタクリア
TV.TCORA =156 - 1; // タイムコンスタントレジスタA設定 15.6kHz / 156= 1kHz
// タイマ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でカウント
}
void int_ad (void)
{
~~~
}
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); // 割込み待ち
}
No.9ベストアンサー
- 回答日時:
こんにちは。
PWMの動作につきましては、近いですが違います。
キャリアとコンペア(と呼んでいるのですね)が直接比較されるわけではありません。
が、PWMの話はスレ違いなので置いておきまして。
本題の、なぜ1KHzにならないかについては、申し訳ないですが正直わかりません。
設定値を見る限り、正しいように思います。
PWMで確認するのがまずい、と書きましたが、それが1250Hzになる理由かどうかはわかりません。
I/Oにしても直らなかった場合、私が考え付く可能性としては、
・設定抜け(データシートの読み落とし)
・挙げられているソース部分以外で何かしている
・ハードウェアが変(25MHzのクリスタルが付いている?)
・その他、初歩的ミスの見落とし
といったところでしょうか。
長々と引っ張ったのにすみません。
I/Oにしてみて、何かわかったら補足なりに挙げていただければ幸いです。。。
No.8
- 回答日時:
こんにちは。
逆にお聞きしたいのですが、PWMを使った現在のプログラムで、なぜ出力が変化するのか、理解されていますか?
周波数を確認する方法としては、全く適さないと思いますが・・・。
I/Oポートの操作は、PWM出力よりはるかに基礎的な事ですので、データシートを調べて、頑張ってみてください。
あと、前の方に書きました、「25MHzでブン回す」とは、プログラムは20MHzのクロックを想定して書かれていますが、実際には25MHzの水晶発振子が基板に実装されていたりしませんか?という事です。
まさかそんな事はないと思いますが、もしそうなら、プログラムの設定で1250Hzになるのも合点がいくのです。
念のためハード担当者にご確認されてみてはいかがでしょうか。
また、万一そうだとすると、オーバークロックってことでもありますし。
ありがとうございます。
TCNT 400でタイマーwのキャリアの周期を決定しています。400がキャリアのピーク値です。
割り込みが入るごとにcountを1つずつ増やし,コンペア値を0か400しています。
そしてコンペア値とキャリアを比較させてパルスを生成しています。この際0か400にしているのでキャリアの周期に依存せずに割り込み周期毎にHi,Lowが出力すると考えて作成しました。
I/Oポートの操作,また基本的なことから勉強してみます。
No.6
- 回答日時:
こんにちは。
ありがとうございます。
1250Hz、つまり1.25KHzという事ですね?
まず考えられるのは、ひょっとして25MHzのクロックでブン回していませんか?
という事ですが。。。
ただ、先の補足にありましたが、タイマの設定を変えても周期が変化しなかった、というのがすごく引っかかります。普通に考えて、絶対変化するはずです。
ここはひとつ、『~~~』の部分もドドンと公開してもらえませんか?
もちろん、本番用ではなく、現在確認用にポート出力している分です。
できればノーカットで、int_timerv()とかmain()とかもそのままつけてもらえるとありがたいです。
ありがとうございます。
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); // 割込み待ち
}
No.5
- 回答日時:
こんにちは。
えー何度もすみません。
状況は何となくわかってきました。
それで、現状の周期は、1KHzにならず、何Hzになっているのでしょうか?
TV.TCRV0.BIT.CKS = 3;
TV.TCRV1.BIT.ICKS = 1 ;
TV.TCORA =156-1
の設定で1250Hzになっています。
No.4
- 回答日時:
こんにちは。
ちょっとやりたい事と問題点を整理させてもらいたいのですが、
やりたい事は、次のような感じでしょうか。
・1msごとにADコンバータを起動し、AD変換を行い、結果を取得。
・現在はデバッグのため、チャネルAのみリードし、取得した値は捨てている。
これで正しいですか?
次に、問題点は、どっちですか?
1) ADコンバータ自体が動いていない
2) AD変換は行われるが、周期が期待通りでない。
1だとすると、挙げられたソース以外の部分が重要です。
2だとすると、どのくらいずれているのかという事が問題です。
計算上、タイマの周期は1001.6Hzとなりますが、まさかこれの事では、ないですよね・・・?
そもそも、「任意の周期にならない」というのは、どうやって確認されているのでしょうか?
回答ありがとうございます。
問題は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は、明示的に割り込みベクトルに設定するようなことをしていませんが、名前が決められている関数とか、これは処理系がやってくれるとかいうことでいいんですかね?
細かな説明ありがとうございます。
コードは先輩のプログラム参考にして自分で作成したものです。
何分初心者なものですみません。
指摘して頂いたint_timerv(void)を重点的に
プログラムの流れ,関数を見直してみます。
No.2
- 回答日時:
こんにちは。
『~~~』の中に、ADSTをクリアするコードは含まれていますでしょうか。
スキャンモードでADコンバータを一度スタートさせると、ソフトでADSTをクリアしない限りAD変換を実行し続けるようですが。。。
回答ありがとうございます。
『~~~』の中に以下のコードを書いています。
AD.ADCSR.BIT.ADF = 0;// AD変換後割込みフラグクリア
AdcResult = AD.ADDRA;// AD変換出力レジスタ値をRAMにコピー
AdcResult = AdcResult >> 6;// 10bit結果を右に6bitシフトして16bit値に変換
でADコンバータを停止させて書き込んでいます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(AV機器・カメラ) オーディオインターフェイスの24bitなど量子化bit数はどこで設定できるのでしょうか? 1 2022/06/26 07:58
- Visual Basic(VBA) VBAでArrayListを使う為の「mscorlib.tlb」の参照設定について 3 2022/03/23 19:45
- Excel(エクセル) Excel 2019 32-bit版を64-bit版にするには? 8 2023/07/28 14:20
- その他(IT・Webサービス) hi-bitの契約について 1 2023/05/04 21:48
- TOEFL・TOEIC・英語検定 bitとlittleは両方ともに同じ 1 2022/08/10 13:03
- その他(Microsoft Office) 折れ線グラフ、同じ項目の色 4 2022/12/23 15:46
- その他(プログラミング・Web制作) Visual Studio Code 関数の使い方について 3 2023/05/31 13:15
- 英語 英文和訳についての質問です。 2 2023/06/23 06:38
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・【お題】甲子園での思い出の残し方
- ・【お題】動物のキャッチフレーズ
- ・人生で一番思い出に残ってる靴
- ・これ何て呼びますか Part2
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・あなたが好きな本屋さんを教えてください
- ・かっこよく答えてください!!
- ・一回も披露したことのない豆知識
- ・ショボ短歌会
- ・いちばん失敗した人決定戦
- ・性格悪い人が優勝
- ・最速怪談選手権
- ・限定しりとり
- ・性格いい人が優勝
- ・これ何て呼びますか
- ・チョコミントアイス
- ・単二電池
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・泣きながら食べたご飯の思い出
- ・一番好きなみそ汁の具材は?
- ・人生で一番お金がなかったとき
- ・カラオケの鉄板ソング
- ・自分用のお土産
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
このレジの並び方は間違ってま...
-
スーパーのレジで並んでいたら...
-
組込みシステム多重割り込みプ...
-
タイマーが動作しません
-
sleep関数の原理について
-
H8マイコンでの割り込み(シリ...
-
マイコンの割り込みについて教...
-
一定間隔のタスク処理について
-
電車乗車時、並んでいるのに割...
-
アトメル社製ATtiny2313マイコ...
-
電車で待機列の割り込みについ...
-
C-Builder OnChangeをマスク
-
一定時間操作がなかったら、と...
-
デュアルCPUのパソコンでCPUを1...
-
irqbalance って
-
PICマイコンでエンコーダパルス...
-
Macターミナルで実行中のプログ...
-
バックグラウンドのプロセスの...
-
C# シリアル通信でデータ受信...
-
家電製品の電力周波数を変える機械
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
電車で待機列の割り込みについ...
-
CPUの処理量を減らすコーデ...
-
スーパーのレジで並んでいたら...
-
このレジの並び方は間違ってま...
-
PICマイコンでエンコーダパルス...
-
USJでの割り込み
-
【組込み】割り込み中のstatic...
-
CPU負荷率の安全な上限と計...
-
pic 複数の割り込み関数 切り分...
-
Amazonfireタブレットにわから...
-
VB.net 割り込みの禁止
-
マイコン C言語 割り込み処理...
-
irqbalance って
-
マイコンのメインルーチン内でw...
-
一定時間操作がなかったら、と...
-
USB機器からのデータ受信による...
-
VB6でSendKeyを利用したTab移動...
-
(定周期タイマ割込み後ポーリン...
-
割り込み処理について
-
SH2のタイマ出力
おすすめ情報