ATmegaでのws2812bプロトコルの実装

LED ws2812bは非常に興味深いものです。 今、彼らの仕事のプロトコルの実装についてお話したいと思います。 前の記事のように、コードは16 MHzクオーツを備えたATmega32マイクロコントローラーの下のIAR環境で書かれています。 16 MHz未満のクォーツでは十分でない可能性が高いことをすぐに明確にしたいと思います。このプロトコルは非常に厳しいタイミング用に設計されています。 ゼロは、0.4μsの時間間隔、0.8μsの単位で設定されます。











まず、0と1を1行に配置する関数を作成します。 関数のnopの数は、論理アナライザーを使用して実験的に選択されます。 スクリーンショットは少し下に添付されています。



#define ClearOutBit PORTC &= ~(1<<1) //0   #define SetOutBit PORTC |= 1<<1 //1   void Set0( void ) //     ~0.4  { SetOutBit; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); ClearOutBit; //     ,     ,      } void Set1( void ) //     ~0.85  { SetOutBit; asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop");asm("nop"); ClearOutBit; //     ,     ,      }
      
      





次に、値の配列があります。 30個の値の32ビット配列を作成しました(はい、これはやり過ぎだと理解していますが、この解決策は受け入れられるように思えました)。 各LEDについて、24ビットをダウンロードする必要があります。最初の値は緑、次に赤、青の行にアップロードされます。







30個すべてのLEDに値の行を設定するのに必要なコントローラーの時間は4ミリ秒以下で、十分に高速です。 もちろん、クロック周波数を上げると、ビット間の時間を少し増やすことができます。 理想的には、30個のLEDのすべての時間間隔が一定であれば、ダウンロードは1ミリ秒未満続きます。



 unsigned long int mas[30]; //32    30  void setMas( void ) //     { unsigned long int a; unsigned int j,i; for (j=0; j<30; j++) { //  30 a = 0x1000000; //  G (Hi->Low),  R  B for (i=0;i<24;i++){ //  G,R,B a=a>>1; if ((mas[j]&a)==0x00000000) { Set0(); // } else { Set1(); // } } } }
      
      





実際、0.4および0.8μsの「高電圧時間」時間間隔のみが維持されますが、「低電圧時間」はプログラムによって制御されません。これらは、値をインラインに入れる間のマイクロコントローラーの動作により取得されます。 結局のところ、彼は状態を確認し、サイクルをスクロールする時間が必要です。 それでも、LEDはパッケージを適切にキャッチします。 そしてもちろん、この時間は50μsを超えてはなりません。そうしないと、LEDはそれをリセットとして受け取り、受信した「不完全な」値をディスプレイにロードします。









記事の最後に、 NECプロト​​コルを使用したIRリモートコントロールを介したタイマーおよび制御によるソースアレイの循環シフトを伴うこれら30個のLEDの動作のビデオがあります 。 楽しかった。






All Articles