「Minika 1101F」のMSP430 + LCD

画像

私の同僚が「MSP430」タグで記事を書いているように、このマイクロコントローラの私の知り合いは、テキサス・インスツルメンツに基づいたメモMSP430開発者キットから始まりました。 注文したキットは5日で届きました。 その後、LED「Hello、World」と...アイデアと時間の不足のためにロッカーに戻されました...

...しかし、倉庫内で未使用のチケットオフィス「Minika 1101F」が見つかった。 子供の頃から、よくある質問「中身は何ですか?」



内部では、マジックナンバー5.104.704のボードでIZhC13-8 / 7-01 LCDが検出されました。

これがこのボードの外観です
画像画像






テーマ別フォーラムをスクロールすると、 回路基板の概念に出会いました。

ボードは両面で、2つのKR1820VG1マイクロ回路で構成されています(はい、2つのうちすべて正しいです-図には4つありますが、ボードにインストールされていない要素のリストが示されています)。 このチップは、Texas Instruments COP472-3チップの完全なアナログです。 データシートを持ってきます。 ソビエト(またはロシア語?)デザイナーがそれさえクローンしたことに再び驚きまし

各マイクロサーキットは、インジケーターの4つのデジタル桁を制御できます(このインジケーターは8桁です)。 したがって、マイクロ回路の1つが4つの上位ビットを担当し、もう1つが下位の4つのビットを担当します。

また、エンジニアは、悪名高いK561LN2で収集されたインバーターを介してすべての信号を「通過」させました(理由-私は理解できませんでした。



接続



LCDモジュールは、6ピンX7コネクタでキャッシュレジスタのメインボードに接続されました。 ここで、コネクタにあるコンタクトの順序を再確認する必要がありました。

導体がどこに向かっているかを見て、MSP430への接続図を描きました。 画像

ポートMSP430G2553はトレースに関係します。 方法:



アルゴリズム



KR1820VG1超小型回路の動作アルゴリズムは、1990年の有名な記事で、 レオニードイバノビッチリディコカークロック温度計-電圧計によって説明されています。 また、インターネットで、ジャーナルELECTRONICSの有用なスキャンが見つかりました:Science、Technology、Business 5/2007



次の図は、カスケードモードでの2つのKR1820VG1超小型回路の動作を示しています。 これはまさに私たちが使用しているものです。

画像



サービスビットセットの名前は、ここでは「ジュニア1/2」と「シニア」です。 画像

カスケードのVG1のアルゴリズムについて説明します。 「ボード操作アルゴリズム」を書くことは可能ですが、そうではありません。 すべてのボード入力にインバータをはんだ付けしたことを忘れないでください。

作業は、1)初期化と2)実際には動作モードで構成されます。

トレースが初期化されます。 方法:

1)両方のチップで設定します^ CS1,2 = 0;

2)32ビットのデータをライン「D」に渡します。

3)4ビットの特別なセグメントを提供します(このインジケーターでは、これらは数字の上にダッシュがあります)。

4)4つの制御ビット0111を発行します(表を参照してください。「BEST1」)。

5)両方のチップで設定します^ CS1,2 = 1;

6)シニアチップを選択^ CS2 = 0、データを受信します。

7)32ビットのデータを「D」ラインに渡します。 4ビットの特別なセグメントを提供します。 4つの制御ビット1000を出力します(表の「SENIOR」を参照)。

8)^ CS = 0。

初期化コードは次のようになります
/* *  LCD */ void initLCD(){ P1OUT |= CS1+CS2; //      ~CS  "0" // ( -  ,     "1") //       spi_IO(0); spi_IO(0); spi_IO(0); spi_IO(0); // 4   spi_IO(0x07); // 4   + 4  P1OUT &= ~(CS1 + CS2); //  ~CS=1    (   ) P1OUT |= CS2; //  ~CS=0   -      spi_IO(0); spi_IO(0); spi_IO(0); spi_IO(0); //  4  spi_IO(0x08); // 4   + 4  P1OUT &= ~(CS2 + CS1); //  ~CS=1 (!) }
      
      





便利な機能
 /* "1"    */ void bit1() { P1OUT &= ~D; P1OUT &= ~CLK; P1OUT |= CLK; } /* "0"    */ void bit0() { P1OUT |= D; P1OUT &= ~CLK; P1OUT |= CLK; } /*      */ void spi_IO( unsigned int data ) { unsigned int i; for( i = 0; i < 8; i++ ) { //      if( data & 0x80 ) bit1(); else bit0(); data <<= 1; } }
      
      





チップは動作モードに入ります。

ここで、データを上位/下位4デジタル桁(つまり、上位/下位チップ)に書き込むには、目的のチップを選択してすぐに書き込むことができます。

作業モード:

1)必要なチップを選択(最年少^ CS1 = 0または最高^ CS2 = 0);

2)32ビットのデータを送信します。

3)4ビットの特別なセグメントを送信します。

4)4つの制御ビット(最年少の「BEST2」の場合は0110、上級の場合は1000)を送信します。

5)チップ(項目1で選択されたチップ= 1)を「選別しています」。

トレイルを厳密に判断しないでください。 コードの一部。 最適化および最適化できますが、記事の目的はそれではありません:)

文字列出力を表示する
 /* *    * data -  * n -   * dot -   () */ void print_LCD( char data[], char n, char dot ) { unsigned char copy[8]; unsigned char i; if(n<1) return ; if(n>8) n=8; for( i = 0; i < 8; i++ ) if(i+1>n) copy[i] = ' ' ; else copy[i] = data[i]; //  //   4  P1OUT |= CS1; for(i=0;i<4;i++){ if( dot & 0x80 ) spi_IO(char2byte(copy[i])+0x80); else spi_IO(char2byte(copy[i])); dot <<= 1; } // 4  ,   ( ) bit0(); bit0(); bit0(); bit0(); //   bit0(); bit1(); bit1(); bit0(); P1OUT &= ~CS1; //   4  P1OUT |= CS2; for(i=4; i<8; i++){ if( dot & 0x80 ) spi_IO(char2byte(copy[i])+0x80); else spi_IO(char2byte(copy[i])); dot <<= 1; } // 4  ,   ( ) bit0(); bit0(); bit0(); bit0(); //   bit1(); bit0(); bit0(); bit0(); P1OUT &= ~CS2; }
      
      





これで、個々のセグメントを強調表示できます。 しかし、これはまったく面白くないので、キャラクタージェネレーターが必要です!



サインジェネレーター



この図では、コードパッケージのビットの順序を確認しています(アルゴリズムの段落2を参照)。

画像

そして、これは典型的なLCD配線図です(ただし、「K」は数字の上にあり、ここでは下にあります)。

画像

文字ジェネレータのコードでは、すべてがケースを通り抜けています。私は謝ります:)

キャラクタージェネレーターコード
 /* *       */ int char2byte( char ch ){ switch(ch){ case '1' : return 0x06; case '2' : return 0x5B; case '3' : return 0x4F; case '4' : return 0x66; case '5' : return 0x6D; case '6' : return 0x7D; case '7' : return 0x07; case '8' : return 0x7F; case '9' : return 0x6F; case 'O' : case 'o' : case '0' : return 0x3F; case 'a' : case 'A' : return 0x77; case 'b' : case 'B' : return 0x7C; case 'c' : case 'C' : return 0x39; case 'd' : case 'D' : return 0x5E; case 'e' : case 'E' : return 0x79; case 'f' : case 'F' : return 0x71; case '-' : return 0x40; case ' ' : return 0x00; case 'p' : case 'P' : return 0x73; case 'g' : case 'G' : return 0x31; case 'l' : case 'L' : return 0x38; case 'h' : case 'H' : return 0x76; case 'y' : case 'Y' : return 0x38; case 'r' : case 'R' : return 0x50; case 'u' : return 0x1C; case 'U' : return 0x3E; case '|' : return 0x30; case '~' : return 0x01; //   case '_' : return 0x08; //  case '=' : return 0x09; //    case 'j' : return 0x21; //    (      - //   jkmn  ) case 'k' : return 0x03; //    case 'm' : return 0x0C; //    case 'n' : return 0x18; //    default: return 0x00; } }
      
      





次に、いくつかのデモ関数が作成されました。これらは記事の最後のリンクで見ることができます。



あとがき



LCDボードは5Vで動作します。 MSP430ランチパッドでは、3.3Vのみが配線されます。 それらから、ボードも動作しますが、非常に退屈です。 おそらく、抵抗R3 *を選択することで必要な明るさを実現できますが、USB入力でピンをはんだ付けし、5Vを削除しても機能します:)



また、このボードでは、数字の上位4セグメントが右側にあり、若いセグメントが左側にあることに注意してください。



完全なファームウェアコードは、 ここからダウンロードできます。
見るために
 #include <msp430g2553.h> #define CS1 BIT1 //    #define CS2 BIT2 //    #define CLK BIT5 //  #define D BIT7 //   char flag_next=0; //      (   ) /* "1"    */ void bit1() { P1OUT &= ~D; P1OUT &= ~CLK; P1OUT |= CLK; } /* "0"    */ void bit0() { P1OUT |= D; P1OUT &= ~CLK; P1OUT |= CLK; } /* *  ( ) */ void delay( unsigned int ms) { while (ms--) __delay_cycles(16000); } /*      */ void spi_IO( unsigned int data ) { unsigned int i; for( i = 0; i < 8; i++ ) { //      if( data & 0x80 ) bit1(); else bit0(); data <<= 1; } } /* *       */ int char2byte( char ch ){ switch(ch){ case '1' : return 0x06; case '2' : return 0x5B; case '3' : return 0x4F; case '4' : return 0x66; case '5' : return 0x6D; case '6' : return 0x7D; case '7' : return 0x07; case '8' : return 0x7F; case '9' : return 0x6F; case 'O' : case 'o' : case '0' : return 0x3F; case 'a' : case 'A' : return 0x77; case 'b' : case 'B' : return 0x7C; case 'c' : case 'C' : return 0x39; case 'd' : case 'D' : return 0x5E; case 'e' : case 'E' : return 0x79; case 'f' : case 'F' : return 0x71; case '-' : return 0x40; case ' ' : return 0x00; case 'p' : case 'P' : return 0x73; case 'g' : case 'G' : return 0x31; case 'l' : case 'L' : return 0x38; case 'h' : case 'H' : return 0x76; case 'y' : case 'Y' : return 0x38; case 'r' : case 'R' : return 0x50; case 'u' : return 0x1C; case 'U' : return 0x3E; case '|' : return 0x30; case '~' : return 0x01; //   case '_' : return 0x08; //  case '=' : return 0x09; //    case 'j' : return 0x21; //    (      - //   jkmn  ) case 'k' : return 0x03; //    case 'm' : return 0x0C; //    case 'n' : return 0x18; //    default: return 0x00; } } /* *    * data -  * n -   * dot -   () */ void print_LCD( char data[], char n, char dot ) { unsigned char copy[8]; unsigned char i; if(n<1) return ; if(n>8) n=8; for( i = 0; i < 8; i++ ) if(i+1>n) copy[i] = ' ' ; else copy[i] = data[i]; //  //   4  P1OUT |= CS1; for(i=0;i<4;i++){ if( dot & 0x80 ) spi_IO(char2byte(copy[i])+0x80); else spi_IO(char2byte(copy[i])); dot <<= 1; } // 4  ,   ( ) bit0(); bit0(); bit0(); bit0(); //   bit0(); bit1(); bit1(); bit0(); P1OUT &= ~CS1; //   4  P1OUT |= CS2; for(i=4; i<8; i++){ if( dot & 0x80 ) spi_IO(char2byte(copy[i])+0x80); else spi_IO(char2byte(copy[i])); dot <<= 1; } // 4  ,   ( ) bit0(); bit0(); bit0(); bit0(); //   bit1(); bit0(); bit0(); bit0(); P1OUT &= ~CS2; } /* *  LCD */ void initLCD(){ P1OUT |= CS1+CS2; //      ~CS  "0" // ( -  ,     "1") //       spi_IO(0); spi_IO(0); spi_IO(0); spi_IO(0); // 4   spi_IO(0x07); // 4   + 4  P1OUT &= ~(CS1 + CS2); //  ~CS=1    (   ) P1OUT |= CS2; //  ~CS=0   -      spi_IO(0); spi_IO(0); spi_IO(0); spi_IO(0); //  4  spi_IO(0x08); // 4   + 4  P1OUT &= ~(CS2 + CS1); //  ~CS=1 (!) } /* *   */ void clear_LCD() { print_LCD( " " , 8, 0); //       -     } /* *  */ void demo() { int demo_n = 1; while(1){ switch(demo_n){ case 0:{ int ms=50; while(1){ print_LCD("~~ " ,8,0); delay(ms); print_LCD(" ~~ " ,8,0); delay(ms); print_LCD(" ~~ " ,8,0); delay(ms); print_LCD(" ~~ " ,8,0); delay(ms); print_LCD(" ~~ " ,8,0); delay(ms); print_LCD(" ~~ " ,8,0); delay(ms); print_LCD(" ~~" ,8,0); delay(ms); print_LCD(" k" ,8,0); delay(ms); print_LCD(" 1" ,8,0); delay(ms); print_LCD(" m" ,8,0); delay(ms); print_LCD(" __" ,8,0); delay(ms); print_LCD(" __ " ,8,0); delay(ms); print_LCD(" __ " ,8,0); delay(ms); print_LCD(" __ " ,8,0); delay(ms); print_LCD(" __ " ,8,0); delay(ms); print_LCD(" __ " ,8,0); delay(ms); print_LCD("__ " ,8,0); delay(ms); print_LCD("n " ,8,0); delay(ms); print_LCD("| " ,8,0); delay(ms); print_LCD("j " ,8,0); delay(ms); if(flag_next==1) { demo_n=1; flag_next=0; break; } } } case 1:{ clear_LCD(); while(1){ print_LCD( " H" , 8, 0); delay(200); print_LCD( " HE" , 8, 0); delay(200); print_LCD( " HEL" , 8, 0); delay(200); print_LCD( " HELL", 8, 0); delay(200); print_LCD( " HELLO", 8, 0); delay(200); print_LCD( " HELLO ", 8, 0); delay(200); print_LCD( " HELLO ", 8, 0); delay(1000); print_LCD( "HELLO ", 8, 0); delay(200); print_LCD( "ELLO ", 8, 0); delay(200); print_LCD( "LLO " , 8, 0); delay(200); print_LCD( "LO " , 8, 0); delay(200); print_LCD( "O " , 8, 0); delay(200); print_LCD( " H" , 8, 0); delay(200); print_LCD( " HA" , 8, 0); delay(200); print_LCD( " HAB" , 8, 0); delay(200); print_LCD( " HABR", 8, 1); delay(200); print_LCD( " HABRR", 8, 2); delay(200); print_LCD( " HABRRu", 8, 4); delay(200); print_LCD( " HABRRu ", 8, 8); delay(1000); print_LCD( "HABRRu ", 8, 16); delay(200); print_LCD( "ABRRu ", 8, 32); delay(200); print_LCD( "BRRu ", 8, 64); delay(200); print_LCD( "RRu " , 8, 128); delay(200); print_LCD( "Ru " , 8, 0); delay(200); print_LCD( "u " , 8, 0); delay(200); if(flag_next==1) { demo_n=2; flag_next=0; break; } } //while } case 3:{ clear_LCD(); int ms=50; while(1){ print_LCD( "~~~~~~~~",8,0); delay(ms); print_LCD( "kkkkkkkk ",8,0); delay(ms); print_LCD( "11111111",8,0); delay(ms); print_LCD( "mmmmmmmm ",8,0); delay(ms); print_LCD( "nnnnnnnn ",8,0); delay(ms); print_LCD( "||||||||",8,0); delay(ms); print_LCD( "jjjjjjjj ",8,0); delay(ms); if(flag_next==1) { demo_n=0; flag_next=0; break; } } } } } } /* * main.c */ void main( void) { //   WDTCTL = WDTPW + WDTHOLD; //   -   delay() BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; // These are the pins we need to drive. P1DIR |= CLK + D + CS1 + CS2; P1SEL &= ~BIT3; //  1.3    P1DIR &= ~BIT3; // Port 1 P1.3 (push button) as input, 0 is input P1REN |= BIT3; //   P1IE |= BIT3; //     P1IFG &= ~BIT3; //    delay(500); // ,     initLCD(); //  LCD __bis_SR_register(GIE); //    demo(); //   } #pragma vector=PORT1_VECTOR __interrupt void Port_1( void) { P1IFG &= ~BIT3; //    flag_next=1; //      }
      
      



かすかな心を覗かないでください。



さて、仕事の小さなビデオ





非常に興味深いヒント、コメント、コメント!

誰かがこの情報が役立つことを願っています。

ありがとう、また会いましょう。



PSそしてまたMinikのようなクールなサーマルプリンター...;)



All Articles