RFID高频读卡器+SG90舵机模拟门禁开门
一.项目介绍
博主本人这几个月也陆陆续续写了挺多文章的,但都是各个模块的知识。今天就想写一个小项目,用RFID高频读卡器加SG90舵机去模拟门禁,当RFID读取到IC卡后,我们的舵机就转动,模拟开门。自我感觉这个项目也是比较容易理解和上手的。
二.RFID+SG90模块
这里呢,这里我二个模块都分别讲过,要去理解的可以去看我这二篇博客 : 一篇为RFID讲解附代码 ,还一篇是SG90舵机讲解附代码。这二篇博客基本就已经讲清楚了这二个模块。而我接下来是将这二个模块合并,模拟门禁。
三.项目源码
这里我使用的是stm32f103系列的开发板。
3.1 main.c
我们首先看main函数
/* 主函数 */
int main(void)
{
delay_init(); //延时初始化
TIM8_PWM_Init(); //初始化舵机的pwm信号
uart_init(115200); //初始化串口,连接串口助手可打印出调试信息
usart3_init(9600); //初始化串口3 RFID使用
while(1)
{
//读卡成功返回0
//这里读卡成功舵机转动
if(!ReadId())
{
//这里代码如果看不懂就去看博主的SG90模块的那篇博客
//上面也给了链接
TIM_SetCompare1(TIM8,5);//0度
delay_ms(500);
TIM_SetCompare1(TIM8,15);//90度
delay_ms(500);
TIM_SetCompare1(TIM8,25);//180度
delay_ms(1000);
}
}
}
3.2 rfid.c
虽然说我们上面只使用了ReadId()函数,但是这里我把代码都贴出来了
#include "stm32f10x.h"
#include "usart3.h"
#include "usart.h"
#include "rfid.h"
#include "stdio.h"
#include "usart.h"
unsigned char Uart3RxBuf[UART3_RX_BUF_LEN];
unsigned char Uart3RxDataConut = 0;
unsigned char Rx3Flag = 0;
unsigned char Cmd_Read_Id[8] = {0x01,0x08,0xa1,0x20,0x00,0x00,0x00,0x00};
unsigned char Cmd_Read_Block[8] = {0x01,0x08,0xa3,0x20,0x00,0x00,0x00,0x00};
unsigned char Cmd_Write_Block[23] = {0x01,0x17,0xa4,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char WBlockData[16] = {0x11,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f};
//CircularBuffer *Uart2_Circular_Buffer;
unsigned char Cmd_Write_RFID[0x0B]={0x03, 0x0B, 0xC5, 0x20, 0x05, 0x12, 0x34, 0x56, 0x78, 0x09, 0x16};
// 命令类型 包长度 命令 设备地址 起始地址 数据长度 保留 校验和
unsigned char Cmd_Read_RFID[]={0x02, 0x08, 0xB5, 0x20, 0x03, 0x06, 0x00, 0x65};
//延时,10000000大约为1S
void Delay(__IO unsigned int nCount)
{
for (; nCount != 0; nCount--);
}
void Uart3_Send_Data(unsigned char *buf,unsigned char num)
{
unsigned char i;
for(i=0;i<num;i++)
{
USART_SendData(USART3, buf[i]);
while (USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
}
}
unsigned char RxCheckSum(unsigned char *ptr,unsigned char len)
{
unsigned char i;
unsigned char checksum;
checksum = 0;
for(i=0;i<(len-1);i++)
{
checksum ^= ptr[i];
}
checksum = ~checksum;
if(ptr[len-1] == checksum)
return STATUS_OK;
else
return STATUS_ERR;
}
void TxCheckSum(unsigned char *ptr,unsigned char len)
{
unsigned char i;
unsigned char checksum;
checksum = 0;
for(i=0;i<(len-1);i++)
{
checksum ^= ptr[i];
}
checksum = ~checksum;
ptr[len-1] = checksum;
}
//ReadId():读IC卡ID号(卡号)
//参数:*idout,读取的卡号保存到它所指向的存储空间
//返回值:0:成功读取卡号,1:读卡号失败
unsigned char ReadId(void)
{
unsigned char status;
unsigned char i;
unsigned char idout[6];
Cmd_Read_Id[5] = 0x01;//开启蜂鸣器提示
//Cmd_Read_Id[5] = 0x00;//关闭蜂鸣器提示
TxCheckSum(Cmd_Read_Id,Cmd_Read_Id[1]); //计算校验和
Uart3_Send_Data(Cmd_Read_Id,Cmd_Read_Id[1]); //发送读卡号ID命令
Delay(2000000);//等待模块返回数据,大于150MS
if(Rx3Flag == 1)
{
Rx3Flag = 0;
status = RxCheckSum(Uart3RxBuf,Uart3RxBuf[1]);//对接收到的数据校验
if(status != STATUS_OK) //判断校验和是否正确
{
return STATUS_ERR;
}
status = Uart3RxBuf[4];
if(status != STATUS_OK) //判断是否正确的读到卡
{
return STATUS_ERR;
}
if((Uart3RxBuf[0] == 0x01)&&(Uart3RxBuf[2] == 0xa1))//判断是否为读卡号返回的数据包
{
printf("IDCard: ");
for(i=0;i<6;i++)//获取卡号ID,6字节
{
//idout[i] = Uart3RxBuf[i+5];//从数组的第5个字节开始为卡号,长度为6字节
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
if(Uart3RxBuf[i+5]/16<10)
printf("%c",Uart3RxBuf[i+5]/16+48);
else printf("%c",Uart3RxBuf[i+5]/16+55);
if(Uart3RxBuf[i+5]%16<10)
printf("%c ",Uart3RxBuf[i+5]%16+48);
else printf("%c ",Uart3RxBuf[i+5]%16+55);
}
printf("\n");
return STATUS_OK; //成功返回0
}
}
return STATUS_ERR; //失败返回1
}
unsigned char Read_RFID(unsigned char addr,unsigned char len)
{
unsigned char status;
unsigned char i;
Cmd_Read_RFID[4]=addr;
Cmd_Read_RFID[5]=len;
TxCheckSum(Cmd_Read_RFID,Cmd_Read_RFID[1]); //计算校验和
Uart3_Send_Data(Cmd_Read_RFID,Cmd_Read_RFID[1]); //发送读用户数据命令
Delay(2000000);//等待模块返回数据,大于150MS
if(Rx3Flag == 1)
{
Rx3Flag = 0;
status = RxCheckSum(Uart3RxBuf,Uart3RxBuf[1]);//对接收到的数据校验
if(status != STATUS_OK) //判断校验和是否正确
{
return STATUS_ERR;
}
status = Uart3RxBuf[4];
if(status != STATUS_OK) //判断是否正确的读到卡
{
return STATUS_ERR;
}
if((Uart3RxBuf[0] == 0x02)&&(Uart3RxBuf[2] == 0xB5))//判断是否为读RFID用户信息返回的数据包
{
for(i=0;i<Cmd_Read_RFID[5];i++) //将读取的RFID打印到串口
{
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
USART_SendData(USART1,Uart3RxBuf[i+5]+'0');
}
return STATUS_OK; //成功返回0
}
}
return STATUS_ERR;
}
四.实验现象
RFID+SG90模拟门禁
五.项目总结
这个项目模块也挺少的,就二个模块,但是学习都是循序渐进的 ,慢慢的叠加模块,也可以去再加一个led灯,刷门禁开灯等等。根据自己的兴趣去添加模块。总之,学了各个模块之后,最好自己去做一个小项目练练手。
另外,这个小项目的源代码也在博主的资源文件中,需要的可以免费下载!