PIC12F1822用のPWMの基本動作テストプログラムを作りましたが、PWM出力が意図どおりに得られません。
(XC8のテストプログラムを下に添付。テストパターン1/2の切り替えはコメントアウトをお願いします。
アナライザの出力を画像で添付しました。)
テスト目的: タイマー0の周期割り込みに合わせて、PWMのデューティー比(または周期)を変更するプログラム
テストパターン 1 : パルスのデューティー比を変えるテスト
質問1: パルスのデューティー比を変えるテストは、PWM設定の一回おきにCCPからのPWMの出力が出ません
テストパターン 2 : パルスの周波数を変えるテスト
質問2: 周波数を変えるテストはOKに見えるものの、1回目のPWMがHighとなるのと、割り込みの11回目、13回目あたりでPWM出力が欠落する
【回答のお願い】
どうも、PWMのレジスタ設定に手順、またはタイミングがあるのではないかと思いますが、原因がわからず困っております。
PICに詳しい方からのご指導をよろしくお願いいたします。
K.A.
------------------------------------------------------
/*
* File: PIC12F1822 PWC
* Author: K.A.
*
* Created on 2014/07/20
*
* タイマー0の周期割り込みに合わせて、PWMのデューティー比(または周期)を変更するプログラム
*
*/
#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
/*
*
*/
// タイマー割込みの処理
int TMR0_Count = 0; // タイマーの割込み発生回数をカウントする変数
void interrupt Timer0(void) {
// タイマー0の割込み発生か? Timer0 は 8bitの オーバーフロー・カウンタ
if (TMR0IF == 1) {
TMR0_Count++;
if (TMR0_Count > 5) {
TMR0_Count = 0;
if (RA5 == 0) RA5 = 1; else RA5 = 0; // RA5は、動作表示用LED
}
TMR0IF = 0; // タイマー0割込フラグをリセット
}
}
int main(int argc, char** argv) {
unsigned int pulse_width = 5;
OSCCON = 0b01110010; // 内部クロックは8MHz
ANSELA = 0b00000000; // すべてをデジタルI/Oに割当
TRISA = 0b00001000; // すべてのピンは出力に割当てる(RA3は入力専用)
PORTA = 0b00000000; // 出力ピンの初期化(全て'0'にする)
RA5 = 0; // 動作確認用LED
// Timer0 Timer0 は 8bitの オーバーフロー・カウンタ
OPTION_REG = 0b00000001; // 内部クロックでTIMER0を使用、プリスケーラカウント値 1:2
// bit5:0=Fosc/4, bit3:0=PreScaler_ON, bit2-0:PreScaler
TMR0 = 0; // タイマー0の初期化 (+2cycle)
TMR0IF = 0; // タイマー0割込フラグを0にする
TMR0_Count = 0; // 割込み発生の回数カウンターを0にする
TMR0IE = 1; // タイマー0割込みを許可する
GIE = 1; // 1: 全割込み処理を許可する
/* 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; // 4.096ms (プリスケーラが x64 の場合)
T2CKPS0 = 0b1; // プリスケーラ 00:x1, 01:x4, 10:x16, 11:x64
T2CKPS1 = 0b1; //
CCPR1L = pulse_width >> 2; // パルス幅上位8bit
CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C; // パルは幅下位2bit
TMR2ON = 1; // TMR2 カウント開始
while (TMR2IF == 0) { /** / do nothing /**/ }
TRISA2 = 0; // RA2に出力を接続
while (1) {
if (TMR0_Count == 0) {
/**** テストパターン 1 : パルスのデューティー比を変えるテスト ****/
// パルスのデューティー比を変えるテストは、PWM設定の一回おきにCCPがPWMの出力が出ません。 なぜ?
pulse_width = pulse_width + 10;
if (pulse_width > 500) pulse_width = 5;
/**/
/**** テストパターン 2 : パルスの周波数を変えるテスト **** /
// 周波数を変えるテストはOKに見えるが、
// 1回目のPWMがHighとなるのと、割り込みの11回目、13回目あたりでPWM出力が欠落する
PR2 = PR2 - 8 ;
if (PR2 < 8) PR2 = 127;
pulse_width = PR2 ; // Duty 25% に相当
/**/
CCPR1L = pulse_width >> 2;
CCP1CON = ((pulse_width & 0x0003) << 4) | 0x0C;
TMR0_Count++; // 続けて PWMの設定変更をしないためのフラグ代わり
}
}
return (EXIT_SUCCESS);
}
A 回答 (1件)
- 最新から表示
- 回答順に表示
No.1
- 回答日時:
質問2だけ。
PICのPWM機能は、デューティー比と違い、周波数をいつでも変えられるようには出来ていません。
タイミングによってはタイマーが1周するまで次の変化が起こりません。
この仕様を理解していないため問題が起こっているのではないかと思います。
ところで、もう1つの質問と内容がかぶっているようですので、示しておいた方がよいかと思います。
http://oshiete.goo.ne.jp/qa/8685497.html
回答ありがとうございます。
アセンブラでなくC言語で書いていますので、書き換えのタイミングはお任せになってしまいます。
これは、もっとスピードの速いCPUを使うしかなさそうですね。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# C言語 3 2022/11/09 13:27
- PHP PHPでCookieを使った訪問回数について 1 2023/05/28 14:10
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- PHP ランキングを表示する際の画像の大きさを固定することは可能でしょうか? <?php if ( has_ 1 2022/07/21 14:55
- Ruby 【JAVA】数字をひし形に出力するプログラムについて 2 2022/07/11 23:32
- Visual Basic(VBA) 【VBA】写真の縦横比を変えずに貼り付ける 5 2023/06/13 11:42
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
スーパーのレジで並んでいたら...
-
PICでのプログラムによるチャタ...
-
SH2 (SH7144)のソフトウェアス...
-
Amazonfireタブレットにわから...
-
電車のドアの前での並び方
-
PICで内部タイマーを使わずカウ...
-
ストップウォッチ
-
マイコン C言語 割り込み処理...
-
PICのI2C通信を行っているとき...
-
V.B.6 多重Call用スプール作成...
-
システムの割り込みについて シ...
-
PICのPWMの正しい使い方につい...
-
auの携帯で「パケット通信中...
-
複数の割込み処理からアクセス...
-
Excelでタイマーの一時停止する...
-
電車で待機列の割り込みについ...
-
USB機器からのデータ受信による...
-
H8マイコンで割り込みが任意の...
-
VB.net 割り込みの禁止
-
順番待ちで並んでいる時、割り...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ショッピング
-
スーパーのレジで並んでいたら...
-
pic 複数の割り込み関数 切り分...
-
マイコン C言語 割り込み処理...
-
Amazonfireタブレットにわから...
-
CPUの処理量を減らすコーデ...
-
irqbalance って
-
CPU負荷率の安全な上限と計...
-
一定時間操作がなかったら、と...
-
電車で待機列の割り込みについ...
-
VB6でSendKeyを利用したTab移動...
-
(H8マイコン)タイマ割込で変更...
-
駅のトイレでナイチンに邪魔さ...
-
アセンブラのタイマー割り込み
-
PICのPIN変化割り込みに...
-
USJでの割り込み
-
H8マイコンで割り込みが任意の...
-
PIC16F84AのRBポート変化割り込...
-
AKI-H8/3048Fでのタイマ割り込み
-
H8マイコンでの割り込み(シリ...
おすすめ情報