树莓派+STM 32人颜认识门禁システム(下)----STM 32部分


このプロジェクトの最後のブログもずいぶん長引いて、復習を始めた頃から期末試験が終わって家に帰ったので、今日は急いでそれを終わらせて、このプロジェクトを正式に終わらせました.
STM 32部は、キー制御、LCD 2004表示、舵機制御、データの記憶、ベリーパイとの通信、RTCクロックの6つの小さなモジュールに分けられる.
キーコントロール
本システムでは4*4マトリクスキーボード、8ピン、行列をそれぞれスキャンして押したキー値を取得しています.駆動は簡単ですが、ボタン制御の解決策は信号量の使用と入力を完全に待つ2つの方法です.例えば、モード選択、確認キーの押下、リターンブラシなどの機能を実現する上でボタンを押すと信号量が発行され、タスクの同期が行われる.パスワード入力部では、パスワードが限界を超えたり、確認キーを押したり、終了キーを押したりしない限り、完全に待機する方法を使用します.
パブリッシング信号量コード信号量
mode=KEY_Scan(0);									//    
if(mode!=0)
{
	switch(mode)
	{
		case KEYA_PRESS:
			//printf("Mode A\r
"); OSSemPost(&MODE_A_SEM,OS_OPT_POST_1,&err);// A break; case KEYB_PRESS: //printf("Mode B\r
"); OSSemPost(&MODE_B_SEM,OS_OPT_POST_1,&err);// B break; case KEYC_PRESS: //printf("Mode C\r
"); OSSemPost(&MODE_C_SEM,OS_OPT_POST_1,&err);// C break; case KEYD_PRESS: //printf("Mode D\r
"); OSSemPost(&MODE_D_SEM,OS_OPT_POST_1,&err);// D break; default: break; } }

LCD 2004表示
私が使用しているLCD 2004はシリアルインタフェース、IICドライバ、32のハードウェアIICを使用していますが、使用は簡単で、ドライバは文字列と数字を表示する関数を提供しています.
コードの例:
    LCDI2C_clear();
	LCDI2C_Show_String(5,0,"SMATA DOOR");
	LCDI2C_Show_Num(1,1,4,calendar.w_year);
	LCDI2C_Show_Num(6,1,2,calendar.w_month);
	LCDI2C_Show_Num(9,1,2,calendar.w_date);
	LCDI2C_Show_Num(13,1,2,calendar.hour);
	LCDI2C_Show_Num(16,1,2,calendar.min);
	LCDI2C_Show_String(5,1,"/");
	LCDI2C_Show_String(8,1,"/");
	LCDI2C_Show_String(15,1,":");
	LCDI2C_Show_String(2,2,"A:Face");
	LCDI2C_Show_String(12,2,"B:Pwd");
	LCDI2C_Show_String(2,3,"C:Visit");	
	LCDI2C_Show_String(12,3,"D:Root");	

かじとりせいぎょ
リアルタイム性を考慮して、PIDの計算をベリーパイの上に置いた.ベリーパイはシリアルポートを通じて32に返されたのはPWMの制御量であり、2つのPWMはデューティ比を変えることで舵機のステアリングを制御した.
データの保存
実はこれが私がこのプロジェクトの中で最も面白いと感じた部分で、私はもともとSPI FLASHあるいはEEPROMを使って開門情報とIDとパスワード情報を記憶するつもりでしたが、すべてのコードをダウンロードして40 K+のFLASH容量を使ったのを見て、私はチップのFLASHの後半を使って情報を記憶して、F 103 C 8 T 6マニュアルには64 KのFLASH容量と書かれています.しかし、いくつかの技術的な理由で(私はブログで*アドレス*)利用可能な空間が大きいので、情報を保存するのは余裕があります.私が保存しているのは開門者ID(U 8タイプ)、開門方式(U 8タイプ)、開門時間(時分秒、3*U 8タイプ)、開門日だけです.(年月日、3*u 8タイプ)、一度に開くと8バイトのデータしかありません.
パスワードと開門記録について私が使っている方法は、前の位置に保存データの数を保存し、後ろの位置にデータを保存し始めます.このような動作の利点は、数を読み出してから数に基づいてデータを読み取ることができ、データをゼロにするにはセクタを消去する必要がない場合は、数値を0と書けばよいということです.
コードの例:
//  FLASH     (     ,            FLASH   +0X08000000)
#define FLASH_PWD_NUM_ADDR  0X0800B000		//     ID  
#define FLASH_PWD_ADDR	0X0800B100			//  ID       
#define FLASH_SAVE_ADDR  0X08010000			//      
#define FLASH_DATE_SAVE_ADDR 0X08010100		//        
/****************************************************************************************/
/*                                                                          		*/
/*  :                                                                          */
/*   :                                                                              */
/*  :                                                                        	    */
/*     :     			2018.12.10	                                              	*/
/*		                                                                     			*/
/****************************************************************************************/
void Data_storage(u8 data_to_storage[8])
{
	u16 date_num;
	date_num=STMFLASH_ReadHalfWord(FLASH_SAVE_ADDR);//           
	STMFLASH_Write(FLASH_DATE_SAVE_ADDR+date_num*8,(u16 *)data_to_storage,DATE_SIZE);//       
	date_num++;//     
	STMFLASH_Write(FLASH_SAVE_ADDR,&date_num,1);//      
}

ベリーパイとの通信
この部分は言うまでもなく、以前Pythonのpackメソッドを使ってデータをパッケージして送信する方法を書いたことがあります.32端の解析もはっきりしています.私のブログ*アドレス*を見てみてください.
RTCクロック
私が使っているのはC 8 T 6の最小システムボードで、本当にとても簡素で、バックアップエリアに電力を供給していないボタン電池ですが、32.768 KHzの結晶振動を溶接して、エイズで、私は電池を受け取っただけで、駆動を書いてRTCクロック部分を完成しました.
構成コードは言うまでもなく、原子のルーチンのコードを使用しています.システムの読み取り時間私が使用する方法はソフトウェアタイマーを使用して、100 msで1回読みます.タイマーのコールバック関数は以下の通りです.
/*************************************************************************************/
/*RTC                                                                        */
/*  :                                                                   	 	 */
/*   :                                                                     	 */
/*  :                                                                      */
/*     :         			2018.12.7	                                */
/*		                                                                     	  */
/********************************************************************************** */
//   1    
void tmr2_callback_RTC(void *p_tmr, void *p_arg)
{	
    //  
	LCDI2C_Show_Num(1,1,4,calendar.w_year);
	LCDI2C_Show_Num(6,1,2,calendar.w_month);
	LCDI2C_Show_Num(9,1,2,calendar.w_date);
	LCDI2C_Show_Num(13,1,2,calendar.hour);
	LCDI2C_Show_Num(16,1,2,calendar.min);
	LCDI2C_Show_String(5,1,"/");
	LCDI2C_Show_String(8,1,"/");
	LCDI2C_Show_String(15,1,":");				
}

まとめ
このプロジェクトは比較的に急いでいるが、多くの収穫を得ている.これは私がLinuxを使った最初のプロジェクトであり、UCOSを使った最初の大きなプロジェクトでもある.表示の美しさもプログラムのロバストさも、顔認識の精度も、実際には多くの向上空間がある.実は私はあるプロジェクトが精巧にする必要があると思っていますが、あるプロジェクトは実は1つの原型システムを構築するためにいくつかの技術を練習するだけです.例えば、このプロジェクトは最初の計画から実は1つの学習の練習プロジェクトなので、私はOpenCVを練習してUCOSを練習します.これからは完全にベリーパイやCortex-Aシリーズの開発ボードを使って完成し、RTOS+Linuxの奇抜な組み合わせではなくLinuxシステムをすべて使います-.-(ここで穴を掘った)