[戻る]
過去ログ [ 0001 ]
過去ログ:     ワード検索: 条件: 表示:

タイトル
記事No
投稿日
投稿者
参照先
10bit pwmでduty100%
79
: 15/01/19-07:50
ちびた

PIC16F1936を使っています。

uint test1 = 1023;
// 下位2bitをセット
CCP1CON |= ((test1 << 4) & 0b110000);
// 上位8bitをセット
CCPR1L = test1 >> 2;

としてもオシロで計測すると一瞬OFFになります。
10bitのpwmでdutyを100にするには単純にポートをONするしかないんでしょうか。
教えてgooで質問したら1024を設定するという回答があったのですが
調べても具体的な方法がわかりませんでした。
お知恵をおかしいただけないでしょうか。
▲pagetop
タイトル
記事No
投稿日
投稿者
参照先
Re: pwmでduty100%
80
: 15/01/19-09:37
Gokan <gokan@picfun.com>

CCP1はECCPとなっています。
初期設定はどのようにしていますでしょうか?
PWM1CONやPSTR1CON、CCP1AS、CCP1CONなどの設定です。


> PIC16F1936を使っています。
>
> uint test1 = 1023;
> // 下位2bitをセット
> CCP1CON |= ((test1 << 4) & 0b110000);
> // 上位8bitをセット
> CCPR1L = test1 >> 2;
>
> としてもオシロで計測すると一瞬OFFになります。
> 10bitのpwmでdutyを100にするには単純にポートをONするしかないんでしょうか。
> 教えてgooで質問したら1024を設定するという回答があったのですが
> 調べても具体的な方法がわかりませんでした。
> お知恵をおかしいただけないでしょうか。
▲pagetop
タイトル
記事No
投稿日
投稿者
参照先
Re^2: pwmでduty100%
84
: 15/01/19-22:33
ちびた

Gokanさん

お返事ありがとうございます。
初期設定ですが以下のとおりです。

// 拡張ではなく通常のPWMとしてセット
CCP1CON = 0b1100;

// 以下、明示的な設定はしていません。
PWM1CON
PSTR1CON
CCP1AS

---------------------------------
// 具体的には以下のように設定しています。

CCPTMRS0 = 0; // TMR2を使用
PR2 = 255; // 10bit
CCP1CON = 0b1100; // PWMモードを指定
T2CON = 0b11; // プリスケーラを64にセット
TMR2 = 0; //tmr2クリア
TMR2ON = 0b1; // tmr2開始

uint test1 = 1023; // 最大値をセット
CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
CCPR1L = test1 >> 2; // 上位8bitをセット

どこか設定が間違っていますでしょうか?

ちなみに教えてgooについた唯一の回答は以下のとおりです。

「1023カウントで出力はOFFになります、
同時に次のサイクルに入りますが出力に反映されるまで遅延時間(td)があるので
100%デューティーにはなりません。
1024以上にするかPWMを使用せず単純にONにするかですね。」

「データシートを見れば容易にわかることです。」とのことだったのですが
PWM関連のところを見たりネットで調べたりしたのですが結局全然わからず
いろいろ検索してる時にこちらにたどり着いた次第です。

そもそも10bitしかないのに1024以上にするというのはどういうことなんでしょうか?
▲pagetop
タイトル
記事No
投稿日
投稿者
参照先
Re^3: pwmでduty100%
85
: 15/01/20-11:34
Gokan <gokan@picfun.com>

この短時間のLow出力は、周期がPR2+1で設定されることによります。
Dutyの方はMax1023で周期の方はMax1024まで進むことになります。
この1カウント分の差が短時間のLow出力となってしまいます。

したがって100%のとき短時間のLowパルスが出ないようにするためにはPR2を0xFEとする必要があり、さらにDutyを1020以上にします。

1024以上にするという回答の意味は、周期以上の値にせよという意味ですね。

それとPSTR1CONレジスタには0x01を設定する必要があります。

> Gokanさん
>
> お返事ありがとうございます。
> 初期設定ですが以下のとおりです。
>
> // 拡張ではなく通常のPWMとしてセット
> CCP1CON = 0b1100;
>
> // 以下、明示的な設定はしていません。
> PWM1CON
> PSTR1CON
> CCP1AS
>
> ---------------------------------
> // 具体的には以下のように設定しています。
>
> CCPTMRS0 = 0; // TMR2を使用
> PR2 = 255; // 10bit
> CCP1CON = 0b1100; // PWMモードを指定
> T2CON = 0b11; // プリスケーラを64にセット
> TMR2 = 0; //tmr2クリア
> TMR2ON = 0b1; // tmr2開始
>
> uint test1 = 1023; // 最大値をセット
> CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
> CCPR1L = test1 >> 2; // 上位8bitをセット
>
> どこか設定が間違っていますでしょうか?
>
> ちなみに教えてgooについた唯一の回答は以下のとおりです。
>
> 「1023カウントで出力はOFFになります、
> 同時に次のサイクルに入りますが出力に反映されるまで遅延時間(td)があるので
> 100%デューティーにはなりません。
> 1024以上にするかPWMを使用せず単純にONにするかですね。」
>
> 「データシートを見れば容易にわかることです。」とのことだったのですが
> PWM関連のところを見たりネットで調べたりしたのですが結局全然わからず
> いろいろ検索してる時にこちらにたどり着いた次第です。
>
> そもそも10bitしかないのに1024以上にするというのはどういうことなんでしょうか?
▲pagetop
タイトル
記事No
投稿日
投稿者
参照先
Re^4: pwmでduty100%
90
: 15/01/21-01:08
ちびた

Gokanさん

さっそく試してみたところ仰られた通り動作しました。
教えていただいたPSTR1CONですがこれは拡張で利用するときのレジスタで
通常のPWMでは必要ないと思っていました。
それとふと疑問に思ったのですが
下記のような場合、値は半端に入ってしまうんでしょうか。

----------------------------
CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット

<<ここで PR2 と TMR2 が一致し CCPR1H にDutyがセットされる>>

CCPR1L = test1 >> 2; // 上位8bitをセット
----------------------------

こうならないようにロジックでTMR2の値を確認しながら
上位と下位のDutyをセットするのが正しいやり方でしょうか?
たとえば上位と下位のDutyをセットするとTMR2が10進むとして

if(TMR2 < (255 - 10)){

CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
CCPR1L = test1 >> 2; // 上位8bitをセット

}

とか。

追加質問になってしまうのですが
このような場合の定番の対応などはあるのでしょうか?


> この短時間のLow出力は、周期がPR2+1で設定されることによります。
> Dutyの方はMax1023で周期の方はMax1024まで進むことになります。
> この1カウント分の差が短時間のLow出力となってしまいます。
>
> したがって100%のとき短時間のLowパルスが出ないようにするためにはPR2を0xFEとする必要があり、さらにDutyを1020以上にします。
>
> 1024以上にするという回答の意味は、周期以上の値にせよという意味ですね。
>
> それとPSTR1CONレジスタには0x01を設定する必要があります。
>
> > Gokanさん
> >
> > お返事ありがとうございます。
> > 初期設定ですが以下のとおりです。
> >
> > // 拡張ではなく通常のPWMとしてセット
> > CCP1CON = 0b1100;
> >
> > // 以下、明示的な設定はしていません。
> > PWM1CON
> > PSTR1CON
> > CCP1AS
> >
> > ---------------------------------
> > // 具体的には以下のように設定しています。
> >
> > CCPTMRS0 = 0; // TMR2を使用
> > PR2 = 255; // 10bit
> > CCP1CON = 0b1100; // PWMモードを指定
> > T2CON = 0b11; // プリスケーラを64にセット
> > TMR2 = 0; //tmr2クリア
> > TMR2ON = 0b1; // tmr2開始
> >
> > uint test1 = 1023; // 最大値をセット
> > CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
> > CCPR1L = test1 >> 2; // 上位8bitをセット
> >
> > どこか設定が間違っていますでしょうか?
> >
> > ちなみに教えてgooについた唯一の回答は以下のとおりです。
> >
> > 「1023カウントで出力はOFFになります、
> > 同時に次のサイクルに入りますが出力に反映されるまで遅延時間(td)があるので
> > 100%デューティーにはなりません。
> > 1024以上にするかPWMを使用せず単純にONにするかですね。」
> >
> > 「データシートを見れば容易にわかることです。」とのことだったのですが
> > PWM関連のところを見たりネットで調べたりしたのですが結局全然わからず
> > いろいろ検索してる時にこちらにたどり着いた次第です。
> >
> > そもそも10bitしかないのに1024以上にするというのはどういうことなんでしょうか?
▲pagetop
タイトル
記事No
投稿日
投稿者
参照先
Re^5: pwmでduty100%
91
: 15/01/21-09:13
Gokan <gokan@picfun.com>

PWMの場合のCCPは、CCPR1LとCCPR1Hがダブルバッファになっていて
CCPR1LにセットしたDuty値は、周期の最初に(TMR2が0のとき)
CCPR1LからCCPR1HにコピーされてDutyが更新されます。
したがってTMR2をチェックする必要はありません。


> Gokanさん
>
> さっそく試してみたところ仰られた通り動作しました。
> 教えていただいたPSTR1CONですがこれは拡張で利用するときのレジスタで
> 通常のPWMでは必要ないと思っていました。
> それとふと疑問に思ったのですが
> 下記のような場合、値は半端に入ってしまうんでしょうか。
>
> ----------------------------
> CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
>
> <<ここで PR2 と TMR2 が一致し CCPR1H にDutyがセットされる>>
>
> CCPR1L = test1 >> 2; // 上位8bitをセット
> ----------------------------
>
> こうならないようにロジックでTMR2の値を確認しながら
> 上位と下位のDutyをセットするのが正しいやり方でしょうか?
> たとえば上位と下位のDutyをセットするとTMR2が10進むとして
>
> if(TMR2 < (255 - 10)){
>
> CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
> CCPR1L = test1 >> 2; // 上位8bitをセット
>
> }
>
> とか。
>
> 追加質問になってしまうのですが
> このような場合の定番の対応などはあるのでしょうか?
>
>
> > この短時間のLow出力は、周期がPR2+1で設定されることによります。
> > Dutyの方はMax1023で周期の方はMax1024まで進むことになります。
> > この1カウント分の差が短時間のLow出力となってしまいます。
> >
> > したがって100%のとき短時間のLowパルスが出ないようにするためにはPR2を0xFEとする必要があり、さらにDutyを1020以上にします。
> >
> > 1024以上にするという回答の意味は、周期以上の値にせよという意味ですね。
> >
> > それとPSTR1CONレジスタには0x01を設定する必要があります。
> >
> > > Gokanさん
> > >
> > > お返事ありがとうございます。
> > > 初期設定ですが以下のとおりです。
> > >
> > > // 拡張ではなく通常のPWMとしてセット
> > > CCP1CON = 0b1100;
> > >
> > > // 以下、明示的な設定はしていません。
> > > PWM1CON
> > > PSTR1CON
> > > CCP1AS
> > >
> > > ---------------------------------
> > > // 具体的には以下のように設定しています。
> > >
> > > CCPTMRS0 = 0; // TMR2を使用
> > > PR2 = 255; // 10bit
> > > CCP1CON = 0b1100; // PWMモードを指定
> > > T2CON = 0b11; // プリスケーラを64にセット
> > > TMR2 = 0; //tmr2クリア
> > > TMR2ON = 0b1; // tmr2開始
> > >
> > > uint test1 = 1023; // 最大値をセット
> > > CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
> > > CCPR1L = test1 >> 2; // 上位8bitをセット
> > >
> > > どこか設定が間違っていますでしょうか?
> > >
> > > ちなみに教えてgooについた唯一の回答は以下のとおりです。
> > >
> > > 「1023カウントで出力はOFFになります、
> > > 同時に次のサイクルに入りますが出力に反映されるまで遅延時間(td)があるので
> > > 100%デューティーにはなりません。
> > > 1024以上にするかPWMを使用せず単純にONにするかですね。」
> > >
> > > 「データシートを見れば容易にわかることです。」とのことだったのですが
> > > PWM関連のところを見たりネットで調べたりしたのですが結局全然わからず
> > > いろいろ検索してる時にこちらにたどり着いた次第です。
> > >
> > > そもそも10bitしかないのに1024以上にするというのはどういうことなんでしょうか?
▲pagetop
タイトル
記事No
投稿日
投稿者
参照先
Re^6: pwmでduty100%
94
: 15/01/21-20:48
ちびた

Gokanさん

内容についてよく理解できました。
一週間くらい悩んでいたので助かりました。
教えていただきありがとうございました。

> PWMの場合のCCPは、CCPR1LとCCPR1Hがダブルバッファになっていて
> CCPR1LにセットしたDuty値は、周期の最初に(TMR2が0のとき)
> CCPR1LからCCPR1HにコピーされてDutyが更新されます。
> したがってTMR2をチェックする必要はありません。
>
>
> > Gokanさん
> >
> > さっそく試してみたところ仰られた通り動作しました。
> > 教えていただいたPSTR1CONですがこれは拡張で利用するときのレジスタで
> > 通常のPWMでは必要ないと思っていました。
> > それとふと疑問に思ったのですが
> > 下記のような場合、値は半端に入ってしまうんでしょうか。
> >
> > ----------------------------
> > CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
> >
> > <<ここで PR2 と TMR2 が一致し CCPR1H にDutyがセットされる>>
> >
> > CCPR1L = test1 >> 2; // 上位8bitをセット
> > ----------------------------
> >
> > こうならないようにロジックでTMR2の値を確認しながら
> > 上位と下位のDutyをセットするのが正しいやり方でしょうか?
> > たとえば上位と下位のDutyをセットするとTMR2が10進むとして
> >
> > if(TMR2 < (255 - 10)){
> >
> > CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
> > CCPR1L = test1 >> 2; // 上位8bitをセット
> >
> > }
> >
> > とか。
> >
> > 追加質問になってしまうのですが
> > このような場合の定番の対応などはあるのでしょうか?
> >
> >
> > > この短時間のLow出力は、周期がPR2+1で設定されることによります。
> > > Dutyの方はMax1023で周期の方はMax1024まで進むことになります。
> > > この1カウント分の差が短時間のLow出力となってしまいます。
> > >
> > > したがって100%のとき短時間のLowパルスが出ないようにするためにはPR2を0xFEとする必要があり、さらにDutyを1020以上にします。
> > >
> > > 1024以上にするという回答の意味は、周期以上の値にせよという意味ですね。
> > >
> > > それとPSTR1CONレジスタには0x01を設定する必要があります。
> > >
> > > > Gokanさん
> > > >
> > > > お返事ありがとうございます。
> > > > 初期設定ですが以下のとおりです。
> > > >
> > > > // 拡張ではなく通常のPWMとしてセット
> > > > CCP1CON = 0b1100;
> > > >
> > > > // 以下、明示的な設定はしていません。
> > > > PWM1CON
> > > > PSTR1CON
> > > > CCP1AS
> > > >
> > > > ---------------------------------
> > > > // 具体的には以下のように設定しています。
> > > >
> > > > CCPTMRS0 = 0; // TMR2を使用
> > > > PR2 = 255; // 10bit
> > > > CCP1CON = 0b1100; // PWMモードを指定
> > > > T2CON = 0b11; // プリスケーラを64にセット
> > > > TMR2 = 0; //tmr2クリア
> > > > TMR2ON = 0b1; // tmr2開始
> > > >
> > > > uint test1 = 1023; // 最大値をセット
> > > > CCP1CON |= ((test1 << 4) & 0b110000); // 下位2bitをセット
> > > > CCPR1L = test1 >> 2; // 上位8bitをセット
> > > >
> > > > どこか設定が間違っていますでしょうか?
> > > >
> > > > ちなみに教えてgooについた唯一の回答は以下のとおりです。
> > > >
> > > > 「1023カウントで出力はOFFになります、
> > > > 同時に次のサイクルに入りますが出力に反映されるまで遅延時間(td)があるので
> > > > 100%デューティーにはなりません。
> > > > 1024以上にするかPWMを使用せず単純にONにするかですね。」
> > > >
> > > > 「データシートを見れば容易にわかることです。」とのことだったのですが
> > > > PWM関連のところを見たりネットで調べたりしたのですが結局全然わからず
> > > > いろいろ検索してる時にこちらにたどり着いた次第です。
> > > >
> > > > そもそも10bitしかないのに1024以上にするというのはどういうことなんでしょうか?
▲pagetop

- WebForum -