[戻る]
新着表示

Re: PWMでDuty=0が実行されない 投稿者:n 投稿日:2017/03/31(Fri) 01:12:30 No.867

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

PWMでDut=0が実行されない 投稿者:Qman 投稿日:2017/03/30(Thu) 19:41:45 No.866


>きちんとオシロスコープで出力を解析されることをお勧めします。

当然、しています。
本質問に関しては、
デジタルオシロスコープで波形観測をして確認したうえでなければ質問自体が
無意味であるということは誰でもわかることです。

8bitとしての使い方はしていません。
プログラムリストをみればわかるとおり10bitで使用していますし
動作も10bitで動作していることは質問および返信に書いたとうりです。

いままで経験した、機械系のような低速応答の閉ループ制御においては
本質問のとおりでもほとんど問題はないことはおわかりのことと思います。
それで、いままで気が付かなかったと思います。


> 横から失礼します。
> 詳しくマニュアルを誰も親切には見ないでしょう。
> PWMを単にOFFでいいものを、原因を知りたいというご意見でしたので、回答を控えていました。
> 8ビットの場合で考えてみれば、0が設定値としてOKなら最大値は255まで、0が値としてNGなら、値は1からなので最大値は256です。
> どちらかで出来ているはずです。
> 前者の場合、ビットの基準が0=256の最大値を意味することも有り得るので、原因を知りたいのなら、0、1、255、256の値をそれぞれ代入してみて、結果がどう変わるか確認して下さい。
> おそらく、255の時にPWMはOFF(duty=0)になるはずです。
> 8ビットの場合で説明しているので、16ビットであれば当てはめて考えて下さい。
> もうひとつ、duty=0は厳密にはならないはずなので、きちんとオシロスコープで出力を解析されることをお勧めします。
>
>
> > 回答ありがとうございます。
> >
> > > PWMのduty=0の出力は、保障外だと思いますが。
> > マニュアルに書いてありますか?
> > 英語が苦手なのでその箇所を教えていただければ幸いです。
> >
> > いままで、このプログラムでPWMは何度か使ってきましたが、
> > 今回初めて気が付いた次第です。
> >
> > 1.@が下位2bitが"11"以外ではduty=0になります。
> > 2.Aの実行後200uS待てばduty=800の次の周期にduty=0になります。
> > 3.duty=0が保障外のPWMって、使い物になりますか?
> >
> > > PWMをOFFにすればいいのでは

Re: PWMでDuty=0が実行されない 投稿者:PWM^2 投稿日:2017/03/30(Thu) 17:40:57 No.865

横から失礼します。
詳しくマニュアルを誰も親切には見ないでしょう。
PWMを単にOFFでいいものを、原因を知りたいというご意見でしたので、回答を控えていました。
8ビットの場合で考えてみれば、0が設定値としてOKなら最大値は255まで、0が値としてNGなら、値は1からなので最大値は256です。
どちらかで出来ているはずです。
前者の場合、ビットの基準が0=256の最大値を意味することも有り得るので、原因を知りたいのなら、0、1、255、256の値をそれぞれ代入してみて、結果がどう変わるか確認して下さい。
おそらく、255の時にPWMはOFF(duty=0)になるはずです。
8ビットの場合で説明しているので、16ビットであれば当てはめて考えて下さい。
もうひとつ、duty=0は厳密にはならないはずなので、きちんとオシロスコープで出力を解析されることをお勧めします。


> 回答ありがとうございます。
>
> > PWMのduty=0の出力は、保障外だと思いますが。
> マニュアルに書いてありますか?
> 英語が苦手なのでその箇所を教えていただければ幸いです。
>
> いままで、このプログラムでPWMは何度か使ってきましたが、
> 今回初めて気が付いた次第です。
>
> 1.@が下位2bitが"11"以外ではduty=0になります。
> 2.Aの実行後200uS待てばduty=800の次の周期にduty=0になります。
> 3.duty=0が保障外のPWMって、使い物になりますか?
>
> > PWMをOFFにすればいいのでは

USART受信プログラム[解決] 投稿者:radio 投稿日:2017/03/30(Thu) 16:30:32 No.864

nさま

色々アドバイスをいただき、ありがとうございます。
結論を申し上げます。

@AM送受信モジュール
1200Bauは、×
 (送信側のタイミング調整をすれば、少しは受信できるかもしれませんが)
 2400Bauは、ノイズが重畳しており、通信が途中で途切れる。
 ⇒これを解決するためには、USARTをリセットするしかないと思っていますが、試していません。

AXbeeモジュール
2400Bauでテストしたところ、有線と同じレベルで通信ができました。ノイズの重畳もなく、加速度センサを変化させても通信が途切れません。
 9600Bauは試していません。

とりあえずxbee(2400)通信ができたところで「解決」としました。
ただ、通信が途切れたときの「保険(リセット、再受信」は、これからも考えていきたいと思います。

ありがとうございました。

PWMでDuty=0が実行されない 投稿者:Qman 投稿日:2017/03/30(Thu) 13:44:27 No.863

回答ありがとうございます。

> PWMのduty=0の出力は、保障外だと思いますが。
マニュアルに書いてありますか?
英語が苦手なのでその箇所を教えていただければ幸いです。

いままで、このプログラムでPWMは何度か使ってきましたが、
今回初めて気が付いた次第です。

1.@が下位2bitが"11"以外ではduty=0になります。
2.Aの実行後200uS待てばduty=800の次の周期にduty=0になります。
3.duty=0が保障外のPWMって、使い物になりますか?

> PWMをOFFにすればいいのでは

Re: PWMでDuty=0が実行されない 投稿者:PWM 投稿日:2017/03/30(Thu) 12:22:58 No.861

PWMのduty=0の出力は、保障外だと思いますが。
PWMをOFFにすればいいのでは

PWMでDuty=0が実行されない 投稿者:Qman 投稿日:2017/03/29(Wed) 10:47:38 No.860

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

Re^11: USART受信プログラム 投稿者:n 投稿日:2017/03/28(Tue) 23:34:52 No.859

radioさん
nです。

@加速度センサを送信モジュールの基板からケーブルで離し、
送受信モジュールを適当な間隔で固定してください。
目的は、加速度センサのみを傾けて動作確認することです。

AUSARTをリセットできる関数があれば良いのですが。
(closeしてopenしなおせばリセットになるかもしれません)

B誤りの少ない通信には、Xbeeのほうが適しています。
(目的が異なれば、何が適するかも異なります)
(今回は「なぜそれではうまくいかないか」を学べたと思います)

トラブルはチャンスと考え、楽しみながら力をつけてください。

> nさま
>
> 返信ありがとうございます。
> 2400bau/有線の条件はまったく問題ありません。
> (1200bau/有線はまだ試しておりません。)
>
> 加速度センサの値の変化は、「送信基板を少しでも傾けたら」という表現となります。
> 受信側 PICマイコンのRX端子の信号をモニタ(オシロスコープ)していると、
> たまにノイズが重畳しています。これが原因なのでしょうか?
>
> いただいた回答から何点か教えていただきたいことがあります。
>
> @送信機と受信機のアンテナの結合状態はどのように調べることができるのでしょうか?
>
> Aノイズが入るたびにUSARTのエラーをリセットするプログラムを組むことは可能でしょうか?
> 今は、一度エラーになると、ハードリセット(PICマイコン1pinをリセット)しなければ、
> 通信を再開することができません。
>
> B参考サイトをまねてAM送受信モジュールを使ってみましたが、nさまがおっしゃるように
>  リモコンとして使うには難しい(または不向き)なのでしょうか?
> Xbeeの方が適していますか?
>
>
>
> [受信側]
> http://www.picfun.com/Sensor/equipj78.html

Re^10: USART受信プログラム 投稿者:radio 投稿日:2017/03/28(Tue) 17:03:05 No.858

nさま

返信ありがとうございます。
2400bau/有線の条件はまったく問題ありません。
(1200bau/有線はまだ試しておりません。)

加速度センサの値の変化は、「送信基板を少しでも傾けたら」という表現となります。
受信側 PICマイコンのRX端子の信号をモニタ(オシロスコープ)していると、
たまにノイズが重畳しています。これが原因なのでしょうか?

いただいた回答から何点か教えていただきたいことがあります。

@送信機と受信機のアンテナの結合状態はどのように調べることができるのでしょうか?

Aノイズが入るたびにUSARTのエラーをリセットするプログラムを組むことは可能でしょうか?
今は、一度エラーになると、ハードリセット(PICマイコン1pinをリセット)しなければ、
通信を再開することができません。

B参考サイトをまねてAM送受信モジュールを使ってみましたが、nさまがおっしゃるように
 リモコンとして使うには難しい(または不向き)なのでしょうか?
Xbeeの方が適していますか?



[受信側]
http://www.picfun.com/Sensor/equipj78.html

Re^9: USART受信プログラム 投稿者:n 投稿日:2017/03/28(Tue) 11:22:13 No.857

radioさん
nです。

2400baudで、有線だとどうなりますか?

1200baudではどうですか?
(25を51、103を207に変更)

「加速度センサの値の変化」とは、「送信基板の移動や振動」ですか?
そうならば、「電波の強さの変化」が主因かもしれません。
送信機と受信機のアンテナの結合状況を確認してください。
(A AMでは、電波の強さの変化はUSARTへの信号の変化です)

AM送信モジュールの採用自体が、リモコンの送信に適さないのでは?
(信号にノイズが含まれることを前提としたアルゴリズムが必要)
(ノイズが入るたびにUSARTのエラーをリセットする必要あり)
(@ 最初の1文字の誤りは、パワーON時のノイズの可能性あり)

> n様
>
> USARTの設定情報をお送りさせていただきます。
>
> [送信側]
> Clock=4MHz
>
> OpenUSART(USART_TX_INT_OFF&USART_RX_INT_OFF&USART_ASYNCH_MODE&USART_EIGHT_BIT&USART_CONT_RX&USART_BRGH_LOW,25 );
>
> [受信側]
> Clock=16MHz
>
> OpenUSART(USART_TX_INT_OFF&USART_RX_INT_OFF&USART_ASYNCH_MODE&USART_EIGHT_BIT&USART_CONT_RX&USART_BRGH_LOW,103 );
>
>
> 今の状況について説明させていただきます。
> 送信側で間隔を開けたり(↓のプログラムでdelay時間を調整)したりして試しています。
>
> ↓に掲載する送信プログラムで、ある程度※1通信し続けることを確認しました。
>
>
> 2つ分かったことがあります。
>
> @最初の文字'S'を受信できない。
> ↓の送信プログラムで、最初に'X'を送信しています。
> 'X'でなくても、最初に何らかの文字を送らないと、1文字目の'S'を受信してくれません。
>
> A※1
> ある程度というのは、送信側の加速度センサが少しでも変化してしまうと、通信が途切れます。
> 送信側で、送信間隔をあけてしまうと、加速度センサの変化に通信速度が追従できず…エラーになるのでしょうか?
>
> 私が今試しているのは、AM送信モジュールを使用して、2400bps通信ですが、
> 安定した通信を行うことができません。
>
> 何かアドバイスをいただけたらと思います。
> 少し手詰まりな感じがしてきました。
>
> [送信プログラム]
> //USART送信
> //delay_ms(100);
> WriteUSART('X');//putsUSART("S");同等
> delay_ms(15);
> WriteUSART('S');
> delay_ms(15);
> WriteUSART('S');
> delay_ms(5);
> WriteUSART(Direction);
> delay_ms(5);
> WriteUSART(MLdata >> 8);
> delay_ms(5);
> WriteUSART(MLdata & 0x00FF);
> delay_ms(5);
> WriteUSART(MRdata >> 8);
> delay_ms(5);
> WriteUSART(MRdata & 0x00FF);
> //delay_ms(5);
> WriteUSART(~Direction);
> delay_ms(5);
> WriteUSART(~(MLdata >> 8));
> delay_ms(5);
> WriteUSART(~(MLdata & 0x00FF));
> delay_ms(5);
> WriteUSART(~(MRdata >> 8));
> delay_ms(5);
> WriteUSART(~(MRdata & 0x00FF));
> delay_ms(5);
> WriteUSART('E');
> //delay_ms(1);

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |

- WebForum -