📄 ic.c
字号:
#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix标准函数定义*/
#include <sys/types.h> /**/
#include <sys/stat.h> /**/
#include <fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX终端控制定义*/
#include <errno.h> /*错误号定义*///#include <linux/delay.h>
char *dev ="/dev/ttyS0";//char *dev = "/home/ic/test";
int fd;int speed_arr[] = { B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, };int name_arr[] = {38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, };int mdelay(unsigned long i){ printf("......\n"); usleep( 1000*i ); usleep( 1000*i );// sleep(1); printf("^_^\n");}int OpenDev(char *Dev)
{
fd = open( Dev, O_RDWR | O_NOCTTY | O_NDELAY );
if (-1 == fd)
{ /*设置数据位数*/
perror("Can't Open Serial Port");
return -1;
}
else
{ fcntl(fd, F_SETFL, 0); printf("Open Serial Port\n"); return fd; }
}void set_speed(int fd, int speed){ int i; int status; struct termios Opt; tcgetattr(fd, &Opt); for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) { if (speed == name_arr[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); if (status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd,TCIOFLUSH); } }}/***@brief 设置串口数据位,停止位和效验位*@param fd 类型 int 打开的串口文件句柄*@param databits 类型 int 数据位 取值 为 7 或者8*@param stopbits 类型 int 停止位 取值为 1 或者2*@param parity 类型 int 效验类型 取值为N,E,O,,S*/int set_Parity(int fd,int databits,int stopbits,int parity){ struct termios options; if ( tcgetattr( fd,&options) != 0) { perror("SetupSerial 1"); return -1; } options.c_cflag &= ~CSIZE; switch (databits) /*设置数据位数*/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data size\n"); return -1; }switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* 转换为偶效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB;break; default: fprintf(stderr,"Unsupported parity\n"); return -1; } /* 设置停止位*/ switch (stopbits){ case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bits\n"); return -1; } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd,TCIFLUSH);options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/ options.c_cc[VMIN] = 0; /* Update the options and do it NOW */if (tcsetattr(fd,TCSANOW,&options) != 0) { perror("SetupSerial 3"); return -1; } return 0; }int InitSerialPort(){printf("open dev...\n"); fd = OpenDev(dev);printf("opened dev\n");// set_speed(fd,9600);// if (set_Parity(fd,8,2,'N') == -1) {// printf("Set Parity Error\n");// exit (0);// } struct termios options; tcgetattr(fd, &options); cfsetispeed(&options, B9600); cfsetospeed(&options, B9600);//波特率 options.c_cflag |= (CLOCAL | CREAD); options.c_cflag &= ~PARENB; options.c_cflag |= CSTOPB;//2位停止位 options.c_cflag &= ~CSIZE; options.c_cflag |= CS8;//8位数据位 options.c_cflag &= ~CRTSCTS; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/ //options.c_lflag &= ~(IXON | IXOFF | IXANY); options.c_oflag &= ~OPOST; /*Output*/ options.c_iflag &= ~(IXON | IXOFF | IXANY); //options.c_cc[VMIN]=0; //options.c_cc[VTIME]=10; tcsetattr(fd, TCSANOW, &options); return 0;}int InitIc(){ int j,i,status; //比较设备密码,不比较是不能操作设置的 //密码是736736,如果变动,写入数据也应变化 unsigned char buf[13]={0xaa,0xb5,0x00,0x08,0x80,0x00,0x00,0x01,0x82,0x73,0x67,0x36,0x36};//unsigned char buf[10]={0xaa,0xb9,0x00,0x05,0x80,0x00,0x00,0x00,0x00,0x96}; write(fd,buf,13);// printf("write over\n"); for( ; ; ) { if ( (status = read(fd,buf,5))!=-1 ) break; }// printf("status = %x\n",status); for( i=0; i<status; i++ ) { printf("%x, ", buf[i]); } if(buf[0]==0x55 && buf[1]==0x00 && buf[2]==0x00 && buf[3]==0x00 && buf[4]==0x55) printf("device password accepted\n"); //蜂鸣100ms unsigned char buf3[20]={0xaa,0xb4,0x00,0x07,0x80,0x00,0x00,0x00,0x00,0x00,0x0a,0x93}; write(fd,buf3,13); for( ; ; ) { if ( (status = read(fd,buf,5))!=-1 ) break; } for( i=0; i<status; i++ ) { printf("%x, ", buf[i]); } if(buf[0]==0x55 && buf[1]==0x00 && buf[2]==0x00 && buf[3]==0x00 && buf[4]==0x55) printf("Ring Ring\n"); //比较卡密码, 倒数第2,3,4位为六位的数字密码/* unsigned char buf2[20]={0xaa,0x64,0x00,0x08,0x79,0x00,0x00,0x00,0x00,0x55,0x11,0x11,0xea};
write(fd,buf2,13); read(fd,buf2,5); for( i=0; i<5; i++ ){ printf("%x, ", buf2[i]); }
if(buf2[0]==0x55 && buf2[1]==0x00 && buf2[2]==0x00 && buf2[3]==0x00 && buf2[4]==0x55)
printf("card password accepted\n");*/}
//将data写入开始单元为pos的length个单元
int WriteIc(int region, int pos, int length, unsigned char *data)
{
int i, j, status;
unsigned char *buf;
//动态分配空间, 实际大小为length+10, 其余预留
buf = malloc( sizeof(unsigned char)*(length+16) );
buf[0] = 0xaa;//通讯字头
buf[1] = 0x60;//操作码:读数据
buf[2] = 0;
buf[3] = 1+2+2+length;//数据长度
buf[4] = 0x6e;//卡型编号, 与实际使用相关
buf[5] = (region >> 8) & 0xff;
buf[6] = region & 0xff;//分区地址,与实际有关, 2字节
buf[7] = 0;
buf[8] = pos;//区内地址, 此处简化处理
for( i=0; i<length; i++ )
{
buf[9+i] = data[i];
}//操作数据
j = 0; for( i=0; i<length+9; i++ )
{
printf("%x, ", buf[i]); j ^= buf[i];
}
buf[9+length] = j;//异或和 printf("%x, ", j);
status = write( fd,buf,length+10 );
if( status == -1 )
{
perror("error write to IC!\n");
return -1;
} printf("write to IC! \n"); for( ; ; ) { if ( (status = read(fd,buf,length+5))!=-1 ) break; } for( i=0; i<status; i++ ){ printf("%x, ", buf[i]); } printf("\n"); if(buf[0]==0x55 && buf[1]==0x00 && buf[2]==0x00 && buf[3]==0x00 && buf[4]==0x55)
printf("Ic card writed\n");
return 0;
}
//返回值:len;
//将开始单元为pos的length个单元读入data, 实际读入len个单元
int ReadIc(int region, int pos, int length, unsigned char *data)
{
int i, j, len,status;
unsigned char *buf;
buf = malloc( sizeof(unsigned char)*(length + 15 ) );
// fd = OpenDev(dev);
buf[0] = 0xaa;//通讯字头
buf[1] = 0x61;//操作码:读数据
buf[2] = 0;
buf[3] = 1+2+2+2;//数据长度
buf[4] = 0x6e;//卡型编号, 与实际使用相关
buf[5] = (region >> 8) & 0xff;
buf[6] = region & 0xff;//分区地址,与实际有关, 2字节
buf[7] = 0;
buf[8] = pos;//区内地址, 此处简化处理, 2字节
buf[9] = 0;
buf[10] = length;//操作数据为长度值, 2字节
j = 0xaa;
for( i=1; i<11; i++ )
{
j ^= buf[i];
}
buf[11] = j;//异或和
write( fd,buf,12 );
mdelay(200);
//data格式:通讯字头+状态编号+数据长度+结果数据+异或和
// 1byte 1byte 2byte <=144byte 1byte for( ; ; ) { if ( (status = read(fd,buf,length+5))!=-1 ) break; } for( i=0; i<status; i++ ){ printf("%x ", buf[i]); } printf("\n"); printf("\n");
// if( buf[1] == 0x00 )
// {// printf("Ic card readed\n");
// }
len = buf[3];
for( i=0; i<len; i++ )
{
data[i] = buf[i+4];
}
return len;
}//返回值:len;
//将开始单元为pos的length个单元读入data, 实际读入len个单元
int ReadIc1byte(int region, int pos, unsigned char *data)
{
int i, j, len,status;
unsigned char *buf; int length = 1;
buf = malloc( sizeof(unsigned char)*(length + 15 ) );
// fd = OpenDev(dev);
buf[0] = 0xaa;//通讯字头
buf[1] = 0x61;//操作码:读数据
buf[2] = 0;
buf[3] = 1+2+2+2;//数据长度
buf[4] = 0x6e;//卡型编号, 与实际使用相关
buf[5] = (region >> 8) & 0xff;
buf[6] = region & 0xff;//分区地址,与实际有关, 2字节
buf[7] = 0;
buf[8] = pos;//区内地址, 此处简化处理, 2字节
buf[9] = 0;
buf[10] = length;//操作数据为长度值, 2字节
j = 0xaa;
for( i=1; i<11; i++ )
{
j ^= buf[i];
}
buf[11] = j;//异或和
write( fd,buf,12 );
mdelay(200);
//data格式:通讯字头+状态编号+数据长度+结果数据+异或和
// 1byte 1byte 2byte <=144byte 1byte for( ; ; ) { if ( (status = read(fd,buf,length+5))!=-1 ) break; } for( i=0; i<status; i++ ){ printf("%x ", buf[i]); } printf("\n");
data[0] = 0x55 ^ 0x1 ^ buf[5];
return len;
}
/*int WritePic( int length, unsigned char *buf )
{
unsigned char len[2] = {length, 0};
WriteIc( 0x20, 1, len );//将buffer长度写入第32个单元
WriteIc( 0x22, length, buf );//将buffer写入开始地址为第34个单元的length个单元
return 0;
}
int ReadPic( unsigned char *data )
{
unsigned char *buf;
int length;
ReadIc( 0x20, 1, buf );
length = buf[0];
ReadIc( 0x22, length, data );
return length;
}*/int main(){ int i; unsigned char data[300]; unsigned char buf[300]; InitSerialPort(); InitIc(); for( i=0; i<144; i++ ) { data[i] = i; }// WritePic(3, data);// WriteIc(2044, 128, 144, data);/* for(i = 0; i < 0x4; i++) { ReadIc(1, 128 + i, 1, &buf[i]); }*/ ReadIc1byte(0, 0x8, &buf[0]); ReadIc(0, 0, 150, buf); int count = 0; for( i=0; i<150; i++ ) { printf("%3x ",buf[i]); if( ++count == 16 ) { count = 0; printf("\n"); } } printf("\n"); printf("%x\n",buf[0]); close(fd); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -