FC2ブログ
2018-06-27 13:51 | カテゴリ:PIC応用回路
さて、気を取り直して、「明日になり」、明るい日になりそうです。

PWM発生によるPIN割り込みが「うんともすんとも」言わなかった件ですが、まず、Nゲージ制御の出力を調べました。
出力が出ていません!?!?
前は出ていましたが!

結論から言いますと、PICの内部設定の論理回路(CLC)のPWMがORで出力する部分のもう一方の入力がオープンのまま(設定忘れ)で、ノイズなどの条件でLやHになり、PWM信号がゲートされたりされなかったりしていました。

これで、PWMがちゃんと出ました。(笑)


続きは、、、


さて、これでいけるかと思ったら、それでもピン入力からの割り込みがかかりません。
Nゲージ制御の出力はちゃんとPWM信号がでているのにです。
この信号をVRで電圧調整したうえで、PICの割り込みピンに入力しています。
この波形をオシロで見てみると、PWMの矩形波であるはずが、鈍った三角波(0.数V)になっています。(驚き!)
PWMの矩形波を半固定VRで電圧調整しただけなのに。

(NG302-01)
NG302-01.jpg

回路を再度念入りに確認しました。
有りました! 小さなコンデンサーが、隠れて取り付けてありました。
この端子は、BEMFの信号をADで受ける設定にしていましたので、ノイズ除去の目的手入れていました。
今回はデジタルなので、これを削り取りました。

(NG302-02)
NG302-02.jpg

そして、ようやく、AD、TMR0割り込み、PWM、ピン割り込みが正常に動作するところまでこぎつけました。
ここまで二日間かかりました(笑)

(NG302-03)
NG302-03.jpg


(NG302-04)
NG302-04.jpg



ついでに動画を撮りました。
左側の緑のLEDが点灯するとピンからの割り込みが入ったことを示します。

右の黄色は、タイマー0割り込みです。


(Video)



さて、気になることが一つ。
前回にLCDに文字や数字を表示させる関数を製作してそれを使用しているのですが、ちょっと設定が不便なので、もっと簡単にできるように改良しておくことにしました。

(現在の書式)
<文字>
LCD_Cursor(Adrs, 0, 0); 注:0,0は表示させる座標
LCD_Disp(Adrs, "ABCDE");


<数字>
numbers = 1234;
itoa(moji, numbers, 10);
LCD_Disp(Adrs, moji);


これを以下のような書式にしたいのです。

<文字>
LCD_C_Disp(0, 0, "ABCDE");

<数字>
 Numbers = 1234;
 LCD_N_Disp(0, 0, numbers);

文字と数字は関数を分けます。

考えたプログラムは、

//**************************************
// LCDに数字を表示
//**************************************

void LCD_N_Disp(int nx, int ny, int nd) {
itoa(moji, nd, 10);
LCD_Cursor(Adrs, nx, ny);
LCD_Disp(Adrs, moji);
 }


これはOK。

次に文字。
//**************************************
// LCDに文字を表示
//**************************************

void LCD_C_Disp(int cx, int cy, unsigned char*p) {
LCD_Cursor(Adrs, cx, cy);
LCD_Disp(Adrs, *p);
 }

これでいけると思いましたが、変な文字化けのデータが表示されるだけでした。
unsigned char*p で受け取った文字列の先頭ポインターをそのまま、 LCD_Disp(Adrs, *p) で渡しているだけなんですが。

WEBで色々参考の記事を探したのですが、どうも解決策が見当たりません。
で、いろいろ考えたのですが、*pは、変数pのポインターです。したがって、*pで受け取ったポインターをそのまま次の関数に引き渡すには、ポインターではなく、変数でよいのではないかと!

そこで、

LCD_Disp(Adrs, *p); の*をとって
LCD_Disp(Adrs, p);の様に

変数pにしたら正常に動作しました。
よかった!

と、今回はここまでで疲れてしまいました(笑)

ご参考までに、LCDへの表示関数をご紹介しておきます。
何かのお役に立てば幸いです。

プログラムは、Microchip社のMPLABXのXC8(Free版)です。


/******************************************
* i2cLCDに文字列を表示する
******************************************/
void LCD_Disp(unsigned char Adrs, unsigned char*p) {
IdleI2C();
SSP1CON2bits.SEN = 1; // スタート出力
while (SSP1CON2bits.SEN); // スタート終了待ち
SendByte(Adrs); // Sアドレスと送信モード送信
SendByte(MultiDat);
while (*p != '\0') {
SendByte(*p);
p++;
}
SSP1CON2bits.PEN = 1; // ストップ出力
while (SSP1CON2bits.PEN); // ストップ終了待ち

}

/*******************************************
* ディスプレイカーソルセット(x、y)
*******************************************/
void LCD_Cursor(unsigned char Adrs, int x, int y) {
unsigned pos;
pos = 0x40 * y + x;
pos |= 0x80;
IdleI2C();
SSP1CON2bits.SEN = 1; // スタート出力
while (SSP1CON2bits.SEN); // スタート終了待ち
SendByte(Adrs); // Sアドレスと送信モード送信
SendByte(SinglCmd);
SendByte(pos);
SSP1CON2bits.PEN = 1; // ストップ出力
while (SSP1CON2bits.PEN); // ストップ終了待ち

}

/***********************************
* 画面クリア
************************************/
void LCD_Clear(unsigned char Adrs) {
IdleI2C();
SSP1CON2bits.SEN = 1; // スタート出力
while (SSP1CON2bits.SEN); // スタート終了待ち
SendByte(Adrs); // Sアドレスと送信モード送信
SendByte(SinglCmd);
SendByte(0x01); //クリアリセット
SSP1CON2bits.PEN = 1; // ストップ出力
while (SSP1CON2bits.PEN); // ストップ終了待ち
}

関連記事

管理者のみに表示する