我们知道在办公室,购物中心和许多其他地方,只有持授权卡的人才能进入房间。这些系统使用RFID通信系统。当产品贴有RFID芯片的标签时,在商场中使用RFID来防止盗窃,当有人使用RFID芯片离开建筑物时,会自动发出警报。RFID标签被设计得像沙子一样小。RFID认证系统易于设计并且成本低廉。如今,一些学校和学院使用基于RFID的考勤系统。
在此项目中,出于安全目的,我们将设计基于RFID的收费系统。因此,该系统打开了大门,只允许人们使用授权的RFID标签。授权的标签持有者ID被编程到ATMEGA微控制器中,并且仅允许那些持有者离开或进入场所。
所需组件
硬件: ATmega32微控制器,电源(5v),AVR-ISP编程器,JHD_162ALCD(16x2 LCD模块),100uF电容器(跨电源连接),按钮,10KΩ电阻,100nF电容器,LED(两个),EM-18( RFID阅读器模块),L293D电机驱动器IC,5V DC电机。
软体: Atmel studio 6.1,progisp或flash magic。
电路图和工作说明
在上面所示的RFID收费系统电路中,ATMEGA32的PORTA连接到LCD的数据端口。如果要使用PORTC作为普通通信端口,我们应该记住在这里通过更改保险丝字节来禁用PORTC与ATMEGA的JTAG通信。在16x2 LCD中,如果有背光,则全部有16个引脚,如果没有背光,则有14个引脚。我们可以给背光插针供电或使其离开。现在,在14个引脚中,有8个数据引脚(7-14或D0-D7),2个电源引脚(1&2或VSS和VDD或gnd和+ 5v),第三个用于对比度控制的引脚(VEE控制着应显示字符),3个控制引脚(RS&RW&E)。
在电路中,您可以观察到我只接了两个控制引脚。这提供了更好理解的灵活性。对比度位和READ / WRITE不经常使用,因此它们可以接地。这使LCD处于最高对比度和读取模式。我们只需要控制ENABLE和RS引脚即可相应地发送字符和数据。
LCD的连接如下所示:
PIN1或VSS接地
PIN2或VDD或VCC至+ 5v电源
PIN3或VEE接地(为初学者提供最大对比度)
PIN4或RS(寄存器选择)到MCU的PD6
PIN5或RW(读/写)接地(将LCD置于读模式可简化用户的通信)
PIN6或E(启用)到微控制器的PD5
PIN7或D0至PA0
PIN8或D1到PA1
PIN9或D2到PA2
PIN10或D3到PA3
PIN11或D4到PA4
PIN12或D5到PA5
PIN13或D6至PA6
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位模式将数据发送到控制器。因此,两个字符将一次发送到控制器。如上图所示。
4.从上图可以看出,模块发送的数据中没有奇偶校验位,只有一个停止位。
以上功能在控制器寄存器中设置;我们将简要讨论它们,
红色(RXEN):该位表示接收数据功能。必须设置该位,控制器才能接收来自模块的数据。它还使能控制器的RXD引脚。
棕色(RXCIE):必须将其设置为成功接收数据后才能产生中断。通过启用此位,我们将在接收到8位数据后立即知道。
PINK(URSEL):必须先将该位置1,然后再启用UCSRC中的其他位。设置后,必须禁用UCSRC,URSEL中的其他所需位或将其置零。
黄色(UCSZ0,UCSZ1,UCSZ2):这三个位用于选择我们一次接收或发送的数据位的数量。
由于RFID模块发送的数据是8位数据类型,因此我们必须将UCSZ0,UCSZ1设置为1,并将UCSZ2设置为零。
橙色(UMSEL):根据系统是异步通信(均使用不同的时钟)还是同步通信(均使用相同的时钟)来设置此位。
由于模块和控制器使用不同的时钟,因此该位必须设置为零或保留为零,因为它们默认情况下都设置为零。
绿色(UPM1,UPM0):这两个位是根据我们在通信中使用的位奇偶校验进行调整的。
由于RFID模块发送的数据没有奇偶校验,因此我们已将UPM1,UPM0都设置为零,或者可以将它们保留为零,因为任何寄存器中的所有位默认情况下都设置为零。
蓝色(USBS):该位用于选择通讯期间使用的停止位的数量。
由于RFID模块使用一个停止位发送数据,因此我们只需要保留USBS位即可。
现在,我们终于需要设置波特率,从上图可以明显看出,RFID模块以9600bps(位/秒)的波特率向控制器发送数据。
通过选择适当的UBRRH在控制器中设置波特率。
通过交叉参考波特率和CPU晶振频率选择UBRRH值,因此通过交叉参考UBRR值被视为“ 6”,因此设置了波特率。
现在如图所示,控制器的两个引脚连接到L293D,这是一个H-BRIDGE,用于控制低功率直流电动机的速度和旋转方向。
L293D是设计用于驱动低功率直流电动机的H-BRIDGE IC,如图所示,该IC由两个h桥组成,因此可以驱动两个直流电动机。因此,该IC可用于根据微控制器的信号来驱动机器人电机。
现在,如前所述,该IC具有更改直流电动机旋转方向的能力。这是通过控制INPUT1和INPUT2上的电压电平来实现的。
使能引脚 |
输入引脚1 |
输入引脚2 |
电机方向 |
高 |
低 |
高 |
右转 |
高 |
高 |
低 |
转左 |
高 |
低 |
低 |
停止 |
高 |
高 |
高 |
停止 |
因此,如上表所示,对于顺时针旋转,应将2A设为高电平并将1A设为低电平。同样,对于逆时针方向,1A应该为高,2A应该为低。
每当将授权卡带到模块附近时,都会对电动机进行编程以使其顺时针旋转一秒,以显示一秒钟后收费站闸门打开,告诉收费站闸门已关闭。收费广场的工作最好在下面的C代码逐步说明中进行说明。
编程说明
以下是RFID收费系统代码的逐行说明。通过阅读下面的代码,您可以了解该项目的概念和工作原理。要下载或复制,您可以在页面底部找到完整的代码。
#include //标头以启用对引脚的数据流控制
#define F_CPU 1000000 //告诉控制器附加的晶体频率
#包括
#define E 5 //将名称“ enable”命名为PORTD的第5引脚,因为它已连接至LCD使能引脚
#define RS 6 //将名称“ registerselection”命名为PORTD的第6引脚,因为它已连接到LCD RS引脚
void send_a_command(unsigned char命令);
void send_a_character(unsigned char character);
无效send_a_string(char * string_of_characters);
int main(无效)
{
DDRA = 0xFF; //将porta用作输出引脚
DDRD = 0b11111110;
_delay_ms(50); //延迟50ms
DDRB = 0b11110000; //以一些portB引脚作为输入。
UCSRB-=(1 <
UCSRC-=(1 <
UCSRC&=〜(1 <
UBRRH&=〜(1 <
UBRRL = 6; //设置波特率//以下内容包含标签的ID,必须为不同的标签更改这些ID,必须对其进行更新才能使项目正常工作
/ *将程序转储到控制器后,必须拿走必须经过授权的卡并获取标签ID。通过将标签放置在RFID模块附近可以获得这些ID,并且ID将显示在屏幕上。获取ID后,必须通过将下面的ID号替换为新的ID号来更新程序。
字符ADMIT = {{((0x97),(0xa1),(0x90),(0x92)},{(0x97),(0xa1),(0x90),(0x93)},{(0x97),(0xa1),( 0x90),(0x94)},{(0x97),(0xa1),(0x90),(0x95)},{(0x97),(0xa1),(0x90),(0x96)}}; |
现在,在上面,我们仅授权五张卡,可以将它们更改为任意数量。
例如,考虑将默认程序转储到控制器中,获取应获得授权的卡。将一个接一个的放置在模块附近,您将获得每个ID的xxxxxxxx(907a4F87),
如果我们有7个标签,那么我们将有7个八位ID。* /
//现在对于七张牌来说 // char ADMIT = {{{(0x90),(0x7a),(0x4F),(0x87)},;; //分配内存以显示模块发送的ID int i = 0; int选票= 0; int k = 0; send_a_command(0x01); //清除屏幕0x01 = 00000001 _delay_ms(50); send_a_command(0x38); //告诉LCD我们正在使用8bit命令/数据模式 _delay_ms(50); send_a_command(0b00001111); // LCD SCREEN(液晶屏)亮起,并且课程灯闪烁 char MEM; //分配内存以存储标签的完整ID send_a_string(“ RFID NUMBER”); //发送字符串 send_a_command(0x80 + 0x40 + 0); //将Courser移至第二行 而(1) { while(!(UCSRA&(1 <
{ } COUNTA = UDR;// UDR存储接收到的八位数据并将其取为整数。 MEM = COUNTA; //前两个字符更新到内存 itoa(COUNTA,SHOWA,16); //将变量号放入LCD的命令(变量号,其中要替换的字符,基数是可变的(此处为十,因为我们在base10中对数字进行计数)) send_a_string(SHOWA); //在LCD上放置滑行器之后,告诉显示屏显示第二人称字符(由变量号替换) while(!(UCSRA&(1 <
{ } COUNTA = UDR; itoa(COUNTA,SHOWA,16); send_a_string(SHOWA); MEM = COUNTA; //将第三个和第四个字符更新到内存 while(!(UCSRA&(1 <
{ } COUNTA = UDR; itoa(COUNTA,SHOWA,16); send_a_string(SHOWA); MEM = COUNTA; //第五和第六个字符已更新到内存 while(!(UCSRA&(1 <
{ } COUNTA = UDR; itoa(COUNTA,SHOWA,16); send_a_string(SHOWA); MEM = COUNTA; //将第七个和八个字符更新到内存 send_a_string(“”); send_a_command(0x80 + 0x40 + 0); UCSRB&=〜(1 <
对于(i = 0; i <5; i ++) { 如果((MEM == ADMIT)&(MEM == ADMIT)&(MEM == ADMIT)&(MEM == ADMIT)) {//检查授权,一次将两个字符与内存中的字符进行比较 PORTB-=(1 <
PORTB&=〜(1 <
_delay_ms(220); //延迟 _delay_ms(220); _delay_ms(220); _delay_ms(220); _delay_ms(220); _delay_ms(220); PORTB-=(1 <
PORTB&=〜(1 <
_delay_ms(220); _delay_ms(220); _delay_ms(220); _delay_ms(220); _delay_ms(220); _delay_ms(220); PORTB&=〜(1 <
PORTB-=(1 <
} } UCSRB-=(1 <
} } 无效send_a_command(unsigned char命令) { PORTA =命令; PORTD&=〜(1 <
PORTD-= 1 <
_delay_ms(50); PORTD&=〜1 <
PORTA = 0; } void send_a_character(无符号字符) { PORTA =字符; PORTD-= 1 <
PORTD-= 1 <
_delay_ms(50); PORTD&=〜1 <
PORTA = 0; } 无效send_a_string(char * string_of_characters) { while(*字符串的字符> 0) { send_a_character(* string_of_characters ++); } } |