掲示板


[記事リスト] [返信する] [新着記事] [過去ログ] [ワード検索] [留意事項] [管理用]

記事No 867
タイトル Re: PWMでDuty=0が実行されない
投稿日 : 2017/03/31(Fri) 01:12:30
投稿者 n
参照先
Qmanさん

はじめましてnです。

データシートを読んだだけなので実際には試していません。
以下の仮説をご検証ください。

データが35のとき、カウンタ?は「0b00100000.11」でコンペアされ、
PWM出力用のFFがリセットされます。
このとき、カウンタの上位8bitはクリヤされますが、下位の2bitは、
クロックOSCの信号を参照しているだけなので、変化しません。

つまり、10ビットカウンタ?の値は「0b00000000.11」です。
これを捕まえるためには、データも「0b00000000.11」と指定します。

0b00000000.00になるのは、0b11111111.11の次です。
0b00000000.11→0b00000001.00→0b00000001.01→…0b11111111.11
このため、約1周期リセットが遅延します。

void pwm_duty_set(signed long x)
{
if (x > 0){
CCP1CON.dat = x & 0b00000011; // 下位2bit
CCPR1L = x >> 2; // 上位8bit
}else{
CCP1CON.dat = CCP1CON.dat; // 下位2bit(保存)
CCPR1L = 0; // 上位8bit
}
}

> PIC16F1827 で CCSC でPWMのプログラムを作りました。
> CPU: PIC16F1827 32MHz(x4 PLL)
> PWMの周期:100uS 分解能: 800
>
> 下記の「PWM繰返し」部において
> PWMの100周期ごとにTMR2割込みを発生させて@ABを実行させます。
> (@の実行前はBの続きでDuty=400になっています。)
>
> @の実行後、(100uS後の)次のPWM周期にDuty=N1になります。
> Aの実行後、(100uS後の)次のPWM周期にDuty=0になります。
> Bの実行後、(100uS後の)次のPWM周期にDuty=400になり、それが続きます。
>
> しかし、N1=35,43,67・・・(10進数)のときだけ (N1は変数ではなく定数です。)
> Aの実行後、(100uS後の)次のPWM周期に
> Duty=0 にならず Duty=800(100%)になります。
> これらの数値を16進数にすると下位2bitが"11"になる場合ということがわかりました。
> しかし、その理由がわかりません?。
> ご教授をお願いします。
>
> CCPTMRS = 0x00; // CCP1 にTMR2を使用
> CCP1CON = 0b00001100; // CCP1=PWMモード
>
> struct {
> int CCP1M :4; // b3-0
> int dat :2; // b5.4 PWM 下位2bitデータ
> int P1M :2; // b7.6
> } CCP1CON;
> #byteCCP1CON = 0x293
>
> void pwm_duty_set(signed long x)
> {
> if (x > 0)
> {
> CCP1CON.dat = x & 0b00000011; // 下位2bit
> CCPR1L = x >> 2; // 上位8bit
> }
> else
> {
> CCP1CON.dat = 0; // 下位2bit
> CCPR1L = 0; // 上位8bit
> }
> }
>
> void main()
> {
> // ----- PWM繰返し -----
> pwm_duty_set(N1); //@
> delay_us(100);
> pwm_duty_set(0); //A
> delay_us(100);
> pwm_duty_set(400); //B

- 関連一覧ツリー (▼ をクリックするとツリーを一括表示します)


- 返信フォーム (この記事に返信する場合は下記フォームから投稿して下さい)
おなまえ
Eメール
タイトル
メッセージ
参照先
画像UP
暗証キー (英数字で8文字以内)
投稿キー (右画像の数字を入力) 投稿キー


- 投稿記事修正/削除フォーム -
処理 No 暗証キー

- WebForum -