オフィスやショッピングモールなど、認証カードを持っている人だけが入室できる場所がたくさんあります。これらのシステムはRFID通信システムを使用しています。RFIDはショッピングモールで盗難を防ぐために使用されます。製品にはRFIDチップのタグが付けられており、RFIDチップを持って建物を離れると、アラームが自動的に鳴ります。RFIDタグは、砂の一部と同じくらい小さいように設計されています。RFID認証システムは設計が簡単で、コストも安いです。最近の一部の学校や大学では、RFIDベースの出席システムを使用してい ます。
このプロジェクトでは、認証された投票のみをカウントする投票機を設計します。これは、RFID(無線周波数識別)タグを使用して行われます。ここでは、許可されたRFIDタグ所有者のみが投票できるようにするATMEGA用のプログラムを作成します。(この簡単な投票機プロジェクトもチェックしてください)
必要なコンポーネント
ハードウェア: ATMEGA32、電源(5v)、AVR-ISP PROGRAMMER、JHD_162ALCD(16x2LCD)、100uFコンデンサ(電源間に接続)、ボタン(5個)、10KΩ抵抗(5個)、100nFコンデンサ(5個)、LED (2個)、EM-18(RFIDリーダーモジュール)。
ソフトウェア: Atmel studio 6.1、progispまたはflashmagic。
回路図と説明
回路ではATMEGA32のPORTAがLCDのデータポートに接続されています。ここで、PORTCを通常の通信ポートとして使用したい場合は、ヒューズバイトを変更してPORTCからATMEGAへのJTAG通信を無効にすることを忘れないでください。 16x2 LCDでは、ブラックライトがある場合は全体で16ピン、バックライトがない場合は14ピンになります。バックライトピンに電力を供給するか、そのままにしておくことができます。 14ピンには8つのデータピン(7-14またはD0-D7)、2つの電源ピン(1&2またはVSS&VDDまたはgnd&+ 5v)、コントラスト制御用の3番目のピン(VEE-文字の太さを制御します)があります。示されている)、3つの制御ピン(RS&RW&E)
回路では、2つの制御ピンしか使用していないことがわかります。これにより、理解を深める柔軟性が得られます。コントラストビットとREAD / WRITEはあまり使用されないため、グランドに短絡できます。これにより、LCDが最高のコントラストと読み取りモードになります。ENABLEピンとRSピンを制御して、それに応じて文字とデータを送信する必要があります。
LCD用に行われる接続を以下に示します。
PIN1またはVSSをアースに接続
PIN2またはVDDまたはVCCから+ 5v電源
PIN3またはVEEを地面に接続(初心者に最適な最大のコントラストを提供)
PIN4またはRS(レジスタ選択)をuCのPD6に
PIN5またはRW(読み取り/書き込み)をグランドに接続(LCDを読み取りモードにすると、ユーザーの通信が容易になります)
PIN6またはE(有効)からuCのPD5
uCのPIN7またはD0からPA0
uCのPIN8またはD1からPA1
uCのPIN9またはD2からPA2
uCのPIN10またはD3からPA3
uCのPIN11またはD4からPA4
uCのPIN12またはD5からPA5
uCのPIN13またはD6からPA6
uCのPIN14またはD7からPA7
回路では、8ビット通信(D0-D7)を使用していることがわかります。ただし、これは必須ではなく、4ビット通信(D4-D7)を使用できますが、4ビット通信プログラムでは少し複雑になるため、8ビット通信を選択しました。
したがって、上記の表を単に観察するだけで、LCDの10ピンをコントローラーに接続します。8ピンはデータピンで、2ピンは制御用です。
先に進む前に、シリアル通信について理解する必要があります。ここでのRFIDモジュールは、データをコントローラーにシリアルに送信します。他の通信モードもありますが、簡単に通信できるようにRS232を選択しています。モジュールのRS232ピンはATMEGAのRXDピンに接続されています。
RFIDモジュールによって送信されるデータは次のようになります。
ここで、RFIDモジュールインターフェイスには、次の機能が必要です。
1.コントローラのRXDピン(データ受信機能)を有効にする必要があります。
2.通信はシリアルであるため、データバイが受信されるたびに知る必要があります。これにより、完全なバイトが受信されるまでプログラムを停止できます。これは、データ受信の完全な割り込みを有効にすることによって行われます。
3.RFIDは8ビットモードでデータをコントローラーに送信します。したがって、一度に2文字がコントローラーに送信されます。これは図3のブロックに示されています
4.図3から、モジュールによって送信されるデータにはパリティビットがなく、1ストップビットがあります。
上記の機能はコントローラレジスタに設定されています。それらについて簡単に説明します。
赤(RXEN):このビットはデータ受信機能を表します。このビットは、モジュールからのデータをコントローラーが受信するために設定する必要があります。また、コントローラーのRXDピンを有効にします。
ブラウン(RXCIE):このビットは、データ受信が成功した後に割り込みを取得するために設定する必要があります。このビットを有効にすることで、8ビットのデータを受信した直後に知ることができます。
PINK(URSEL):このビットは、UCSRCで他の必要なビットを設定した後、UCSRCで他のビットを有効にする前に設定する必要があります。URSELを無効にするか、ゼロにする必要があります。
YELLOW(UCSZ0、UCSZ1、UCSZ2):これらの3ビットは、一度に受信または送信するデータビットの数を選択するために使用されます。
RFIDモジュールによって送信されるデータは8ビットデータタイプ(図3)であるため、UCSZ0、UCSZ1を1に、UCSZ2を0に設定する必要があります。
オレンジ(UMSEL):このビットは、システムが非同期(両方とも異なるクロックを使用)または同期(両方とも同じクロックを使用)で通信しているかどうかに基づいて設定されます。
モジュールとコントローラーは異なるクロックを使用するため、このビットはデフォルトですべてゼロに設定されているため、ゼロに設定するか、そのままにしておく必要があります。
緑(UPM1、UPM0):これらの2つのビットは、通信で使用しているビットパリティに基づいて調整されます。
RFIDモジュールはパリティなしでデータを送信するため(図3)、UPM1、UPM0の両方をゼロに設定するか、レジスタのすべてのビットがデフォルトでゼロに設定されているため、そのままにしておくことができます。
青(USBS):このビットは、通信中に使用するストップビットの数を選択するために使用されます。
RFIDモジュールは1つのストップビットでデータを送信するため(図3)、USBSビットをそのままにしておく必要があります。
最後に、ボーレートを設定する必要があります。図3から、RFIDモジュールが9600bps(ビット/秒)のボーレートでデータをコントローラーに送信することは明らかです。
ボーレートは、適切なUBRRHを選択することにより、コントローラーで設定されます。
UBRRH値は、ボーレートとCPU水晶周波数を相互参照することによって選択されます。
したがって、相互参照により、UBRR値は「6」と見なされ、ボーレートが設定されます。
ここには5つのボタンがあり、4つは候補者の投票を増やすためのもので、5つ目は候補者の投票をゼロにリセットするためのものです。ここにあるコンデンサは、ボタンのバウンス効果を無効にするためのものです。それらが削除された場合、コントローラーはボタンが押されるたびに複数カウントする可能性があります。
ピンに接続されている抵抗は、ボタンを押してピンをグランドに引き下げるときに電流を制限するためのものです。ボタンが押されるたびに、コントローラーの対応するピンが地面に引き下げられ、コントローラーは特定のボタンが押されたことを認識し、対応するアクションが実行されます。ボタンが押されると、候補投票が増加するか、投票がリセットされます。
対応する人物を表すボタンが押されると、コントローラーはそれを選択し、増分後にメモリ内の対応する人物番号をインクリメントし、16x2LCDディスプレイに対応する人物のスコアを表示します。
投票機の動作は、以下に示すCコードのステップバイステップで最もよく説明されています。
コードの説明
#include //ピンのデータフロー制御を有効にするヘッダー
#define F_CPU 1000000 //接続されているコントローラーの水晶周波数を伝える
#include
#define E 5 // LCDイネーブルピンに接続されているため、PORTDの5番目のピンに「enable」という名前を付けます
#define RS 6 // LCD RSピンに接続されているため、PORTDの6番目のピンに「registerselection」という名前を付けます
void send_a_command(unsigned char command);
void send_a_character(unsigned char character);
void send_a_string(char * string_of_characters);
int main(void)
{{
DDRA = 0xFF; //ポルタを出力ピンとして配置
DDRD = 0b11111110;
_delay_ms(50); // 50msの遅延を与える
DDRB = 0b11110000; //いくつかのportBピンを入力として使用します。
UCSRB-=(1 <
//データ受信完全割り込みを有効にし、データ受信ピンを有効にします
UCSRC-=(1 <
//最初にURSELを設定し、8ビット通信を設定して他のビットを変更します
UCSRC&=〜(1 <
UBRRH&=〜(1 <
UBRRL = 6; //ボーレートの設定
int16_t VOTEA = 0; // person1投票でメモリを保存
char A; // person1がLCDに文字を表示する投票
int16_t VOTEB = 0;; // person2投票でメモリを保存
char B; // person2投票でLCDに文字を表示
int16_t VOTEC = 0;; // person3投票でメモリを保存
char C; // person3票がLCDに文字を表示
int16_t VOTED = 0;; // person4投票でメモリを保存
char D; / / person4票がLCDに文字を表示
//以下にはタグのIDが含まれています。これらはタグごとに変更する必要があります。プロジェクトを機能させるには、これらを更新する必要があります。
//プログラムをコントローラーにダンプした後、認証が必要なカードを取得してタグIDを取得する必要があります。これらは、RFIDモジュールの近くにタグを配置することで取得され、IDが画面に表示されます。IDを取得したら、以下のID番号を新しいID番号に置き換えてプログラムを更新する必要があります。
char ADMIT = {{(0x97)、(0xa1)、(0x90)、(0x92)}、{(0x97)、(0xa1)、(0x90)、(0x93)}、{(0x97)、(0xa1)、( 0x90)、(0x94)}、{(0x97)、(0xa1)、(0x90)、(0x95)}、{(0x97)、(0xa1)、(0x90)、(0x96)}}; |
上記では、5枚のカードのみを承認しています。これらは任意の数に変更できます。
たとえば、デフォルトのプログラムがコントローラーにダンプされていると考えて、承認されるべきカードをモジュールの近くに次々に配置します。各カードのIDをxxxxxxxx(907a4F87)として取得します。
タグが7つある場合、8ビットIDが7つあります。
//今では7枚のカードの場合は次のようになります // char ADMIT = {{(0x90)、(0x7a)、(0x4F)、(0x87)}、; //モジュールによって送信されたIDを表示するためのメモリを割り当てる int i = 0; intvote = 0; int k = 0; send_a_command(0x01); //画面をクリア0x01 = 00000001 _delay_ms(50); send_a_command(0x38); // 8ビットコマンド/データモードを使用している液晶ディスプレイに通知 _delay_ms(50); send_a_command(0b00001111); // LCD画面がオンでコースラーが点滅 char MEM; //タグの完全なIDを格納するためのメモリの割り当て send_a_string( "RFID NUMBER"); //送信文字列 send_a_command(0x80 + 0x40 + 0); //コースラーを2行目に移動 while(1) {{ while(!(UCSRA&(1 <
{{ } COUNTA = UDR; // UDRは、受信した8ビットデータを格納し、整数に変換されます。 MEM = COUNTA; //最初の2文字がメモリに更新されます itoa(COUNTA、SHOWA、16); // LCDに変数番号を入力するコマンド(変数番号、置換する文字、ベースは可変(ここではbase10で数を数えているので10)) send_a_string(SHOWA); //コースターをLCDに配置した後、2人目の人物の文字(変数番号に置き換えられます)を表示するようにディスプレイに指示します while(!(UCSRA&(1 <
{{ } COUNTA = UDR; itoa(COUNTA、SHOWA、16); send_a_string(SHOWA); MEM = COUNTA; // 3番目と4番目の文字がメモリに更新されます while(!(UCSRA&(1 <
{{ } COUNTA = UDR; itoa(COUNTA、SHOWA、16); send_a_string(SHOWA); MEM = COUNTA; // 5番目と6番目の文字がメモリに更新されます while(!(UCSRA&(1 <
{{ } COUNTA = UDR; itoa(COUNTA、SHOWA、16); send_a_string(SHOWA); MEM = COUNTA; // 7文字目と8文字がメモリに更新されます send_a_string( ""); send_a_command(0x80 + 0x40 + 0); UCSRB&=〜(1 <
for(i = 0; i <5; i ++) {{ if((MEM == ADMIT)&(MEM == ADMIT)&(MEM == ADMIT)&(MEM == ADMIT)) {//一度に2文字をメモリ内の文字と比較して承認購入を確認する PORTB-=(1 <
投票= 1; //承認された場合は投票する } } if(vote == 0)//投票が設定されていない場合は承認に失敗しました {{ UCSRB-=(1 <
} while(vote == 1)//承認された場合、投票されるまでこのループを実行します {{ send_a_command(0x80 + 0); // line1の位置0に移動します send_a_string( "VOTE NOW"); //文字列の表示 if(bit_is_clear(PINB、0))//ボタン1が押されたとき {{ VOTEA ++; //一人称の投票メモリを1つ増やします 投票= 0; //投票後にwhileループを実行させる } if(bit_is_clear(PINB、1))//ボタン2が押されたとき {{ VOTEB ++; //投票2のメモリインクリメントND ずつ人を 投票= 0; } if(bit_is_clear(PINB、2))//ボタン3が押されたとき {{ VOTEC ++; // 3の投票メモリインクリメント番目の 1によって人を 投票= 0; } if(bit_is_clear(PINB、3))//ボタン4が押されたとき {{ VOTED ++; // 4人目の投票メモリを1つ増やします 投票= 0; } if(vote == 0)//投票を受け取った後にクリア {{ send_a_command(0x80 + 0); // line1の位置0に移動 send_a_string( "THANK U FOR VOTE"); //文字列を表示 for(k = 0; k <10; k ++) {{ _delay_ms(220); } PORTB&=〜(1 <
send_a_command(0x01); send_a_command(0x80 + 0); // 4人全員の投票を表示する send_a_string( "A ="); send_a_command(0x80 + 2); itoa(VOTEA、A、10); send_a_string(A); send_a_command(0x80 + 8); send_a_string( "B ="); send_a_command(0x80 + 10); itoa(VOTEB、B、10); send_a_string(B); send_a_command(0x80 + 0x40 + 0); send_a_string( "C ="); send_a_command(0x80 + 0x40 + 2); itoa(VOTEC、C、10); send_a_string(C); send_a_command(0x80 + 0x40 + 8); send_a_string( "D ="); send_a_command(0x80 + 0x40 + 10); itoa(VOTED、D、10); send_a_string(D); send_a_command(0x80 + 0x40 + 16); for(k = 0; k <25; k ++) {{ _delay_ms(220); } UCSRB-=(1 <
send_a_command(0x01); send_a_command(0x80 + 0); //ゼロ位置に移動 send_a_string( "RFID NUMBER"); //文字列を送信します send_a_command(0x80 + 0x40 + 0); } } void send_a_command(unsigned char command) {{ PORTA =コマンド; PORTD&=〜(1 <
PORTD- = 1 <
_delay_ms(50); PORTD&= 〜1 <
PORTA = 0; } void send_a_character(unsigned char character) {{ PORTA =文字; PORTD- = 1 <
PORTD- = 1 <
_delay_ms(50); PORTD&= 〜1 <
PORTA = 0; } void send_a_string(char * string_of_characters) {{ while(* string_of_characters> 0) {{ send_a_character(* string_of_characters ++); } } |