串口自发自收测试程序
sp_uart_test.c
1 #include <stdio.h> /*标准输入输出定义*/ 2 #include <stdlib.h> /*标准函数库定义*/ 3 #include <unistd.h> /*Unix标准函数定义*/ 4 #include <sys/types.h> /**/ 5 #include <sys/stat.h> /**/ 6 #include <fcntl.h> /*文件控制定义*/ 7 #include <termios.h> /*PPSIX终端控制定义*/ 8 #include <errno.h> /*错误号定义*/ 9 #include <pthread.h> 10 #include <signal.h> 11 #include <sys/ioctl.h> 12 13 typedef unsigned char uchar; 14 typedef unsigned int uint; 15 16 uchar LRC_Check(uchar *data, uchar length) 17 { 18 uchar i; uint k; 19 uchar result; 20 21 uchar lrcdata[length]; 22 for(i=1;i<length+1;i++) 23 { 24 if(data[i]>0x40) 25 lrcdata[i-1]=data[i]-0x41+10; 26 else 27 lrcdata[i-1]=data[i]-0x30; 28 } 29 30 k=0; 31 for(i=0;i<length/2;i++) 32 { 33 k+=(lrcdata[2*i]*16+lrcdata[2*i+1]); 34 } 35 36 k=k%256; 37 k=256-k; 38 result=k%256; 39 return result; 40 } 41 42 unsigned char LRC(uchar * data, int length) 43 { 44 uchar i; 45 uint k; 46 uchar result; 47 uint iCount = 0; 48 uint lrcValue = 0x00; 49 50 for(iCount=0;iCount<length;iCount++) 51 { 52 lrcValue=lrcValue^data[iCount]; 53 //printf("%02x\n",data[iCount]); 54 } 55 56 result=lrcValue; 57 return(result); 58 } 59 60 #define FALSE 0 61 #define TRUE 1 62 int uart_fd; 63 pthread_t g_tid; 64 65 66 int speed_arr[] = {B460800, B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300}; 67 int name_arr[] = {460800, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300}; 68 void set_speed(int fd, int speed) 69 { 70 int i; 71 int status; 72 struct termios Opt; 73 tcgetattr(fd, &Opt); 74 for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) 75 { 76 if (speed == name_arr[i]) 77 { 78 tcflush(fd, TCIOFLUSH); 79 cfsetispeed(&Opt, speed_arr[i]); 80 cfsetospeed(&Opt, speed_arr[i]); 81 status = tcsetattr(fd, TCSANOW, &Opt); 82 if (status != 0) 83 perror("tcsetattr fd1"); 84 return; 85 } 86 tcflush(fd,TCIOFLUSH); 87 } 88 } 89 /** 90 *@brief 设置串口数据位,停止位和效验位 91 *@param fd 类型 int 打开的串口文件句柄* 92 *@param databits 类型 int 数据位 取值 为 7 或者8* 93 *@param stopbits 类型 int 停止位 取值为 1 或者2* 94 *@param parity 类型 int 效验类型 取值为N,E,O,,S 95 */ 96 int set_Parity(int fd,int databits,int stopbits,int parity) 97 { 98 struct termios options; 99 if ( tcgetattr( fd,&options) != 0) 100 { 101 perror("SetupSerial 1"); 102 return(FALSE); 103 } 104 options.c_cflag &= ~CSIZE; 105 /** 106 如果不是开发终端之类的,只是串口传输数据,而不需要串口来处理,那么使用原始模式(Raw Mode)方式来通讯,设置方式如下 107 **/ 108 options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/ 109 options.c_iflag &= ~(ICRNL | IXON | IXOFF); 110 options.c_oflag &= ~OPOST; /*Output*/ 111 switch (databits) /*设置数据位数*/ 112 { 113 case 7: 114 options.c_cflag |= CS7; 115 break; 116 case 8: 117 options.c_cflag |= CS8; 118 break; 119 default: 120 fprintf(stderr,"Unsupported data size\n"); 121 return (FALSE); 122 } 123 switch (parity) 124 { 125 case 'n': 126 case 'N': 127 options.c_cflag &= ~PARENB; /* Clear parity enable */ 128 options.c_iflag &= ~INPCK; /* Enable parity checking */ 129 break; 130 case 'o': 131 case 'O': 132 options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ 133 options.c_iflag |= INPCK; /* Disnable parity checking */ 134 break; 135 case 'e': 136 case 'E': 137 options.c_cflag |= PARENB; /* Enable parity */ 138 options.c_cflag &= ~PARODD; /* 转换为偶效验*/ 139 options.c_iflag |= INPCK; /* Disnable parity checking */ 140 break; 141 case 'S': 142 case 's': /*as no parity*/ 143 options.c_cflag &= ~PARENB; 144 options.c_cflag &= ~CSTOPB; 145 break; 146 default: 147 fprintf(stderr,"Unsupported parity\n"); 148 return (FALSE); 149 } 150 /* 设置停止位*/ 151 switch (stopbits) 152 { 153 case 1: 154 options.c_cflag &= ~CSTOPB; 155 break; 156 case 2: 157 options.c_cflag |= CSTOPB; 158 break; 159 default: 160 fprintf(stderr,"Unsupported stop bits\n"); 161 return (FALSE); 162 } 163 /* Set input parity option */ 164 if (parity != 'n') 165 options.c_iflag |= INPCK; 166 options.c_cc[VTIME] = 15; // 15 seconds 167 options.c_cc[VMIN] = 0; 168 169 tcflush(fd,TCSANOW); /* Update the options and do it NOW */ 170 171 if(ioctl(fd, TIOCEXCL, 0) < 0) { 172 printf("TIOCEXCL err\n"); 173 } 174 175 if (tcsetattr(fd,TCSADRAIN,&options) != 0) 176 { 177 perror("SetupSerial 3"); 178 return (FALSE); 179 } 180 return (TRUE); 181 } 182 /** 183 *@breif 打开串口 184 */ 185 int OpenDev(char *Dev) 186 { 187 int fd = open( Dev, O_RDWR| O_NOCTTY);// | O_NDELAY ); 188 if (-1 == fd) 189 { /*设置数据位数*/ 190 perror("Can't Open Serial Port"); 191 return -1; 192 } 193 else 194 return fd; 195 196 } 197 198 void SendCommand(unsigned char *buf, int len) 199 { 200 int ret=0; 201 int total = len; 202 203 do 204 { 205 ret=write(uart_fd,buf,len); 206 if ( ret < 0 ) 207 break; 208 else 209 { 210 buf += ret; 211 len -= ret; 212 } 213 214 if ( len > 0 ) 215 { 216 printf("send again, data left:%d\n",len); 217 usleep(5000); 218 } 219 } while(len > 0); 220 221 printf(" --> send size:%d, ret=%d\n", total - len, ret); 222 } 223 224 //06 02 00 09 01 16 00 00 01 23 45 67 89 03 94 225 226 #define TEST_DATA_SIZE 2048 227 #define BUFFER_SIZE (TEST_DATA_SIZE * 2) 228 void main(void) 229 { 230 int nread=0,i; 231 int counts=0; 232 int max_data_size=0; 233 int time_last; 234 int time_now; 235 int np=0; 236 char *dev ="/dev/ttyS1"; 237 238 /* unsigned char data1[ ]={ 239 0x00,0x00,0x01, 0x23 ,0x45 ,0x67 ,0x89 ,0xab ,0xcd ,0xef ,}; 240 */ 241 242 unsigned char data1[TEST_DATA_SIZE]; 243 244 245 unsigned char tmp[BUFFER_SIZE]; 246 unsigned char revtmp[BUFFER_SIZE]; 247 248 struct package{ 249 unsigned char start; 250 unsigned short length; 251 unsigned short sn; 252 unsigned short cmd; 253 unsigned char *data;//[1018]; 254 unsigned char end; 255 unsigned char lrc; 256 }; 257 258 259 struct package pks; 260 261 #define PKS_HEAD_SIZE 5 262 263 pks.start=0x02; 264 pks.length=sizeof(data1); 265 pks.sn=0x01; 266 pks.cmd=0x16; 267 pks.data=data1; 268 pks.end=0x03; 269 270 tmp[0]=pks.start; 271 tmp[1]=pks.length>>8; 272 tmp[2]=pks.length; 273 tmp[3]=pks.sn; 274 tmp[4]=pks.cmd; 275 //memcpy(&tmp[5],data1,sizeof(data1)); 276 //tmp[3+pks.length]=pks.end; 277 //pks.lrc=LRC(&tmp[1],pks.length+3); 278 //tmp[4+pks.length]=pks.lrc; 279 280 //printf("%02x----l:%d\n",pks.lrc,pks.length ); 281 282 printf("S600 uart bridge!\n"); 283 284 //system("stty -F /dev/ttyS1 speed 115200 -brkint -icrnl -imaxbel -opost -isig -icanon -echo -echoe"); 285 286 /*for(i=0;i<pks.length+5;i++) 287 { 288 printf("%02x\n",tmp[i]); 289 } 290 */ 291 292 uart_fd = OpenDev(dev); 293 if (uart_fd > 0 ) 294 set_speed(uart_fd,115200*4); 295 else 296 { 297 printf("Can't Open Serial Port!\n"); 298 exit(0); 299 } 300 301 if (set_Parity(uart_fd,8,1,'N')== FALSE) 302 { 303 printf("Set Parity Error\n"); 304 exit(1); 305 } 306 307 while(1) 308 { 309 SEND: 310 //usleep(1000*100); 311 pks.length = TEST_DATA_SIZE / 2 + rand() % 256; 312 pks.sn = counts & 0xff;; 313 314 tmp[1]=pks.length>>8; 315 tmp[2]=pks.length; 316 tmp[3] = pks.sn; //pkg.sn 317 318 for(i=0;i<sizeof(data1);i++) 319 { 320 data1[i]= i + tmp[3]; 321 } 322 323 memcpy(&tmp[PKS_HEAD_SIZE],data1,sizeof(data1)); 324 tmp[5+pks.length]=pks.end; 325 pks.lrc=LRC(&tmp[1],pks.length+3); 326 tmp[6+pks.length]=pks.lrc; 327 328 printf("NO:%d\n", counts); 329 SendCommand(tmp,pks.length+PKS_HEAD_SIZE); 330 counts++; 331 332 333 time_last = time(NULL); 334 np = 0; 335 // printf(" <--"); 336 READ: 337 338 nread = read(uart_fd,&revtmp[np],BUFFER_SIZE - np); 339 if(nread>0) 340 { 341 np=np+nread; 342 // printf("."); 343 } 344 345 time_now = time(NULL); 346 347 if((np>=pks.length+PKS_HEAD_SIZE) || (time_now - time_last) > 5) 348 { 349 if ( np > max_data_size ) 350 max_data_size = np; 351 352 printf(" <-- recv max %d, recv %d\n",max_data_size,np); 353 354 if(memcmp(tmp,&revtmp,pks.length+PKS_HEAD_SIZE)) 355 { 356 357 for(i=0;i<np;i++) 358 { 359 printf("%02x ",revtmp[i]); 360 if (i % 32 == 31 ) 361 printf("\n"); 362 } 363 printf("\n"); 364 printf("****************** check erro!*****************\n"); 365 for ( i = 0; i < np; i++ ) 366 { 367 if ( tmp[i] != revtmp[i] ) { 368 printf("error data index:%d, send value:0x%x, recv value:0x%x\n", i, tmp[i], revtmp[i] ); 369 } 370 371 } 372 printf("\n"); 373 break; 374 } 375 np=0; 376 printf("\n"); 377 goto SEND; 378 } 379 else 380 { 381 goto READ; 382 } 383 384 } 385 386 }
Android.mk
1 LOCAL_PATH:= $(call my-dir) 2 3 include $(CLEAR_VARS) 4 5 LOCAL_MODULE:= uart_test 6 7 LOCAL_SRC_FILES := \ 8 sp_uart_test.c 9 10 include $(BUILD_EXECUTABLE)