STM32平台控制AS3992 UHF RFID读写模块应用案例
1.1项目说明:
本平台使用STM32做主控,通过串口控制Eleckits UHF RFID读写模块,当红外线感应到物体时,读写器自动执行标签读操作,读写器将识别到的标签ID以Excel的数据格式存储在SD卡中。
总体架构:
垃圾车的机械臂带有红外臂章传感器,当抓取到垃圾桶Spuce 控制RFID读写器读取垃圾桶上的标签信息并处理读到的数据,记录到SD卡中。存入有效的数据后,蜂鸣器报警提示。即完成数据的记录和处理。进而进行下个垃圾桶的垃圾收集。
Spruce和RFID的通信:
SD卡存储格式:
标号 | RFID标签号 | 日期 |
1 | 3005FB63AC1F3841EC880467 |
2011-8-1-MON-12:00:00 |
2 | 3005FB63AC1F3841EC880467 |
2011-8-1-MON-13:00:00 |
3 | 3005FB63AC1F3841EC880467 |
2011-8-1-MON-14:00:00 |
4 | 3005FB63AC1F3841EC880467 |
2011-8-1-MON-15:00:00 |
1.2流程图:
1.3实现功能
1. 检测SD卡是否插入,没有插入蜂鸣器报警。需断电后重新插入SD卡。
2. 红外避障功能,当有障碍物时STM32才会通过串口发送命令,节约了耗电量。
3. 显示日期功能,具体到秒。需要在程序中配置时间。
4. 读取有效的标签号存入SD卡中。
5. 创建CSV格式文件,按照上表格式存储数据(会重复记录数据)。可以以表格形式打开,便于查看。
6. 存入有效数据成功后,蜂鸣器报警提示。
1.4外设连接(需参考电路图)
1. 蜂鸣器连接:
正极接STM32 5V引脚。
蜂鸣器另一端接STM32的PB9引脚。
2.
正极接STM32 5V引脚。
负极接STM32 接地引脚。
标有S的引脚接STM32的PE9引脚。
3. RFID连接:
RFID和STM32共地连接。
连接3V电源
STM32的USART2的TX(PA2)连接RFID的RX。
STM32的USART2的RX(PA3)连接RFID的TX。
2.主要程序解读
void SendCmd1(void) { cmd_delay();//waiting receive data USART_SendData(USART2, 0x10); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } USART_SendData(USART2, 0x03); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } USART_SendData(USART2, 0x01); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } } void SendCmd2(void) { cmd_delay();//waiting receive data USART_SendData(USART2, 0x10); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } USART_SendData(USART2, 0x03); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } USART_SendData(USART2, 0x00); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } } void SendCmd3(void) { cmd_delay();//waiting receive data USART_SendData(USART2, 0x43); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } USART_SendData(USART2, 0x04); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } USART_SendData(USART2, 0x01); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } USART_SendData(USART2, 0xcd); while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET) { } } void USART2_IRQHandler(void) { //uint8_t RecieveData,i; if (USART_GetITStatus(USART2, USART_IT_RXNE) != 0) { USART_ClearITPendingBit(USART2, USART_IT_RXNE);//清除中断标志位 RecieveData = USART_ReceiveData(USART2); String_to_Hex();//转换成字符 //USART_SendData(USART1, RecieveData); //while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) {} } } void String_to_Hex(void)//a hex need two string data example: A8 store the file like 'A'and'8' { uint8_t value1,value2; uint8_t Map_value=RecieveData; value1=Map_value/16;//high if(value1<10) RecieveData2[count++]=Map_value/16+'0';//high value int to hex else RecieveData2[count++]=Map_value/16+'7';//high value int to hex(A,B,C,D,E,F) value2=Map_value;//low if(value2<10) RecieveData2[count++]=Map_value+'0';//low value int to hex else RecieveData2[count++]=Map_value+'7';//low value int to hex(A,B,C,D,E,F) } void Write_Mark(void) { int Mark[5],i;//Mark数组存放标号 char name[] = { "Data.csv" };//file name char Information[]="No.,Tag Num,Date"; f_mount(0, &fs);//挂载逻辑盘符0 res = f_open(&fsrc, name, FA_CREATE_NEW | FA_WRITE);//create file f_open(&fsrc, name, FA_WRITE);//打开写操作 f_lseek(&fsrc, fsrc.fsize); //文件指针移动到文件底部 if(0==Information_Flag)//说明信息标志位为0时写入说明信息 { Information_Flag=1; f_write(&fsrc, &Information, sizeof(Information), &br);//写入说明信息 f_putc('\n',&fsrc); } Mark[0] = Mark_Num / 10000+48; //标号计算 Mark[1] = Mark_Num % 10000 / 1000+48;//标号计算 Mark[2] = Mark_Num % 1000 / 100+48;//标号计算 Mark[3] = Mark_Num % 100 / 10+48;//标号计算 Mark[4] = Mark_Num % 10+48;//标号计算 for(i=0;i<5;i++) { f_putc(Mark[i], &fsrc);//写入标号 } f_putc(',',&fsrc);//逗号隔开 } void Wtite_SerialNumber(void) { char Num[24];//Num数组用来存放24位标签号 memcpy(Num,RecieveData2+20*sizeof(char),24*sizeof(char));//去掉接收到得前20位非标签号,保留24位标签号 f_write(&fsrc,&Num, 24, &br);//写入SD卡中 f_putc(',', &fsrc);//逗号隔开 count=0;//接受到得数据重新开始存储 } void Write_Date(void) { count=0; f_lseek(&fsrc, fsrc.fsize);//移动文件指针 RTC_Get();//获取日期时间 f_write(&fsrc, &cal, sizeof(cal), &br);//写入SD卡中 f_putc(',', &fsrc);//逗号隔开 f_putc('\n', &fsrc);//换行 f_close(&fsrc);//关闭文件 } void Colation(void) { char b[] = "4405000000";//无效数据 char c[] = "48656C6C6F";//无效数据 char d[] = "494E545643";//无效数据 char f[] = "3033323420";//无效数据 char e[10] = "0";//e数组用来存放接受到得数据 memcpy(e, RecieveData2, 10 * sizeof(char));//拷贝接受到得数据 if ((0 == strcmp(b, e)) || (0 == strcmp(c, e)) || (0 == strcmp(d, e))|| (0 == strcmp(f, e)))//和无效数据进行比较 { C_Flag = 0;//和无效数据相等 C_Flag标志位清零 } else C_Flag = 1;//不相等则置位 count = 0; } //输入:年份//输出:该年份是不是闰年.1,是.0,不是 u8 Is_Leap_Year(u16 year) { if(year%4==0) //必须能被4整除 { if(year0==0) { if(year@0==0)return 1;//如果以00结尾,还要能被400整除 else return 0; }else return 1; }else return 0; } u8 RTC_Get_Week(u16 year,u8 month,u8 day)//返回week的下标,0为周一 {//注:1900年1月1日为周1 uint16_t temp2; uint8_t yearH,yearL; yearH=year/100; yearL=year0; // 如果为21世纪,年份数加100 if (yearH>19) yearL+=100; // 所过闰年数只算1900年之后的 temp2=yearL+yearL/4;//365/7余数为1,闰年再多加1 temp2=temp2%7; temp2=temp2+day+table_week[month-1]; if (yearL%4==0&&month<3)//闰年1月或2月,还不必加1,过了2月才要加 temp2--; return(temp2%7); } u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)//成功返回0,否则返回1 { u16 t; u32 seccount=0; if(syear<1970||syear>2099)//从1970-1-1-00:00:00开始记秒 return 1; for(t=1970;t<syear;t++) //把所有年份的秒钟相加 { if(Is_Leap_Year(t)) seccount+=31622400;//闰年的秒钟数 else seccount+=31536000;//平年的秒钟数 } smon-=1; for(t=0;t<smon;t++) //把前面月份的秒钟数相加 { seccount+=(u32)mon_table[t]*86400;//月份秒钟数相加 if(Is_Leap_Year(syear)&&t==1) seccount+=86400;//闰年2月份增加一天的秒钟数 } seccount+=(u32)(sday-1)*86400;//把前面日期的秒钟数相加 seccount+=(u32)hour*3600;//小时秒钟数 seccount+=(u32)min*60; //分钟秒钟数 seccount+=sec;//最后的秒钟加上去 //以下为设置时钟 PWR_BackupAccessCmd(ENABLE);//区消写保护,使能 RTC 和后备寄存器访问 RTC_SetCounter(seccount);//设置RTCCounter的初始值 RTC_WaitForSynchro();//等待 RTC 寄存器(RTC_CNT, RTC_ALR and RTC_PRL)与 RTC 的 APB 时钟同步 RTC_WaitForLastTask();//等待最近一次对 RTC 寄存器的写操作完成 return 0; } u8 RTC_Get(void) { static uint16_t daycnt=0; uint32_t timecount1=0; uint32_t temp=0; uint16_t temp1=0; int a,b,c;//i, timecount1=RTC_GetCounter();//获得存储秒数的32位计数器的值 temp=timecount1/86400; //得到天数(秒钟数对应的) if(daycnt!=temp)//超过一天了 { daycnt=temp; temp1= 1970; //仿照linux计时,从1970-1-1-00:00:00开始记秒 while(temp>=365) { if(Is_Leap_Year(temp1))//是闰年 { if(temp>=366)temp-=366;//闰年的秒钟数 else {temp1++;break;} } else temp-=365; //平年 temp1++; } timer.year=temp1;//得到年份 temp1=0; while(temp>=28)//超过了一个月 { if(Is_Leap_Year(timer.year)&&temp1==1)//当年是不是闰年/2月份 { if(temp>=29) temp-=29;//闰年的秒钟数 else break; } else { if(temp>=mon_table[temp1]) temp-=mon_table[temp1];//平年 else break; } temp1++; } timer.month=temp1+1;//得到月份 timer.day=temp+1; //得到日期 } temp=timecount1�400; //得到秒钟数 timer.hour=temp/3600; //小时 timer.min=(temp600)/60; //分钟 timer.sec=(temp600)`; //秒钟 timer.week=RTC_Get_Week(timer.year,timer.month,timer.day);//获取星期 cal[0]='2';//Timer.year/1000+48; 数字转换为字符a=a+48; a=(timer.year-2000)/100; cal[1]=(timer.year-2000)/100+48; b=(timer.year-2000-a*100)/10; cal[2]=(timer.year-2000-a*100)/10+48; c=(timer.year-2000-a*100-b*10); cal[3]=(timer.year-2000-a*100-b*10)+48; //month cal[4]='-'; a=timer.month/10; cal[5]=(timer.month/10)+48; cal[6]=timer.month-a*10+48; cal[7]='-'; //day a=timer.day/10; cal[8]=(timer.day/10)+48; cal[9]=(timer.day-a*10)+48; cal[10]='-'; //week,从周日开始记周 switch(timer.week) { case 1:// cal[11]=week[0]; cal[12]=week[1]; cal[13]=week[2]; break; case 2:// cal[11]=week[3]; cal[12]=week[4]; cal[13]=week[5]; break; case 3:// cal[11]=week[6]; cal[12]=week[7]; cal[13]=week[8]; break; case 4:// cal[11]=week[9]; cal[12]=week[10]; cal[13]=week[11]; break; case 5:// cal[11]=week[12]; cal[12]=week[13]; cal[13]=week[14]; break; case 6:// cal[11]=week[15]; cal[12]=week[16]; cal[13]=week[17]; break; case 0:// cal[11]=week[18]; cal[12]=week[19]; cal[13]=week[20]; break; default: USART_print("this is a bug"); break; } cal[14]='-'; //hour a=timer.hour/10; cal[15]=(timer.hour/10)+48; cal[16]=(timer.hour-a*10)+48; cal[17]=':'; //mini a=timer.min/10; cal[18]=(timer.min/10)+48; cal[19]=(timer.min-a*10)+48; cal[20]=':'; //sec a=timer.sec/10; cal[21]=(timer.sec/10)+48; cal[22]=(timer.sec-a*10)+48; return 0; } |
完全兼容AMS官方价值RMB 4000元的Roger开发板。适合客户做RFID的二次开发。我们是模块产品,可以通过普通Uart接口把模块集成到您的项目中。我们的价格只是原厂的四分之一!!!!!
Uart串口UHF RFID读写器 915M 无源GEN2超高频读写模块 AS3992
http://item.taobao.com/item.htm?spm=a1z10.1.w4004-3535073336.7.rTV2tL&id=15138367983
RFID 读写器系统包括如下部分:
电源适配器+3.0~3.3V/2A 一个 赠送
RFID 读写模块 一块
RFID 读写天线 (单独选配)
1、3dBi PCB MMCX口 UHF 天线:尺寸 4.5cm*4.1cm
http://item.taobao.com/item.htm?spm=a1z10.5.w4002-3535073328.12.Dejdh5&id=13640879646
2、5dBi PCB MMCX口 UHF 天线:尺寸 10cm * 10cm
http://item.taobao.com/item.htm?spm=a1z10.5.w4002-3535073328.18.Dejdh5&id=23426460127
3、【推荐!!】8dBi 板状定向圆极化 MMCX口 UHF 天线:尺寸 22.5cm*22.5cm
http://item.taobao.com/item.htm?spm=a1z10.5.w4002-3535073328.15.Dejdh5&id=22075632296
与PC 机连接的通信电缆 一条 赠送
EPC UHF GEN2 电子标签 一个 赠送
RFID 读写器开发资料SDK及应用程序 赠送
更多资料、手册,在 http://arm.eleckits.com 下载频道 UHF RFID页面可以直接下载。
您还可以登陆 http://rfid.eleckits.com 下载更多相关资料。
发表评论
要发表评论,您必须先登录。