赞
踩
目录
经过几个星期对RFID的学习,完成了一个关于RFID的项目,本项目用到的模块有gec6818开发板,一个高频RFID,一个高频RFID读卡器,一个蓝牙模块。根据RFID实现用户注册功能,记录一些用户的基本信息,如姓名、部门单位、工牌号等,信息存储在一个文件中。每次运行程序都会读取之前保存的信息。打卡功能:用户进入和离开办公室需要刷卡,LCD显示打开房间门。刷卡时会显示基本信息,记录上下班打卡时间,语音播报,显示用户基本信息,并通过蓝牙模块通知手机。家电管理功能:第一个员工进入办公室,会使用驱动程序打开gec6816的led灯;最后一个员工离开办公室时,会使用驱动程序关闭所有灯光。
1 GND 地
2 VCC +5v
3 TXD 串口输出
4 TRD 串口输入
6818串口con2 低频RFID阅读器
VCC------------------------VCC
GND-----------------------GND
RX ------------------------- TX
TX—————————RX
1、 请求(CMD=A)
命令类型:0x02
命令:‘A‘
数据长度:1
数据信息:0x26—IDLE,0x52—ALL
代码如下
- int PiccRequest(int fd)
- {
- int ret;
- unsigned char tx_buf[7];//存放要发送的数据
- tx_buf[0]=0x07;//命令长度
- tx_buf[1]=0x02;//命令类型
- tx_buf[2]='A';//命令
- tx_buf[3]=0x01;//数据长度
- tx_buf[4]=0x52;//请求模式
- tx_buf[5]=CalBCC(tx_buf,tx_buf[0]-2);//校验
- tx_buf[6]=0x03;//结束
-
- write(fd,tx_buf,7);//发送数据给从机
- usleep(50000);//延时
- ret=read(fd,rt_buf,8);//接收从机应答消息
- if(ret<0)//接收返回值小于0接收失败
- {
- printf("read err\n");
- return 1;
- }
- if(ret==8)//接收到长度8的数据
- {
- if(rt_buf[2]==0x00)//判断status位为0表示成功
- {
- return 0;
- }
- }
- return 1;
- }
2、 防碰撞
命令类型:0x02
命令:‘B‘
数据长度:计数位=0,长度=2;计数位!=0,长度=6
数据信息:0x93——一级防碰撞 0x95——二级防碰撞 0x97——三级防碰撞
代码如下
- int PiccAnticoll(int fd)
- {
- int ret;
- unsigned char tx_buf[8];//存放要发送的数据
- int card_ID=0;
- tx_buf[0]=0x08;//命令长度
- tx_buf[1]=0x02;//命令类型
- tx_buf[2]='B';//命令
- tx_buf[3]=0x02;//数据长度
- tx_buf[4]=0x93;//碰撞级别选择1级
- tx_buf[5]=0x00;
- tx_buf[6]=CalBCC(tx_buf,tx_buf[0]-2);//校验
- tx_buf[7]=0x03;//结束
-
- write(fd,tx_buf,8);//发送数据给从机
- usleep(50000);//延时
- ret=read(fd,rt_buf,10);//接收从机应答消息
- if(ret<0)//接收返回值小于0接收失败
- {
- printf("read err\n");
- return 1;
- }
- if(ret==10)//接收到长度10的数据
- {
- if(rt_buf[2]==0x00)//判断status位为0表示成功
- {
- card_ID=(rt_buf[7]<<24)|(rt_buf[6]<<16)|(rt_buf[5]<<8) |rt_buf[4];//读取buf中数据
- printf("ID=%x\n",card_ID);
- return 0;
- }
- }
- return 1;
- }
- int uart1_init()
- {
- int uart1_fd= open("/dev/ttySAC1", O_RDWR);//打开串口1设备文件
- if (uart1_fd == -1)
- {
- perror("open error:");
- return -1;
- }
- struct termios myserial;
- memset(&myserial, 0, sizeof (myserial));//清空结构体
- myserial.c_cflag |= (CLOCAL | CREAD);//O_RDWR
- //设置控制模式状态,本地连接,接受使能
- //设置 数据位
- myserial.c_cflag &= ~CSIZE; //清空数据位
- myserial.c_cflag &= ~CRTSCTS; //无硬件流控制
- myserial.c_cflag |= CS8; //数据位:8
- myserial.c_cflag &= ~CSTOPB;// //1位停止位
- myserial.c_cflag &= ~PARENB; //不要校验
- cfsetospeed(&myserial, B9600); //设置波特率,B9600是定义的宏
- cfsetispeed(&myserial, B9600);
- tcflush(uart1_fd, TCIFLUSH);/* 刷新输出队列,清楚正接受的数据 */
- tcsetattr(uart1_fd, TCSANOW, &myserial);/* 改变配置 */
- return uart1_fd;
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <errno.h>
- #include <termios.h>
-
- unsigned char rt_buf[10];//存放接收数据
-
- //串口初始化
- int uart1_init()
- {
-
- int uart1_fd= open("/dev/ttySAC1", O_RDWR);//打开串口1设备文件
- if (uart1_fd == -1)
- {
- perror("open error:");
- return -1;
- }
-
- struct termios myserial;
-
- memset(&myserial, 0, sizeof (myserial));//清空结构体
-
- myserial.c_cflag |= (CLOCAL | CREAD);//O_RDWR
-
- //设置控制模式状态,本地连接,接受使能
- //设置 数据位
- myserial.c_cflag &= ~CSIZE; //清空数据位
- myserial.c_cflag &= ~CRTSCTS; //无硬件流控制
- myserial.c_cflag |= CS8; //数据位:8
-
- myserial.c_cflag &= ~CSTOPB;// //1位停止位
- myserial.c_cflag &= ~PARENB; //不要校验
-
- cfsetospeed(&myserial, B9600); //设置波特率,B9600是定义的宏
- cfsetispeed(&myserial, B9600);
-
- tcflush(uart1_fd, TCIFLUSH);/* 刷新输出队列,清楚正接受的数据 */
-
- tcsetattr(uart1_fd, TCSANOW, &myserial);/* 改变配置 */
- return uart1_fd;
- }
-
- //校验
- unsigned char CalBCC(unsigned char *buf,int n)
- {
- int i;
- unsigned char bcc=0;
- for(i=0;i<n;i++)
- {
- bcc^=*(buf+i);
- }
- return (~bcc);
- }
-
- //申请请求
- int PiccRequest(int fd)
- {
- int ret;
- unsigned char tx_buf[7];//存放要发送的数据
- tx_buf[0]=0x07;//命令长度
- tx_buf[1]=0x02;//命令类型
- tx_buf[2]='A';//命令
- tx_buf[3]=0x01;//数据长度
- tx_buf[4]=0x52;//请求模式
- tx_buf[5]=CalBCC(tx_buf,tx_buf[0]-2);//校验
- tx_buf[6]=0x03;//结束
-
- write(fd,tx_buf,7);//发送数据给从机
- usleep(50000);//延时
- ret=read(fd,rt_buf,8);//接收从机应答消息
- if(ret<0)//接收返回值小于0接收失败
- {
- printf("read err\n");
- return 1;
- }
- if(ret==8)//接收到长度8的数据
- {
- if(rt_buf[2]==0x00)//判断status位为0表示成功
- {
- return 0;
- }
- }
- return 1;
- }
-
- //防碰撞
- int PiccAnticoll(int fd)
- {
- int ret;
- unsigned char tx_buf[8];//存放要发送的数据
- int card_ID=0;
- tx_buf[0]=0x08;//命令长度
- tx_buf[1]=0x02;//命令类型
- tx_buf[2]='B';//命令
- tx_buf[3]=0x02;//数据长度
- tx_buf[4]=0x93;//碰撞级别选择1级
- tx_buf[5]=0x00;
- tx_buf[6]=CalBCC(tx_buf,tx_buf[0]-2);//校验
- tx_buf[7]=0x03;//结束
-
- write(fd,tx_buf,8);//发送数据给从机
- usleep(50000);//延时
- ret=read(fd,rt_buf,10);//接收从机应答消息
- if(ret<0)//接收返回值小于0接收失败
- {
- printf("read err\n");
- return 1;
- }
- if(ret==10)//接收到长度10的数据
- {
- if(rt_buf[2]==0x00)//判断status位为0表示成功
- {
- card_ID=(rt_buf[7]<<24)|(rt_buf[6]<<16)|(rt_buf[5]<<8) |rt_buf[4];//读取buf中数据
- printf("ID=%x\n",card_ID);
- return 0;
- }
- }
- return 1;
- }
-
- int main()
- {
- int fd=uart1_init();//串口初始化
- while(1)
- {
- if(PiccRequest(fd))//请求
- {
- continue;
- }
- if(PiccAnticoll(fd))//防碰撞
- {
- continue;
- }
- }
- colse(fd);//关闭文件
- return 0;
- }
由宽x=800,高y=480个像素点组成
在Linux中一切皆文件
LCD屏同样是一个文件: /dev/fb0
fb:Frame Buffer 帧缓存,也叫做显存
帧缓存的每一个存储单元对应一个像素,整个帧缓存就对应一副图像
像素:描述组成图像的每一个点的颜色值
颜色:在计算机系统中,颜色常见的是由RGB三基色组成的24位整数值表示
用符号描述为:0x00RRGGBB
即:
bit16 ~ bit23 这8个bit位表示红色分量
bit8 ~ bit15 这8个bit位表示绿色分量
bit0 ~ bit7 这8个bit位表示蓝色分量
相关函数1、void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);//地址映射
2、int munmap(void *addr, size_t length); //地址释放映射
映射后,mmap的返回值(plcd)就是映射空间的首地址,对于映射屏幕来说,指针plcd指向的就是第一个像素点,给该地址存入数据,就是给对于的像素点显示颜色。因此 *plcd = 0x00ff00; 就是给第一个像素点显示了绿色
- int *plcd=NULL;
- int lcd_fd;
- int lcd_init()
- {
- lcd_fd=open("/dev/fb0",O_RDWR);//打开lcd控制文件
- if(lcd_fd==-1)
- {
- perror("open lcd err\n");
- return -1;
- }
-
- plcd=mmap(NULL,800*480*4,PROT_READ|PROT_WRITE,MAP_SHARED,lcd_fd,0);//地址映射
- if(MAP_FAILED==plcd)
- {
- perror("mmap erro\n");
- return -1;
- }
- return 0;
- }
- //lcd画点
- void lcd_draw_point(int x,int y,int color)
- {
- *(plcd+y*800+x)=color;
- }
-
- //清屏
- void lcd_clear(int color)
- {
- int x,y;
- for(y=0;y<480;y++)
- {
- for(x=0;x<800;x++)
- lcd_draw_point(x,y,color);
- }
- }
-
- //显示单个字符
- void show_word(unsigned char word[],int width,int length,int x0,int y0,unsigned int color)
- {
- int i,j,k;
- int x;
- for(i=0;i<length;i++)
- {
- x=word[i];
- //printf("%x\n",x);
- for(k=7;k>=0;k--)
- {
- if(x&0x01<<k)
- lcd_draw_point(x0+(7-k)+(i%(width/8)*8),y0+(i/(width/8)),color);
- }
- }
- }
- //显示图片
- void lcd_show_bmp(int x,int y,char *bmpname)
- {
- unsigned char buf[4];
- int fd=open(bmpname,O_RDWR);
- if(fd==-1){
- perror("open bmp file err\n");
- return ;
- }
- //读魔数
- lseek(fd,0,SEEK_SET);
- read(fd, buf, 2);
- if(buf[0]!=0x42 || buf[1]!=0x4D)
- {
- printf("this picture is not bmo!\n");
- return ;
- }
- //读位图宽度
- int bmp_w=0;
- lseek(fd, 0x12, SEEK_SET);
- read(fd,&bmp_w,4);
- //读位图高度
- int bmp_h=0;
- lseek(fd,0x16,SEEK_SET);
- read(fd,&bmp_h,4);
- //读图片色深
- int bmp_colordepath=0;
- lseek(fd, 0x1c, SEEK_SET);
- read(fd,&bmp_colordepath,2);
- printf("bmp:%d*%d*%d\n",bmp_w,bmp_h,bmp_colordepath);
- //读像素数组
- lseek(fd,54, SEEK_SET);
- int i,j;
- for(i=0;i<bmp_h;i++)
- {
- for(j=0;j<bmp_w;j++)
- {
- int color=0;
- read(fd, &color, bmp_colordepath/8);
- lcd_draw_point(x+j,y+(bmp_h>0?(bmp_h-i-1):i),color);
- }
- lseek(fd, (4-bmp_colordepath/8*bmp_w%4)%4,SEEK_CUR);
- }
- //printf("i=%d,j=%d\n",x+j,y+(bmp_h>0?(bmp_h-i-1):i));
- close(fd);
- }
- int get_coordinate(int *x,int *y)
- {
- struct input_event et;
- int fd=open("/dev/input/event0",O_RDONLY);
- if(fd==-1)
- {
- perror("open event0 failed");
- return -1;
- }
- while (1)
- {
- int r=read(fd, &et, sizeof(et));
- if(r==sizeof(et))
- {
- if(et.type==EV_ABS && et.code==ABS_X)//保存x
- {
- *x=et.value;
- }
- if(et.type==EV_ABS && et.code==ABS_Y)//保存y
- {
- *y=et.value;
- }
- if(et.type==EV_KEY && et.code==BTN_TOUCH && et.value==0)//手指离开
- {
- close(fd);
- return 0;
- }
- }
- }
- }
- void write_user_to_file(FILE *fp)
- {
- int class=0;
- int number=0;
- char name[25];
- char str[124];
- printf("请输入class,number,name:\n");
- scanf("%d %d %s",&class,&number,name);
- sprintf(str,"%u %d %d %s\n",card_ID,class,number,name);//无符号整型写入
- fputs(str, fp);
-
- //更新用户信息
- users[num].card_id=card_ID;
- users[num].class=class;
- users[num].number=number;
- users[num].time_num=5;
- strcpy(users[num].name, name);
- num++;
- }
- FILE *delete_line(FILE *fp,unsigned int id)
- {
- FILE *ff;
- unsigned int id_bk=0;
- ff=fopen("./users_message_bk","at+");
- system("chmod 777 users_message_bk");//防止权限问题
- fseek(fp,0,SEEK_SET);
- while(fgets(data_buf,sizeof(data_buf),fp)!=NULL)
- {
- sscanf(data_buf,"%u",&id_bk);
- if(id_bk!=id)
- {
- fputs(data_buf,ff);
- //printf("id=%u,id_bk=%u\n",id,id_bk);//取值取无符号整型
- }
- }
- fclose(fp);
- remove("./users_message");
- fp=fopen("./users_message","at+");
- system("chmod 777 users_message");//防止权限问题
- fseek(ff,0,SEEK_SET);
- while(fgets(data_buf,sizeof(data_buf),ff)!=NULL)
- {
- fputs(data_buf,fp);
- }
- fclose(ff);
- remove("./users_message_bk");
- //更新用户信息
- num=0;
- fseek(fp,0,SEEK_SET);
- get_file_users_message();
- return fp;
- }
使用串口2
首先对串口2进行初始化
使用手机蓝牙助手与gec6818进行通信
效果如下
我使用的是gec6818驱动开发,对led的gpio进行高低电平的输出来控制led灯的亮灭
led测试代码如下
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/ioctl.h>
-
- /* ioctl: ./step_motor_test /dev/xxx type frequency
- */
-
- //定义LED的魔幻数
- #define MOTOR_forward _IO('x', 0)//正转
- #define MOTOR_backward _IO('x', 1)//逆转
-
- static int Power_10(int num)
- {
- int i,temp=1;
- for( i=0;i<num;i++)
- temp=temp*10;
- return temp;
- }
-
- int main(int argc, char **argv)
- {
- int fd,i=100;
- int len;
- unsigned int com,freq,num=0;
- char buf[5];
-
- if (argc < 4)
- {
- printf("Usage: \n");
- printf("%s <dev> type frequency\n", argv[0]);
- return -1;
- }
-
- // open
- fd = open(argv[1], O_RDWR);
- if (fd < 0)
- {
- printf("can not open file %s\n", argv[1]);
- return -1;
- }
-
- com=strtol(argv[2],NULL,0);
- freq=strtol(argv[3], NULL, 0);
- printf("com=%d,freq=%d\n",com,freq);
- if(com!=0 && com!=1)
- {
- printf("type=0 or 1\n");
- close(fd);
- return -1;
- }
- while(i--)
- {
- switch (com) {
- case 0:
- ioctl(fd,MOTOR_backward,freq);
- break;
- case 1:
- ioctl(fd,MOTOR_forward,freq);
- break;
- }
- //sleep(1);
- }
-
- // close
- close(fd);
- return 0;
- }
使用mplayer进行语音播报
经过这个小项目我获得了很多收获,对linux操作系统和RFID有了更加深刻的理解。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。