STM32F4Discovery-DCMIを介してカメラを接続します

STM32F4Discovery-DCMIを介してカメラを接続します





カメラを携帯電話からSTM32F407VGT6マイクロコントローラー( STM32F4Discoveryボード上で実行 )に接続すると、このコントローラーにはこのケース用の特別なハードウェアインターフェイスがあるとは思いもしませんでした。 データシートを不注意に読んだのかもしれませんが、144フィートのUFBGA176LQFPケースのチップのみにDCMIインターフェースがあるといつも思っていました。 しかし、それほど前ではないが、音声付きの詳細を発見しました。100フィートSTM32F407にはDCMIも搭載されています。

MKでさまざまなモバイルハードウェア(特にLCDやカメラ)を研究し、共同発売することの大ファンなので、そのような発見をすり抜けることができなかったため、STM32周辺機器の研究でこのギャップを埋めることにしました。 実際、この資料は、アイデアの実装の説明に専念しています。



ちょっとした理論。




まず第一に、それが何であるかを想像する必要があります-むしろ、CMOSカメラとは何か、それは何と一緒に食べられるのか。

このタイプのカメラは、センサーからの情報をデジタル形式(RGB、YCbCr、および圧縮形式-JPEG)で表示します。 さまざまなカメラは機能の点で独自のニュアンスを持っています。私は、 Siemens C72電話( PixelPlus PO2030Nセンサー)から太古の時代から引き出された小さな解像度(VGA、640x480)のカメラの非常に特殊なケースを検討します。 このカメラは、操作が簡単で、多かれ少なかれ一般的なタイプに属しているため、研究に最適です。 むかしむかし、I 2 Cバスに2.8 Vのスタビライザーとプルアップ抵抗を付けて、接続のために小さなボードをエッチングしました。 ここにあります(ケーブルとカメラコネクタはカバーの下に隠れています)。



画像



データ形式の分野でのニュアンスに加えて、カメラは同期リードの数の分野でも異なる場合があります。 ほとんどの(私の意見では)センサーには、特別なラインおよびフレーム同期の結論があります。 ただし、ピクセルストロボ出力しかないカメラがあり、特殊な送信コード(たとえば、 0x00または0xFF )を使用して、新しいライン/フレームの開始を知らせます。 利用可能なカメラには外部同期出力があります。

ブロックの形でカメラのおおよその概略画像を推定できます。







ほとんどの場合、CMOSカメラはI2Cインターフェイスを介して制御されます (ただし、 UARTによっても制御されるデバイスを見てきました)。 I2Cは、解像度、色域、出力データ形式などのさまざまなパラメーターを構成します。

EXTCLKの結論はカメラのクロッキングであり、外部から提供する必要があります。 DCLK-データがカメラデータバスに記録される前縁または後縁のストローブ信号(たとえば、マトリックスの1ピクセルのデータバイト、またはカメラがRGB565モードで動作している場合は「ハーフピクセル」のデータバイト)。 HSYNCは、新しいラインの始まりを示す水平同期信号です。VSYNCは、アクティブレベルが新しいフレームの始まりを示す同期信号です。 結論D0..D7-データバス。 原則として、このようなカメラでは8ビットです。

同期信号について詳しく説明します。







グラフは、カメラがアクティブなHSYNCフェーズでのみDCLK信号アクティビティ用に設定されていることを示しています(つまり、このフェーズは私たちにとって重要であり、「ラインフィード」期間中のクロック信号には興味がありません)。 カメラが320x240の解像度に設定されている場合、 DCLKの 320パルスが各HSYNCパルスの周期に適合し、240 HSYNCVSYNC周期に適合します

ズームインすると、データバスで何が起こっているかがわかります。







リーディングエッジ(この場合)では、1バイトがデータバスから削除されます。これは、表示のためにディスプレイに直接送信されるか、後続の処理のためにバッファに「入れられます」。



理論的には、 STM32マイクロコントローラーのDCMIインターフェースに関するすべてが多かれ少なかれ明確です。




DCMIインターフェイスは、最大14ビット幅のデータバスで動作し、ハードウェアとソフトウェアの両方の同期、およびデータ形式(YCbCr、RGB、JPEG)をサポートします。

さらに、 DCMIにはFIFOバッファーが含まれており、割り込み(データレジスタの入力を含む)を構成し、 DMAを介して作業を構成できます。







DCMI割り込みは、次の条件が発生したときにトリガーできます 。ライン終了、フレーム終了、受信バッファーオーバーフロー、同期エラー検出(内部同期あり)。

戸惑うことに、カメラクロック用の特別な出力がないことで私は紹介されました。 SGS Microelectronicsの開発者がそれを拒否した理由はわかりませんが、たとえば、カスタムクロックソースがあると非常に便利です。

個人的には、PWMモードに含まれる汎用タイマーカウンターを使用して、4 MHzの蛇行を生成しました。 もちろん、このようなクロック速度では大きなFPSを取得することはできませんが、すぐに予約します-使用するディスプレイはFSMCに接続されていないため、回路全体で最も長い機能はLCD出力機能です。したがって、より高い周波数では、画面への画像出力が失敗します。 したがって、アンロードする前にタイマーをオフにし、その後タイマーを再びオンにします。

DCMIハードウェアモジュールには、データレジスタに加えて、10個の制御/ステータスレジスタが含まれています。 制御レジスタ( DCMI_CR )、ステータスレジスタ( DCMI_SR )、割り込みステータスレジスタ( DCMI_RIS )、割り込みイネーブルレジスタ( DCMI_IER )、割り込みマスクレジスタ( DCMI_MIS )、割り込みフラグリセットレジスタ( DCMI_ICR )、内部同期コードレジスタ( DCMI_ESCR ) 、内部同期コードのマスクをリセットするためのレジスタ( DCMI_ESUR )、フレームの一部をキャプチャするときの開始値のレジスタ( DCMI_CWSTRT )、およびCropWindowモードのフレームのフラグメントの値のレジスタ( DCMI_CWSIZE )。 そして、もちろん、データレジスタはDCMI_DRです。

この場合、フレームの一部のキャプチャと内部同期に関連するレジスタは、私たちには関係ありません。 また、今のところ中断を残すことにしたので、 DCMI_CR制御レジスタDCMI_SRステータスレジスタのみをより詳細に検討する価値があります。



制御レジスタにより、カメラとの相互作用のフォーマットを完全にカスタマイズできます:データバスサイズ、 HSYNCおよびVSYNCラインのアクティブレベルなど。







順番に。 ENABLEビットは、もちろん、インターフェイスを含めることです。 フィールドEDM拡張データモード )-データバスサイズ。 カメラのバスは8ビットなので、このフィールドは「00」に設定する必要があります。 フィールドFCRCフレームキャプチャレート制御 )を使用すると、FPCをわずかに調整できます。00-すべての着信フレームがキャプチャされ、 01-1秒おきに フレーム、 10-4秒ごとにキャプチャされます。 VSPOLおよびHSPOLビットは、垂直および水平同期ラインのアクティブレベルです。 アクティブなレベルは無視され、アクティビティ期間中のデータはキャプチャされません。これを考慮する必要があります。 PCKPOL-ピクセルストローブのアクティブレベルのビット-バスからデータを読み取る信号のエッジ:フロントまたはバック。 ESS-同期方法の選択のビット:外部または内部。 JPEG-受信データの形式を選択します-圧縮されているかどうか。 CROP-フレームフラグメントのキャプチャを選択するビット( トリミングウィンドウ )。 このビットが1に設定されている場合、インターフェイスは、 DCMI_CWSTRTおよびDCMI_CWSIZEレジスタの値によって決定されるウィンドウのデータをキャプチャします。



だから、カスタマイズ可能。


私はSTの標準周辺機器ライブラリを使用することに慣れているため(「ペン」でレジスタをさらに掘り下げるまで、新しい周辺機器を使用する最初の反復では使用しませんが)、ライブラリを使用して設定を行います。



void DCMIInitialRoutine(void) { DCMI_InitTypeDef DCMI_CamType; DCMI_DeInit(); DCMI_CamType.DCMI_CaptureMode = DCMI_CaptureMode_Continuous; DCMI_CamType.DCMI_CaptureRate = DCMI_CaptureRate_All_Frame; DCMI_CamType.DCMI_ExtendedDataMode = DCMI_ExtendedDataMode_8b; DCMI_CamType.DCMI_SynchroMode = DCMI_SynchroMode_Hardware; DCMI_Init(&DCMI_CamType); DCMI_CaptureCmd(ENABLE); DCMI_Cmd(ENABLE); return; }
      
      





実際、私のニーズのために、 DCMI_CRレジスタの1ビットに触れないようにすることができました-デフォルトでは、 CAPTUREおよびENABLEビットを除き、リセットされます。

インターフェイスが構成され、準備ができました。 カメラにクロック信号を適用すると、インターフェイスは処理が必要なデータの受信を開始します。

まず、タスクを可能な限り単純に設定します。ディスプレイに画像を表示して、データ処理が最小限になるようにします。

受信バッファからのデータのタイムリーな読み取りでは、ステータスレジスタDCMI_SRが役立ちます。







読み取りに使用できるビット数は非常に少ないため、3ビットのみです。 HSYNCおよびVSYNCビットは、対応するラインのステータスを通知します。アクティブフェーズまたはラインフィード。 最も興味深いのはFNEビットです。 バッファをデータで埋めるように指示します。 または記入しません。

一定のサイクルでDCMI_SRFNEビットの状態を確認すると、32ビットの受信バッファーにデータが到着したことがわかります。 私の場合、データは次のように配置されます。







FNEビットが設定れると、受信バッファーのDCMI_SRステータスレジスタには4つのバイト、2つの隣接ピクセルのデータが含まれます: Byte0Byte1-ピクセルnの 16ビット、 Byte2Byte3-ピクセルn + 1の 16ビット。 それらを組み合わせて表示用に送信するだけです。 メインループは次のようになります。

 while (1) { while ((DCMI_GetFlagStatus(DCMI_FLAG_FNE)) == RESET); //Waiting for the buffer TIM_Cmd(TIM3, DISABLE); //Disable CAM clock cam_grab = (DCMI->DR); //Reading buffer SendDataByte_LCD (cam_grab); cam_grab = (DCMI->DR)>>16; //Reading 2nd part of the buffer SendDataByte_LCD (cam_grab); TIM_Cmd(TIM3, ENABLE); //Enable CAM clock again }
      
      





つまり、 DCMI_SRステータスレジスタFNEビットが設定されるのを待ち 、その後16ビットのデータを2 パスでディスプレイにアップロードします。

この時点で、論理的な結論に達したいと思いますが、そうでした。

ディスプレイでMKを点滅させて再起動した後、私は見ました...いいえ、私は自分の身近な物理学を見ましたが、黒と青の色合いで見ました。 赤と緑の色は完全に欠けていました。

デバッガーで簡単に逆アセンブルした後、次のことが発見されました。インターフェイスデータレジスタには、1ピクセルのデータが16ビットのみ含まれ、下位8ビットはByte0 (上図を参照)、最古はByte2にあります。 スペースByte1およびByte3は空でした。 今まで、私は現実の記録間の矛盾がどこから来たのか理解しておらず、STMに目を向けることがあります。

その結果、 DCMIインターフェースを使用してカメラから画像を取得することができましたが、多少の困難はありました。 図では、カメラのSTM32F3Discoveryデモボードの画像が表示されたディスプレイの写真を示しています。







ロジックアナライザーを接続した場合のEXTCLKPIXCKHSYNC 、およびVSYNCの出力に表示されるものを次に示します。







すべてが期待どおりに見えます。240個のHSYNCパルスが1つのVSYNCの持続時間に収まり、320 PIXCK -1つのHSYNCに 収まります。 HSYNCのアクティブフェーズでは、カメラは設定されたとおりにPIXCK信号を出力しません。

一般的に言って、インターフェースは私をいくらか失望させました。 カメラをクロックするための「通常の」足の欠如、興味深い組み込みチップの欠如(ハードウェアJPEGエンコーダーについてはどうでしょうか?)、さらに半分のFIFOでタンバリンと踊る...

PIXCKHSYNC 、およびVSYNC割り込みでカメラを使用して作業を整理しましたが、ハードウェアDCMIを使用してカメラを操作していましたが、これほどバントはありませんでした。

それでも、近い将来、フレームをキャプチャしてJPEGで圧縮し、SDカードに画像を書き込もうとします。

PS。 念のため、「 Code :: Blocks 」のプロジェクトへのリンクを提供します-それは突然誰かに役立つでしょう。



www.dropbox.com/sh/nfjdwqsdzlr7djm/9v2mQM8uYV



All Articles