• ベストアンサー

dsPICを用いたPWM出力

dsPIC(30F4012)でPWMの出力をしてやりたいのですがソフトの知識があまりなく困っています。外部の可変抵抗の値をAD変換した後にそのAD変換した値をデューティ比と比例させてPWM波形を出力してやりたいのです(リアルタイムで変化)。開発環境はMPLAB(C30)です。ご指導お願いいたします。

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

  • ベストアンサー
  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.2

何か複雑に考えすぎなような気がします。 PICは使ったことがないのでH8とかでの話になりますが、基本は一緒のはずです。 質問文から、やることは ・ADCが変換完了時に割り込み ↓ ・ISRでA/DデータレジスタからA/D値を取得、Duty比からPWM幅を計算してPWM設定レジスタに入れる(ここまでがAD変換完了割り込み) ↓ ・PWMは勝手に設定通りにパルス幅を変化させる と考えたので、この通りならPWMとADCのコードが一箇所にまとまっている必要はほとんどないと言えます。 せいぜい、ADCがパルス幅設定レジスタを知っている必要がある程度でしょう。

その他の回答 (1)

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.1

ええと、「やりたいこと」じゃなくて「その中でどこがわからないのか」を書いてもらえませんか? これだと、単純にA/D変換完了割り込みの中でPWM幅を変化させればよいと思う訳ですが。 ADCが外部とかいうと少し面倒ですが30F4012はADCもPWMも持ってるようなのであまり考えることはないと思いますけど。

thunder_5252
質問者

お礼

AD変換はできたのですがPWM出力のプログラムの中の関数の設定を行った後以降がわからないです。そして、AD変換とPWM出力を同じプログラム中に書くにはどうやったらいいのかもわかりません(文法的なこと)

関連するQ&A

  • PWM信号の切り替わり時間について

    今、PWM制御回路をアナログ回路で考えています。 コンパレータを使い、三角波発振回路と基準電圧で比較してPWM波形を出力して、デューティを可変抵抗で調整できるようなものを考えています。 そこで、PWM信号をHigh→Low、Low→Highへ切り替わる時間を3nsほどにしたいのですが、アナログ回路でこの値で切り替わるようにするには、どのような設計をすればいいのでしょうか? 今調べているのですが、まだわかっておりません。 もしよろしければアドバイスを頂けたら幸いです。

  • PICのPWMについてのプログラム

    先程似たような質問してしまいましたが変更します。 PICを使い外部からのアナログ音声約0.5秒をPIC内臓のAD変換機能を使用してPIC内に格納します。 元々スイッチを2つ付けて1つを押したら上記のようになり、もう1つを押したら格納されているデジタルデータがPWM波となりポートBから出力される物を作りたいです。 出力された波形はローパスフィルターを通りDA変換されてアナログ音が外部に出る。 『0.5秒しか録音できないレコーダ』みたいなものをつくりたいというのが全体図です。 AD変換やDA変換はなんとか解るのですがPICからPWM波を出力する回路(プログラム)がよく解りません。 知っている方いましたら力を貸してもらえませんでしょうか?

  • PICによるPWM出力の周期について

    PIC(16f873)を用いて、モータをPWM制御しようと思っています。 そこでいくつか質問なんですが、PWMの周期は下記の式で与えられるとありますが、 PWM周期 = (PR2の値+1)x4x発振器周期xタイマー2のプリスケーラ値 この周期は、自分で適当に決めていいのでしょうか?それともモータによって決まっているんでしょうか?  そもそもPWMは、デューティ比で出力が変わると思うんですが、周期が違うとどのような違いが出るのでしょうか?周波数が高くなると細かい制御が出来るって感じでしょうか? 初歩的な質問ですが、よろしくお願いします。m(_ _)m

  • PWMのパルスを直流電圧にしたいです

    PWMのパルス幅によって電圧が0~5VとしてPICなどのADコンバータで入力して デジタルの数値として認識したいのですが、 パルス波形をDuty比に応じた直流電圧にするにはどんな回路をつければ良いでしょうか? またPWMの周波数は何ヘルツくらいが良いでしょうか? (周波数の上限、下限などがあったら教えていただきたいです)

  • マイコンによるPWM制御

    7個のサーボをマイコンによって独立に駆動しようと試みています。 つまり、別の周期、DUTY比のPWM信号を7つ同時に出力できるマイコンが要求されます。 どのようなマイコンが最適でしょうか。 ほかの条件としては、 1.開発環境が整っている。 2.入手性がよい 3.ローコスト 4.20MIPS以上の処理性能 でしょうか。どなたかお願いします。

  • タイマICを使ったPWM信号の作り方

    周波数:約100Hz(精度悪くても良いです) デューティ比:10%~90%ぐらい タイマIC入力:5V PWM信号:5V・20mA以下 以上の仕様でPWM信号を出力する回路を自作したいのですが、 どのようなタイマICを使うのが良いでしょうか? タイマIC555を検討したのですが、デューティ比50%以上しか作れないようでした。 よろしくお願いします。

  • PWM制御のデューティ変更時におけるトラブル

    SH7211マイコンのPWM(モード1)を使用して、定電流制御をしています。 PWMの周期を10KHzとし、その割り込みの周期で電流値を増設のADコンバータで取得、PID演算の後にPWMのデューティを変更して電流を制御するフィードバック機構です。 この時、10KHzで割り込みをして電流を一定に保つようデューティを常に変更しているのですが、過度に電流を流さないようデューティの値を変更する時はデューティが50%以上にならないようにしています。 ですが、PWM出力をオシロで見ていると、例えば電流値を5Aから1Aへ変更しようとした時、変更するタイミングで何故かデューティが100%以上になってしまい、本来電流値が下がるべき所で一瞬だけ5A以上となる現象に悩まされています。 CPUのマニュアルに、「周期レジスタとデューティレジスタのコンペアマッチが同時に発生すると出力は変化しない」とあり、その時デューティが100%以上になってしまう動作例が載っているのですが、プログラム上でデューティは50%以上にならないようにしていますので、この箇所は問題ないかと思います。 今現在わかっている事ですが 1) 割り込みで常にデューティは書き換えているのですが、電流値を変化させた時、つまりデューティレジスタの値を急激に変化させた時に発生しているように見えます。2A→1A程度の変化では発生しません。 2) 5A→1Aと減らした時と、1A→5Aと増やした時両方で発生します。 3) デューティを変更する直前でブレークをかけて、適当なタイミングでブレーク解除した時、この現象が発生する時と発生しない時があります(デューティを変更するタイミングが問題?)。 4) デューティレジスタの値を0とした場合、上記に書きました「周期レジスタとデューティレジスタのコンペアマッチが同時に発生すると出力は変化しない」事に該当するかもしれないと考え、デューティレジスタの値が0の時は強制的に値を10としましたが、この現象が発生しました。 また、プログラムの中身ですが 1) 周期レジスタの値は3999、デューティレジスタの値は0~1999の値で変化。 2) 出力は初期出力がHi、コンペアマッチでLowというHi→Low出力。 3) 割り込み関数の中でADコンバータから値を取得→PID演算→デューティレジスタの値を変更という処理をしています。 4) 割り込みレベルを他の割り込みと比べて一番高くしているため、割り込み関数処理中に他の割り込みは発生しません。 長文申し訳ございませんが、何か同じような現象が起きた方、または何かしらの解決策をご存知の方、アドバイスを宜しくお願いします。

  • 回路について教えてください!!

    PWM発振回路について積分回路での三角波形が乱れてしまいます。直す方法がわかりません。 現在、タイマIC(NE555)とオペアンプ(LMC662)を用いてPWM発振回路の作成をしています。 タイマICでデューティ比0.5のクロック波形(5V, 6.8kHz)を作り、積分回路を通して三角波形を出力します。その時、積分回路において可変抵抗を操作することで基準電圧をGNDに近づけようとすると三角波形が非常に乱れ、周波数・位相が全く違うものになってしまいます。乱れた波形をどうにか安定したものにしたいです。 解決策を考えたのですがわかりません。どなたか教えてください。

  • UC3526A:PWMコントローラの使用法について

    本を読んでいたところ、気になる部品がありましたので質問させて頂きます。 PWMコントローラ「UC3526A」の動作についてです。 データシート → http://www.tij.co.jp/jp/lit/ds/symlink/uc3526a.pdf データシートを読み、自分なりに考えてみましたが、英語ということもありこのシートだけでは よく理解できませんでした。 シートにはPWMコントローラと記述されており、また書いてある内容から 出力するパルスのDuty比を変化させる物であると思うのですが、 もう少し詳細な動作を知りたいと思っています。 ご存知の方、教えて頂けますか? 現在私がこんな動作をするんじゃないかと思っている事、及び疑問点を挙げます。 ・ RESET、SHUTDOWNで出力を止められる。 ・ 外付けのR、Cでオシレータの周波数を決められる。   → オシレータの半分の周波数のパルスがOUT A、Bから出力されるのですか?(Duty比可変) ・ 1,2ピンの+EA、-EAの差を見て、差があるとDuty比が上下するのですか? ・ SYNC信号は入力にも出力にもなるのですか?   入力の場合、出力の場合それぞれのSYNC信号の役目は何ですか? ・ 6,7ピンの役割は何ですか? ・ Vrefの役割は何ですか? ほとんどわかっていませんが、動作を知りたいと思います。 お願いします。

  • PICのPWMの使い方を教えてください

    PIC12F1822のPWMのテストをしていますが、正しい設定方法が判らず、以下の現象が出ています。 プログラム全体と、MPLIB のシミュレータによるLogic Analyzerの画像を添付しましたので、PICにお詳しい方のアドバイスをよろしくお願いいたします。 ◆ テスト内容: 周波数一定でデューティー比を変化させていく  今回の設定は、PR2=127 なので、パルス幅を0 ~ 最大パルス幅の 511 ((PR2+1)*4)で変化させる ●問題点1: デューティー比100%近く(508/512)でPWM出力が突然 50%に変わる。 ●問題点2: デューティー比100%以上(512/512以上)を設定するとPWMは100%('H'のまま)となる。 その後デューティ比を下げてもPWMの出力は'H'のままで、PWMの出力が出ない。 ● 問題点3: パルス幅の設定で、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる(出力が'H'のまま) ・・・ これはシミュレータのバグでしょうか? プログラム全体は、一番下にありますが、メインロジックは以下のように簡単なものです。 while (1) { for (i = 500; i <= 512; i = i + 1) { pulse_width = i ; CCPR1L = pulse_width >> 2; // パルス幅上位8bit CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; // パルス幅下位2bit         // ここで、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる __delay_ms(1); } } どうぞよろしくお願いいたします。                           K.A. --------------------------------------------- /* * File: 周波数一定、ディューティー比連続変化 * Author: K.A. * * Created on 2014/07/20 * */ #include <stdio.h> #include <stdlib.h> #include <xc.h> #pragma config FOSC=INTOSC, WDTE=OFF, PWRTE=ON, BOREN=ON, MCLRE=OFF #define _XTAL_FREQ 8000000 // クロック8MHz #define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0))) int main(int argc, char** argv) { OSCCON = 0b01110010; // 内部クロックは8MHz ANSELA = 0b00000000; // すべてをデジタルI/Oに割当 TRISA = 0b00001000; // すべてのピンは出力に割当てる(RA3は入力専用) PORTA = 0b00000000; // 出力ピンの初期化(全て'0'にする) RA5 = 0; // 動作確認用LED /* PWM */ TRISA2 = 1; // RA2 出力をサスペンド TMR2IF = 0; // TMR2 フラグをクリア CCP1SEL = 0b0; // CCP1/P1Aの機能をRA2に割り当てる CCP1CON = 0x0C; // PWM モード // Period を 設定する xx ms=((PR2)+1)*4*125ns(8MHz)* PreScaler(x1-x64) PR2 = 127; // 0.064ms (プリスケーラが x1 の場合) T2CKPS0 = 0b0; // プリスケーラ 00:x1, 01:x4, 10:x16, 11:x64 T2CKPS1 = 0b0; // CCPR1L = 0; // パルス幅上位8bit CCP1CON = ((0 & 0x0003) << 4) | 0x0C; // パルス幅下位2bit TMR2ON = 1; // TMR2 カウント開始 while (TMR2IF == 0) { /** / do nothing /**/ } TRISA2 = 0; // RA2に出力を接続 unsigned int pulse_width; int i; while (1) { // パターン1 : デューティー比を変化させていく // 今回の設定は、PR2=127 なので、最大パルス幅は 511 ((PR2+1)*4) // 問題点1: デューティー比100%近く(508/512)でPWM出力が突然 50%に変わる。 // 問題点2: デューティー比100%以上(512/512以上)を設定するとPWMは100%('H'のまま)となる。 // その後デューティ比を下げてもPWMの出力は'H'のままで、PWMの出力が出ない。 // 問題点3: パルス幅の設定で、CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる(出力が'H'のまま) for (i = 500; i <= 512; i = i + 1) { pulse_width = i ; // Pulse width を 設定する PW=(CCPR1L:CCP1CON<5:4>)*125ns(8MHz)*PreScaler(x1-x64) CCPR1L = pulse_width >> 2; CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; // CCP1CON<5:4>に'00'以外をセットすると、PWMの動作がおかしくなる // printf("PR2= %d, PW= %d, CCPR1L= %x, DCIB= %x \n", PR2, pulse_width, CCPR1L, temp2) ; __delay_ms(1); if (RA5==1) RA5=0; else RA5=1 ; } } return (EXIT_SUCCESS); } ----------------------------------------

専門家に質問してみよう