LPC1114FN28で同一ポート群から別々にデジタル出力する場合に出力波形が乱れることがあります。この現象を確認するためのテストプログラムです。

Dependencies:   mbed

LPC1114FN28 でのデジタル出力について

LPC1114FN28でデジタル出力をする場合、同一ポート群に対して、個別出力をすると他方の出力に影響を与えます。

<サンプルプログラムの説明>
PIO1_xのポート群(dp13(PIO1_4),dp14(PIO1_5))で確認しました
Tickerで0.1ms周期割り込みでレベル反転(dp14)させ、main()でdp13から固定レベル出力させます。
main()でLo出力しているとき、割り込みで出力させているパルスが乱れます。

main()でHi出力させているときは、パルスは乱れません。
プログラムの 19行目の"NG_LEVEL"define定義を無効にするとこのプログラムになります。

dp13(PIO1_4)をdp1(PIO0_8)の別ポート群にするとパルスは乱れません。
プログラムの18行目の"NG_PORT"define定義を無効にするとこのプログラムになります。

LPC1768(青mbed)では、上記の様な現象は発生しません(P2xポート群(P21(P2.5),P22(P2.4)で確認)
プログラムの17行目の"LPC1114FN28"define定義を無効にして、コンパイラの設定をLPC1768にするとこのプログラムになります。

main.cpp

Committer:
suupen
Date:
2013-10-28
Revision:
1:bf75eed34e82
Parent:
0:01c0ed9b80c5

File content as of revision 1:bf75eed34e82:

/*
LPC1114FN28でデジタル出力をする場合、同一ポート群に対して、個別出力をすると他方の出力に影響を与えます。

<サンプルプログラムの説明>
PIO1_xのポート群(dp13(PIO1_4),dp14(PIO1_5))で確認
Tickerで0.1ms周期割り込みでレベル反転(dp14)させ、main()でdp13から固定レベル出力させます。
main()でLo出力しているとき、割り込みで出力させているパルスが乱れます。

main()でHi出力させているときは、パルスは乱れません。
dp13(PIO1_4)をdp1(PIO0_8)の別ポート群にするとパルスは乱れません。
mainでのパルス出力を割り込み禁止にするとパルスは乱れません。

<結論>
割り込みとmainの双方で同一ポート群へのデジタル出力をすると出力レベルが異常になる場合がある。
これは、ポート出力処理のbit演算でメモリからの読み出し、書き込みが重複するためと思われる。
回避方法は、mainルーチンでのデジタル出力時に割り込み禁止にすること。


LPC1768(青mbed)では、上記の様な現象は発生しません(P2xポート群(P21(P2.5),P22(P2.4)で確認)

131028 mainでの割り込みと結論を追記
*/

#include "mbed.h"

#define LPC1114FN28         // 無効時LPC1768設定になります
#define NG_PORT             // 無効時、mainでの出力を別ポート群にします
#define NG_LEVEL            // 無効時、mainでの出力をHiにします
//#define OK_IRQ              // 有効時mainでの出力時に割り込み禁止にする(波形の乱れは無くなる)

#ifdef LPC1114FN28

#ifdef NG_PORT 
    DigitalOut out(dp13);
#else //~NG_PORT
    DigitalOut out(dp1);
#endif // NG_PORT

    DigitalOut test(dp14);

#else // ~LPC1114FN28 (LPC1768)
    DigitalOut out(p22);
    DigitalOut test(p21);
#endif // LPC1114FN28
    
    Ticker timer;
    
    void attime(){
        test = !test;
    }


   int main() {
        timer.attach_us(&attime, 100);

  

        while(1) {
#ifdef NG_LEVEL
#ifdef OK_IRQ 
           __disable_irq();     // Disable Interrupts
#endif // OK_IRQ
            out = 0; 
#ifdef OK_IRQ
            __enable_irq();     // Enable Interrupts
#endif // OK_IRQ
#else // ~NG_LEVEL
          out = 1; 
#endif // NG_LEVEL
        }
    }