タイマー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); // 割込み待ち
}

このQ&Aに関連する最新のQ&A

A 回答 (9件)

こんにちは。


PWMの動作につきましては、近いですが違います。
キャリアとコンペア(と呼んでいるのですね)が直接比較されるわけではありません。
が、PWMの話はスレ違いなので置いておきまして。

本題の、なぜ1KHzにならないかについては、申し訳ないですが正直わかりません。
設定値を見る限り、正しいように思います。
PWMで確認するのがまずい、と書きましたが、それが1250Hzになる理由かどうかはわかりません。
I/Oにしても直らなかった場合、私が考え付く可能性としては、
・設定抜け(データシートの読み落とし)
・挙げられているソース部分以外で何かしている
・ハードウェアが変(25MHzのクリスタルが付いている?)
・その他、初歩的ミスの見落とし
といったところでしょうか。

長々と引っ張ったのにすみません。
I/Oにしてみて、何かわかったら補足なりに挙げていただければ幸いです。。。
    • good
    • 0

こんにちは。


逆にお聞きしたいのですが、PWMを使った現在のプログラムで、なぜ出力が変化するのか、理解されていますか?
周波数を確認する方法としては、全く適さないと思いますが・・・。
I/Oポートの操作は、PWM出力よりはるかに基礎的な事ですので、データシートを調べて、頑張ってみてください。

あと、前の方に書きました、「25MHzでブン回す」とは、プログラムは20MHzのクロックを想定して書かれていますが、実際には25MHzの水晶発振子が基板に実装されていたりしませんか?という事です。
まさかそんな事はないと思いますが、もしそうなら、プログラムの設定で1250Hzになるのも合点がいくのです。
念のためハード担当者にご確認されてみてはいかがでしょうか。
また、万一そうだとすると、オーバークロックってことでもありますし。
    • good
    • 0
この回答へのお礼

ありがとうございます。

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

I/Oポートの操作,また基本的なことから勉強してみます。

お礼日時:2011/04/22 13:24

こんばんは。


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

ありがとうございます。

なぜダメなのか分りません...

今までPWM出力しか行っていない物で,
確認するプログラムも書いていただけたら幸いです。

お礼日時:2011/04/22 11:14

こんにちは。


ありがとうございます。
1250Hz、つまり1.25KHzという事ですね?
まず考えられるのは、ひょっとして25MHzのクロックでブン回していませんか?
という事ですが。。。

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

ありがとうございます。
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); // 割込み待ち
}

お礼日時:2011/04/21 18:23

こんにちは。


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

TV.TCRV0.BIT.CKS = 3;
TV.TCRV1.BIT.ICKS = 1 ;
TV.TCORA =156-1

の設定で1250Hzになっています。

お礼日時:2011/04/21 17:13

こんにちは。


ちょっとやりたい事と問題点を整理させてもらいたいのですが、
やりたい事は、次のような感じでしょうか。
・1msごとにADコンバータを起動し、AD変換を行い、結果を取得。
・現在はデバッグのため、チャネルAのみリードし、取得した値は捨てている。

これで正しいですか?

次に、問題点は、どっちですか?
1) ADコンバータ自体が動いていない
2) AD変換は行われるが、周期が期待通りでない。

1だとすると、挙げられたソース以外の部分が重要です。
2だとすると、どのくらいずれているのかという事が問題です。
計算上、タイマの周期は1001.6Hzとなりますが、まさかこれの事では、ないですよね・・・?

そもそも、「任意の周期にならない」というのは、どうやって確認されているのでしょうか?
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
問題は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にしてパルス時間を見て確認しています。

お礼日時:2011/04/21 15:49

ここに掲載されたコードは、自分で書いたものですか?


理解されていないのなら、よく調べることをお薦めします。

H8は使ったことがないので、完全に説明することはできませんが、一般にAD変換をするシステムは、次のようになっているはずです。

main()
 CPU全体の割り込みを禁止する。
 AD変換の設定をする。
 割り込みの設定をする。(割り込みベクトルなどの設定)
 CPU全体の割り込みを許可する。
 AD変換をスタートする。
 while(1)
 表示など。


int_ad() //これは、割り込みベクトルか、そこから呼ばれる。
 ADを読む。
 mainで表示したりする為のAD値を橋渡しする。
 AD変換を再スタート // 今回はスキャンモードなので、不要のはず。


掲載のコードでは、AD変換をスタートする処理が、int_timerv(void)に書かれていますが、
何処からも呼ばれていません。あと、int_adは、明示的に割り込みベクトルに設定するようなことをしていませんが、名前が決められている関数とか、これは処理系がやってくれるとかいうことでいいんですかね?
    • good
    • 0
この回答へのお礼

細かな説明ありがとうございます。
コードは先輩のプログラム参考にして自分で作成したものです。
何分初心者なものですみません。

指摘して頂いたint_timerv(void)を重点的に
プログラムの流れ,関数を見直してみます。

お礼日時:2011/04/21 17:47

こんにちは。


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

回答ありがとうございます。
『~~~』の中に以下のコードを書いています。

AD.ADCSR.BIT.ADF = 0;// AD変換後割込みフラグクリア
AdcResult = AD.ADDRA;// AD変換出力レジスタ値をRAMにコピー
AdcResult = AdcResult >> 6;// 10bit結果を右に6bitシフトして16bit値に変換

でADコンバータを停止させて書き込んでいます。

お礼日時:2011/04/21 11:25

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

    • good
    • 0
この回答へのお礼

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

お礼日時:2011/04/21 10:57

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q何故、月の自転周期と公転周期は同じなのでしょうか?

月の自転周期が公転周期と同じなのは、偶然でしょうか、それとも、同じになる必然性があったのでしょうか?

また、他の惑星の月で、自転周期と公転周期が同じものはありますか?

Aベストアンサー

>えーっ! と驚きました。大変おもしろいので
>ちょっと確認させてください。以下のような理解
>で良いのでしょうか?
>月には、比重が他の部分より大きい部分が偏った位置に
>埋まっている。その部分が地球に引っ張られて
>そこで止まっている。すなわち比重の大きい部分が
>地球から見て一番近い位置になるように止まって
>いるということですか?

 正解です!えーと、今では、ラグビーボール変形モデルによる説明は、はっきり言って”天動説”みたいな過去のものです。

>月が変形するという説の場合は
>その変形位置は刻々変わるはずなので
>自転周期=公転周期でピタッと止まる理由が
>まだ、あまりぴんときません。

 そのとおりです、これは、実際の月の秤動です。
http://antwrp.gsfc.nasa.gov/apod/ap991108.html
 軌道が楕円だし、太陽にも影響されるが、一定の所が正面に戻っています。変形モデルではこれが説明できない。なぜなら、地球起潮力が、月の相を一定の面に保つシステムを、自動制御系とみなせば、起潮力によって円が楕円に変形するモデルは無定位系だからです。外乱による位相変化は累積されるだけで、復元力は無い。これは、昔からわかっていた変形モデルの欠陥です。月も山や海があって多少はデコボコだけど、地球を向いてるのは山じゃなく海だし。その海にマスコンが発見されて、全面解決しました。

 アポロの探査でマスコンが発見されて以来、長年の精密測定の結果、起潮力によるかすかな変形より、マスコンという質量分布の片寄りの方が、決定的に大きかった。これが観測事実です。


 しかし変形説だけを信じる人が多いので、僕は驚いています。
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1020594
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1096679
誤りは二重です。
マスコンが支配的である事実を受け入れないことと、
変形によるこね回しでエネルギーを吸収して、月の自転にブレーキをかけているのは、月ではなく、柔らかい地球の方であることが理解されてない。月は固い棒で、地球は柔らかなモチです。

>えーっ! と驚きました。大変おもしろいので
>ちょっと確認させてください。以下のような理解
>で良いのでしょうか?
>月には、比重が他の部分より大きい部分が偏った位置に
>埋まっている。その部分が地球に引っ張られて
>そこで止まっている。すなわち比重の大きい部分が
>地球から見て一番近い位置になるように止まって
>いるということですか?

 正解です!えーと、今では、ラグビーボール変形モデルによる説明は、はっきり言って”天動説”みたいな過去のものです。

>月が変形するという説の場...続きを読む

Qアトメル社製ATtiny2313マイコンのINT0端子、INT1端子の割り込みに優先順位は設定できる?

ATtiny2313で割り込み端子入力2つを使用してINT0が入力されたら赤LEDを点灯させて、INT1端子が入力されたら黄LEDを点灯させて、どちらの入力もなかったらパワーダウンモードでマイコンの消費電流を最小限まで落とすというプログラムを作って動作させています。

だいたい割り込みのプログラムはできたのですが、INT0とINT1端子がどちらとも入力されていた場合INT0を優先して、割り込み1ベクタルーチンに飛ぶようにしたいのですが、今のプログラムは先に入った方の入力が優先されるようで、後から入ってきた割り込み端子入力は全く無視するようなプログラムになっているようです。

ATtiny2313のデータシートでINT0端子に優先的な割り込み許可を与えるレジスタ設定などがあるのかなと探しているのですが、よくわからない状態です。

現在のプログラムの動きを試験しているテスト基板の画像をyoutubeで動画にして投稿しました。

どなたかご存知のかたいらっしゃいましたらご教授よろしくお願い致します。

http://www.youtube.com/watch?v=HM6OfK_xbJQ

ATtiny2313で割り込み端子入力2つを使用してINT0が入力されたら赤LEDを点灯させて、INT1端子が入力されたら黄LEDを点灯させて、どちらの入力もなかったらパワーダウンモードでマイコンの消費電流を最小限まで落とすというプログラムを作って動作させています。

だいたい割り込みのプログラムはできたのですが、INT0とINT1端子がどちらとも入力されていた場合INT0を優先して、割り込み1ベクタルーチンに飛ぶようにしたいのですが、今のプログラムは先に入った方の入力が優先されるようで、後から入ってきた割り...続きを読む

Aベストアンサー

えぇと、読み直したら質問の回答になっていないようで…;

まず、割り込みの条件は何でしょう。
目的からすると論理変化ですよね?

プログラムの内容としては…

・メイン
 スリープ無限ループ

・INT0処理
 INT0=Loなら赤ON
 INT0=Hiなら赤OFF

・INT1処理
 INT1=Loなら黄ON
 INT1=Hiなら黄OFF

というプログラムであれば、変化時にLEDが変わると思うんですが。

ちなみに、割り込み処理中に割り込みが発生しても割り込みは保留されるので、割り込み処理から抜けていなければ他の割り込みの処理は出来ません。

Q【速報】地球オワタ超惑星接近 地球の4倍木星レベル

【速報】地球オワタ 超惑星ニビル(別名:プラネットX)が地球に接近 大きさは地球の4倍 木星レベル゛

■惑星二ビルは太陽系の惑星で超長楕円軌道で太陽の周りを回っている。別名:プラネットX(Xは数字の10番目の意味)という。

NASAが惑星ニビルを発見しアメリカのワシントンポスト紙が「地球衛星軌道を周回中のIRASがオリオン座の方角に巨大な天体を発見」と報じた。

さらに、NASAが惑星Xとして冥王星の彼方に惑星がある可能性を公表、この惑星は冥王星の彼方にある事から超冥王星と更に進み、天王星と海王星の軌道に揺らぎを認め冥王星に惑星X(10番目)の存在が明らかに。惑星Xは木星と同じ位の大きさで1000年以上の公転周期が確認された。

惑星ニビルは3600年周期で太陽系に交差する。シュメール語でニビルは交差するを意味だ。

NIBIRU Facts of Truth
Posted on July 28, 2011 by the truth behind the scenes| 74 Comments

http://thetruthbehindthescenes.wordpress.com/2011/07/28/nibiru-facts-of-truth/

NASA 2012 PLANET X SIMULATION LEAKED - MUST SEE!
http://www.youtube.com/watch?v=xpPP9Z9LOBU&

ちょっとこのNASAの動画2012年にとんでもないことになってるけど本当にこうなるシミュレーション結果なの?
2012年に惑星ニビルによって地球は滅亡するのかな?皆はどう思う?

http://www.youtube.com/watch?v=xpPP9Z9LOBU&

【速報】地球オワタ 超惑星ニビル(別名:プラネットX)が地球に接近 大きさは地球の4倍 木星レベル゛

■惑星二ビルは太陽系の惑星で超長楕円軌道で太陽の周りを回っている。別名:プラネットX(Xは数字の10番目の意味)という。

NASAが惑星ニビルを発見しアメリカのワシントンポスト紙が「地球衛星軌道を周回中のIRASがオリオン座の方角に巨大な天体を発見」と報じた。

さらに、NASAが惑星Xとして冥王星の彼方に惑星がある可能性を公表、この惑星は冥王星の彼方にある事から超冥王星と更に進み、天王星と海...続きを読む

Aベストアンサー

スピリチュアル系の人たちが数年前から流してる有名なデマです。
シュメール人が3600年周期の記録をもつはずがありません。今から3600年前、シュメール人はすでに古バビロニア王朝に滅ぼされていました。そのバビロニア王朝もヒッタイト帝国に攻められていました。そのためシュメール人が3600年前の記録を残せるはずがありません。

その前の周期、7200年前はシュメール人はまだ文字を持っていません。シュメール人が楔形文字を使いはじめるのは5500年前くらいからです。

だからシュメール人は3600年周期の天体を観察し記録することは不可能です。

生物史、天文学、考古学、どの分野からみても明らかなデマ、またはジョークですね。

QSolaris10 スレッドでのタイマー割り込みについて

さっき載せたつもりがどこかに消えてしまっているようなのでまた書かせていただきます。

Solarisでスレッドごとのアラームのサポート中止が出ており、スレッドでsocket通信中のreadでタイマーを張りたいのですが、どうすればいいのでしょうか。
これまでsetitimer()を使ってきました。
http://docs.sun.com/app/docs/doc/819-0390/6n2qp46er?l=ja&a=view

要件はSolaris10,スレッド,C言語,socket-readでの3秒でのタイムアウト実現。

Solaris/POSIXスレッドを使っている方はこのような場合どうしていらっしゃいますか?
どう解決されたかお教えいただければと思います。
自分でタイマースレッドを作るしかないのでしょうか。

Aベストアンサー

Solaris8で、スレッドは使用していないのですが、
read()する前に、
select()で、I/Oの同期を確認し、
ここでタイムアウトを取得するように処理していました。

Q惑星の見かけの逆行運動と赤経の差について

惑星の見かけの逆行運動と赤経の差について
内惑星の公転周期は一年より短いので、一ヶ月間の赤経の差は2hより大きくなる。外惑星のは2hより小さくなる。

これについてなんですが、実際に模式図を書いてみたら、たしかに、赤経の差の合計は内惑星だと24hより大きくなって、外惑星だと24h未満になりました。
…でも、なんでこうなるのか、不思議です。内惑星の位置を一年見ていたら、一周より大きくなるのは、なんか不思議です(ㆆ_ㆆ)?このままでは納得できません。
数式とかなんでもいいんで、理由を教えてください。

Aベストアンサー

>一ヶ月間の赤経の差は2hより大きくなる。
逆行している前後はそうでもないですね。
以下は金星の2年間の視位置ですが、「*」の部分が
1ヶ月の差分は2h以下です。

  *** 金星の視位置 ***
        赤経    赤緯     距離
2010/01/01  18:34:20  -23:38:31   1.708
2010/02/01  21:18:49  -17:03:33   1.705
2010/03/01  23:32:21  -04:29:15   1.668
2010/04/01  01:53:40   11:06:32   1.587
2010/05/01  04:20:16   22:17:00   1.462
2010/06/01  07:02:47   24:31:48   1.286
2010/07/01  09:29:02   16:45:12   1.077
2010/08/01  11:36:32   02:40:48   0.837
2010/09/01  13:23:26  -12:03:02   0.590 *
2010/10/01  14:30:31  -21:45:38   0.375 *
2010/11/01  13:58:11  -17:48:28   0.272 *
2010/12/01  13:54:57  -10:25:51   0.394 *
2011/01/01  15:28:19  -15:16:29   0.616 *
2011/02/01  17:44:20  -20:43:35   0.851
2011/03/01  20:02:29  -19:32:07   1.054
2011/04/01  22:31:11  -10:14:39   1.259
2011/05/01  00:46:23   03:10:57   1.433
2011/06/01  03:09:50   16:21:33   1.579
2011/07/01  05:43:07   23:09:28   1.677
2011/08/01  08:26:55   20:07:15   1.727
2011/09/01  10:57:38   08:10:51   1.721
2011/10/01  13:14:24  -06:51:14   1.669
2011/11/01  15:43:59  -20:02:01   1.574
2011/12/01  18:24:29  -24:44:55   1.450

巡行の場合に1ヶ月の差が2h以上になるのは、単純に
内惑星の公転周期が地球の公転周期より短いためということ
では納得いかないでしょか・・?

http://www.s-yamaga.jp/nanimono/uchu/wakusei-01.htm

>一ヶ月間の赤経の差は2hより大きくなる。
逆行している前後はそうでもないですね。
以下は金星の2年間の視位置ですが、「*」の部分が
1ヶ月の差分は2h以下です。

  *** 金星の視位置 ***
        赤経    赤緯     距離
2010/01/01  18:34:20  -23:38:31   1.708
2010/02/01  21:18:49  -17:03:33   1.705
2010/03/01  23:32:21  -04:29:15   1.668
2010/04/01  01:53:40   11:06:32   1.587
2010/05/01  04:20:16   22:17:00   1.462
2010/06/...続きを読む

Qマイコン C言語 割り込み処理で変数参照

マイコンのC言語で1つ困っています。

メイン処理である条件でグローバル変数Aを設定しています。

また、割り込み処理をタイマーとして使い、グローバル変数Aを参照しています。

このような動作の時に割り込み処理でグローバル変数Aを参照した際にエラーで動作しなくなります。

おそらく、同じデータをメイン処理での設定と割り込み処理での参照を行ったせいだと思いますが、

何かPICプログラミングとして最適な対処法はありますか?

是非、ご教授お願いします。

Aベストアンサー

まず、エラーが出たなら、どういうエラーなのかを明確に記載して下さい。
それから、セマフォ・mutexという言葉が出てきていますが、
割り込みハンドラ中で、待ちが発生する処理を記載してはいけません。
可能な限り短く処理を終わらせなければなりません。

割り込みは、高い優先度をもって実行されていますから、待ち状態を作ってしまうような処理を
書いてしまうと、他の割り込み制御に影響を及ぼしたり、待ち状態解除を行う側のタスクが
動作できなくて、デッドロックすることがあります。

割り込みハンドラの中で、printfでログを出力することなども、禁止です。
printfの中には、ストリームバッファの排他制御があるので、待ち状態になる可能性が
あるためです。

基本的には、割り込みハンドラ内では、最短で処理を終わらせるために、
フラグをONするような処理しかしてはいけません。
そして、メインスレッドでフラグがONなら処理をするような形とします。

Q公転周期と現在位置から未来位置を割り出す式について

 惑星の位置と公転周期が分かっている場合、未来位置はどうやって算出すればいいのでしょうか?
 お願いします。

Aベストアンサー

 「未来位置」とはどのようなことを言っているのでしょう?地球からどの方角に見えるのか、ということでしょうか。

 単純に円軌道状を動く惑星として図形的に考えるのなら、次のようなことですが。
 公転周期がT年とすると、 n年後の位置は、現在位置から
 360°×n/T
 だけ回転したところ。

QH8マイコンでの割り込み(シリアルポート入力で)

マイコン:AKI H8/3048F
開発環境:GCC Developer Lite
マイコンとパソコンをRS-232Cケーブルでつないでいます。

ハイパーターミナルを使用して、マイコンを制御したいと考えております。
それで、パソコンのキーボードから入力があった時だけ、割り込みを実行したいです。
割り込みが無い場合は、パソコンでマイコンを制御することができたのですが、割り込みを追加したら、うまくいかなくなりました。

アセンブラを使用せずに、C言語だけでプログラムを完成させたいと思っています。

SCI1からの割り込み処理をするには、どの様にしたらよいのでしょうか?

どうか、お願いいたします。

Aベストアンサー

>void int_rxi1(void) 
>{
>  DI;  /*ここで他のプログラムの割り込みを禁止*/
>      /*割り込みで実行させたいプログラム*/
>  EI;  /*割り込み許可にしてプログラムを終了*/
>}

I.割込み処理ルーチンではDI,EIを行ってはいけません。
 以下に示すように割込みの禁止はハードウェアがやってくれます。
 割込み禁止解除は割込み処理が終了したとき実行されるRTE命令で
行われます。
------------ H8/3048ハードウェアマニュアル --------------------
4.1.2 例外処理の動作
例外処理は、各例外処理要因により起動されます。
トラップ命令および割り込み例外処理は、次のように動作します。
(1) プログラムカウンタ(PC)とコンディションコードレジスタ(CCR)をスタックに退避しま
す。
(2) CCRの割り込みマスクビットを1にセットします。
(3) 起動要因に対応するベクタアドレスを生成し、そのベクタアドレスの内容が示す番地からプ
ログラムの実行が開始されます。
【注】リセット例外処理の場合は上記(2)、(3)の動作を行います。
-------------------------------------------------------------------
II.割込み処理関数には#pragma interrupt を付けます。
#pragma interrupt
void int_rxi1(void)
{

}
 なお、#pragma と関数宣言の間にコメントを入れてはいけません。
 一種のおまじないです。

III. 割込み処理関数では少なくとも以下の2つを実行する。
 (1)SCI1.RDRを適切な場所に保存
 (2)SCI1.SCR.BIT.RDFをクリア

 デバッガを使えるなら、割込み処理の入り口で止めて動作を
確認して下さい。

>void int_rxi1(void) 
>{
>  DI;  /*ここで他のプログラムの割り込みを禁止*/
>      /*割り込みで実行させたいプログラム*/
>  EI;  /*割り込み許可にしてプログラムを終了*/
>}

I.割込み処理ルーチンではDI,EIを行ってはいけません。
 以下に示すように割込みの禁止はハードウェアがやってくれます。
 割込み禁止解除は割込み処理が終了したとき実行されるRTE命令で
行われます。
------------ H8/3048ハードウェアマニュアル --------------------
4.1.2 例外処理の動作
例外処...続きを読む

Q太陽系惑星は8個あります。すべて太陽を焦点とする楕円軌道上を公転しなが

太陽系惑星は8個あります。すべて太陽を焦点とする楕円軌道上を公転しながら、それぞれ異なる周期で反時計回りに自転しています。という問題があったのですが、これはあってますか、間違ってますか?
回答宜しくお願いしたします。

Aベストアンサー

【それぞれ異なる周期で反時計回りに自転しています】
                ~~~~~~~~
金星以外の惑星は公転方向に対して逆方向に自転しています。
金星だけは公転と同じ方向に自転しています。
答えは × になりますね・v・ノ

QH8Sで割り込み発生時の飛び先アドレスがRAM上にある場合の割り込み関数の記述方法

ルネサスのマイコンH8Sのプログラムを組んでおります。
プログラムの構成がBoot部分とアプリケーション部分に分かれており、
Bootはアドレス0番地から、アプリは3000番地以降の領域を使用するようになっています。
完成されたBootを使用してアプリケーションのプログラムを組まなければならなく、また、Bootは変更できないことになっています。
このBootの中のベクターテーブル上で、割り込みが発生した場合の飛び先のアドレスがRAM上になるように設定してあります。

このため、アプリケーションソフトでは、
割り込みが発生した場合のRAM上の飛び先に
FLASH ROM上の指定したアドレスにジャンプする命令を書き、
FLASH ROMのジャンプ先には、実行したい関数を書きたいのですが、

(1)RAM上の特定のアドレスからFLASH ROM上の指定したアドレスにジャンプさせる方法。
(2)FLAH ROM上の指定したアドレスに関数を記述する方法。
を知りたいのですが、
どなたか教えて頂けないでしょうか?
開発環境はHew4 言語はC言語を使用しております。
私自身が理解不足であるため質問内容が伝わりにくいかと思いますが、
宜しくお願い致します。

ルネサスのマイコンH8Sのプログラムを組んでおります。
プログラムの構成がBoot部分とアプリケーション部分に分かれており、
Bootはアドレス0番地から、アプリは3000番地以降の領域を使用するようになっています。
完成されたBootを使用してアプリケーションのプログラムを組まなければならなく、また、Bootは変更できないことになっています。
このBootの中のベクターテーブル上で、割り込みが発生した場合の飛び先のアドレスがRAM上になるように設定してあります。

このため、アプリケーションソフトでは...続きを読む

Aベストアンサー

特定のアドレスに特定のデータを書き込む方法。

例:6000番地から、順に、16進数の01,23,45,67を書き込む
unsigned char *addr;
addr = 0x6000;
addr[0] = 0x01;
addr[1] = 0x23;
addr[2] = 0x45;
addr[3] = 0x67;

もし「3014番地にジャンプするアセンブラコード」が「5A 00 14 30」であって、RAMの飛び先が6004番地なら
unsigned char *addr;
addr = 0x6004;
addr[0] = 0x5A;
addr[1] = 0x00;
addr[2] = 0x30;
addr[3] = 0x14;
と書けば良いです。

また「関数のアドレスにジャンプ」の場合は
unsigned char *addr;
addr = 0x6004;
int int_var;
void (*func_addr)(void);
func_addr = function_name; /*関数void function_name(void)のアドレスを受け取る*/
int_var = (int)func_addr); /*intにキャストする*/
addr[0] = 0x5A; /*JMP命令の1バイト目*/
addr[1] = 0x00; /*JMP命令の2バイト目*/
addr[2] = (int_var >> 8) & 0xff; /*アドレスの上位をセット*/
addr[3] = int_var & 0xff; /*アドレスの下位をセット*/

*注意*
上記の「0x5A 0x00」の命令コードは「たとえばの値」です。本当のJMP命令が何になるかは、アセンブラの命令コード表で調べて下さい。
また、上記では、16ビットアドレスを「上位、下位」の順にしていますが、H8Sでは順番が異なるかも知れません。命令コード表を良く見て「正しい順番」を確認して下さい。

特定のアドレスに特定のデータを書き込む方法。

例:6000番地から、順に、16進数の01,23,45,67を書き込む
unsigned char *addr;
addr = 0x6000;
addr[0] = 0x01;
addr[1] = 0x23;
addr[2] = 0x45;
addr[3] = 0x67;

もし「3014番地にジャンプするアセンブラコード」が「5A 00 14 30」であって、RAMの飛び先が6004番地なら
unsigned char *addr;
addr = 0x6004;
addr[0] = 0x5A;
addr[1] = 0x00;
addr[2] = 0x30;
addr[3] = 0x14;
と書けば良いです。

また「関数のアドレスにジャンプ」の場合...続きを読む


人気Q&Aランキング