串口以及USB转串口收发程序(16进制数的读取发送)
2014-04-16 11:23
791 查看
工作中遇到一个问题,利用串口发送一串16进制数,每一个16进制数占8位,所以可以使用char类型buf数组来作为接发缓冲,注意点,读取时fscanf()中,类型使用“%x” 表示为一个16进制数。
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<errno.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define FALSE -1
#define TRUE 0
/*
* 串口配置 波特率,停止位,数据位,校验位
*/
int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300};
long name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200, 300};
void set_speed(int fd, long speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
bzero(&Opt,sizeof(struct termios)); //clear
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) {
printf("tcsetattr fd\n");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0) {
perror("SetupSerial 1");
return(FALSE);
}
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 (FALSE);
}
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 (FALSE);
}
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] = 0; //read 0s//读取的等待时间,一般为0
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
int main(){
printf("This program updates last time at %s %s\n",__TIME__,__DATE__);
printf("---------SERIAL PORT TEST PROGRAM-------\n");
int fd;
int a = 3,b;
char buf[20]={0};
while((a != 1)&&(a != 2))
{
printf("which kind of COM do you want to test?\n1(USB to COM)\t2(common COM)\tother number(exit)\n");
scanf("%d",&a);
switch(a)
{
case 1:
system("clear");
printf("please input the Number of USB to COM ( 0 ~ 8 )\n");
scanf("%d",&b);
switch(b)
{ //读写权限,不作为系统终端命令行,不关心另一端口的状态 不添加后2项,会导致程序最后设备无法正常关闭
case 0:fd = open("/dev/ttyUSB0",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 1:fd = open("/dev/ttyUSB1",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 2:fd = open("/dev/ttyUSB2",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 3:fd = open("/dev/ttyUSB3",O_RDWR|O_NOCTTY|O_NDELAY);break;
default:
printf("bad USB-COM port!\n");
exit(1);
break;
}
break;
case 2:
system("clear");
printf("please input the Number of common COM( 0~3 )\n");
scanf("%d",&b);
switch(b)
{
case 0:fd = open("/dev/ttySAC0",O_RDWR);break; //该串口为命令行!
case 1:fd = open("/dev/ttySAC1",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 2:fd = open("/dev/ttySAC2",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 3:fd = open("/dev/ttySAC3",O_RDWR|O_NOCTTY|O_NDELAY);break;
default:
printf("bad SAC-COM port!\n");
exit(2);
break;
}
break;
default:
printf("exit!\n");
exit(0);
}
}
if(fd < 0)
{
printf("open device error!\n");
return -1;
}else{
printf("open ");
printf("%s",ttyname(fd));
printf(" succesfully\n");
printf("fd = %d\n",fd);
}
int in_buad;
int data_bits;
int stop_bits;
int parity_bits;
do{ //设置波特率
printf("please input baud rate:115200,38400,19200,9600,4800,2400,1200\n");
scanf("%d",&in_buad);
}while(in_buad!=115200&&in_buad!=38400&&in_buad!=19200&&in_buad!=9600&&in_buad!=4800&&in_buad!=2400&&in_buad!=1200);
//设置数据位
/* do{
printf("please input data bits:7 ,8 , 9(exit)\n");
scanf("%d",&data_bits);
}while(data_bits!=7&&data_bits!=8&&data_bits!=9);
if(data_bits == 9)
return 11;
//设置停止位
do{
printf("please input the stop bits:1 ,2 ,9(exit)\n");
scanf("%d",&stop_bits);
}while(stop_bits!=1&&stop_bits!=2&&stop_bits!=9);
if(stop_bits == 9)
return 12;
//设置校验位
do{
printf("please choose the parity check:1(none), 2(ODD), 3(EVE), 9(exit)\n");
scanf("%d",&parity_bits);
}while(parity_bits!=1&&parity_bits!=2&&parity_bits!=3&&parity_bits!=9);
if(parity_bits == 9)
return 13;
char ch_parity;
switch(parity_bits){
case 1:ch_parity = 'N';break;
case 2:ch_parity = 'O';break;
case 3:ch_parity = 'E';break;
default:printf("select parity bits error!\n");
exit(-1);
}
*/
// set_speed(fd,in_buad);
// if (set_Parity(fd,data_bits,stop_bits,ch_parity) == FALSE) {
set_speed(fd,in_buad); //此处为已确定波特率,数据位,停止位,校验位
if(set_Parity(fd,8,1,'N') == FALSE)
{
printf("Set Parity Error\n");
exit (0);
}
int len = 0;
char sbuf[100]={0};
char rbuf[BUFSIZ]={0};
int ret,i;
int now=0;
int loop = 1;
while(loop--)
{
FILE *fp; //读取文件中的内容发送至对应串口
fp = fopen("cmd.txt","r");
if(fp==NULL)
exit(0);
int readlen = 0;
printf("send:\n");
while(!feof(fp))
{
//fseek(fp,len,SEEK_SET);
if((readlen = fscanf(fp,"%x",&sbuf[now]))>=0) //读取文件中的16进制数!例如0xAA 0x55
{
len += readlen;
//len += fread(&sbuf[now],sizeof(char)*2,1,fp);
printf("%x ",sbuf[now]);
now++;
}
}
printf("\n");
fclose(fp);
printf("len = %d\n",len);
len = write(fd,sbuf,len);
if(len < 0)
{
printf("send failed!\n");
}else{
printf("recv:");
sleep(3);
//防止数据接收不完整
while((ret = read(fd,rbuf,BUFSIZ))>0)//非阻塞读取
{
//printf("recv_len = %d,recv:\n",ret);
rbuf[ret+1]='\0';
for(i=0;i<ret;i++)
{
printf("%x ",rbuf[i]);
}
}
printf("\n");
}
len = 0;
memset(sbuf,0,sizeof(sbuf));
memset(rbuf,0,BUFSIZ);
}
if(close(fd)) //判断是否关闭成功,成功返回0,失败返回-1
{
printf("close fail\n");
}
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<termios.h>
#include<errno.h>
#include<string.h>
#include<sys/socket.h>
#include<netinet/in.h>
#define FALSE -1
#define TRUE 0
/*
* 串口配置 波特率,停止位,数据位,校验位
*/
int speed_arr[] = {B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300};
long name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400, 1200, 300};
void set_speed(int fd, long speed)
{
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
bzero(&Opt,sizeof(struct termios)); //clear
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) {
printf("tcsetattr fd\n");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
int set_Parity(int fd,int databits,int stopbits,int parity)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0) {
perror("SetupSerial 1");
return(FALSE);
}
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 (FALSE);
}
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 (FALSE);
}
switch (stopbits)
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
fprintf(stderr,"Unsupported stop bits\n");
return (FALSE);
}
/* Set input parity option */
if (parity != 'n')
options.c_iflag |= INPCK;
tcflush(fd,TCIFLUSH);
options.c_cc[VTIME] = 0; //read 0s//读取的等待时间,一般为0
options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0)
{
perror("SetupSerial 3");
return (FALSE);
}
return (TRUE);
}
int main(){
printf("This program updates last time at %s %s\n",__TIME__,__DATE__);
printf("---------SERIAL PORT TEST PROGRAM-------\n");
int fd;
int a = 3,b;
char buf[20]={0};
while((a != 1)&&(a != 2))
{
printf("which kind of COM do you want to test?\n1(USB to COM)\t2(common COM)\tother number(exit)\n");
scanf("%d",&a);
switch(a)
{
case 1:
system("clear");
printf("please input the Number of USB to COM ( 0 ~ 8 )\n");
scanf("%d",&b);
switch(b)
{ //读写权限,不作为系统终端命令行,不关心另一端口的状态 不添加后2项,会导致程序最后设备无法正常关闭
case 0:fd = open("/dev/ttyUSB0",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 1:fd = open("/dev/ttyUSB1",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 2:fd = open("/dev/ttyUSB2",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 3:fd = open("/dev/ttyUSB3",O_RDWR|O_NOCTTY|O_NDELAY);break;
default:
printf("bad USB-COM port!\n");
exit(1);
break;
}
break;
case 2:
system("clear");
printf("please input the Number of common COM( 0~3 )\n");
scanf("%d",&b);
switch(b)
{
case 0:fd = open("/dev/ttySAC0",O_RDWR);break; //该串口为命令行!
case 1:fd = open("/dev/ttySAC1",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 2:fd = open("/dev/ttySAC2",O_RDWR|O_NOCTTY|O_NDELAY);break;
case 3:fd = open("/dev/ttySAC3",O_RDWR|O_NOCTTY|O_NDELAY);break;
default:
printf("bad SAC-COM port!\n");
exit(2);
break;
}
break;
default:
printf("exit!\n");
exit(0);
}
}
if(fd < 0)
{
printf("open device error!\n");
return -1;
}else{
printf("open ");
printf("%s",ttyname(fd));
printf(" succesfully\n");
printf("fd = %d\n",fd);
}
int in_buad;
int data_bits;
int stop_bits;
int parity_bits;
do{ //设置波特率
printf("please input baud rate:115200,38400,19200,9600,4800,2400,1200\n");
scanf("%d",&in_buad);
}while(in_buad!=115200&&in_buad!=38400&&in_buad!=19200&&in_buad!=9600&&in_buad!=4800&&in_buad!=2400&&in_buad!=1200);
//设置数据位
/* do{
printf("please input data bits:7 ,8 , 9(exit)\n");
scanf("%d",&data_bits);
}while(data_bits!=7&&data_bits!=8&&data_bits!=9);
if(data_bits == 9)
return 11;
//设置停止位
do{
printf("please input the stop bits:1 ,2 ,9(exit)\n");
scanf("%d",&stop_bits);
}while(stop_bits!=1&&stop_bits!=2&&stop_bits!=9);
if(stop_bits == 9)
return 12;
//设置校验位
do{
printf("please choose the parity check:1(none), 2(ODD), 3(EVE), 9(exit)\n");
scanf("%d",&parity_bits);
}while(parity_bits!=1&&parity_bits!=2&&parity_bits!=3&&parity_bits!=9);
if(parity_bits == 9)
return 13;
char ch_parity;
switch(parity_bits){
case 1:ch_parity = 'N';break;
case 2:ch_parity = 'O';break;
case 3:ch_parity = 'E';break;
default:printf("select parity bits error!\n");
exit(-1);
}
*/
// set_speed(fd,in_buad);
// if (set_Parity(fd,data_bits,stop_bits,ch_parity) == FALSE) {
set_speed(fd,in_buad); //此处为已确定波特率,数据位,停止位,校验位
if(set_Parity(fd,8,1,'N') == FALSE)
{
printf("Set Parity Error\n");
exit (0);
}
int len = 0;
char sbuf[100]={0};
char rbuf[BUFSIZ]={0};
int ret,i;
int now=0;
int loop = 1;
while(loop--)
{
FILE *fp; //读取文件中的内容发送至对应串口
fp = fopen("cmd.txt","r");
if(fp==NULL)
exit(0);
int readlen = 0;
printf("send:\n");
while(!feof(fp))
{
//fseek(fp,len,SEEK_SET);
if((readlen = fscanf(fp,"%x",&sbuf[now]))>=0) //读取文件中的16进制数!例如0xAA 0x55
{
len += readlen;
//len += fread(&sbuf[now],sizeof(char)*2,1,fp);
printf("%x ",sbuf[now]);
now++;
}
}
printf("\n");
fclose(fp);
printf("len = %d\n",len);
len = write(fd,sbuf,len);
if(len < 0)
{
printf("send failed!\n");
}else{
printf("recv:");
sleep(3);
//防止数据接收不完整
while((ret = read(fd,rbuf,BUFSIZ))>0)//非阻塞读取
{
//printf("recv_len = %d,recv:\n",ret);
rbuf[ret+1]='\0';
for(i=0;i<ret;i++)
{
printf("%x ",rbuf[i]);
}
}
printf("\n");
}
len = 0;
memset(sbuf,0,sizeof(sbuf));
memset(rbuf,0,BUFSIZ);
}
if(close(fd)) //判断是否关闭成功,成功返回0,失败返回-1
{
printf("close fail\n");
}
return 0;
}
相关文章推荐
- QT5 串口(com)通信_16进制数发送与接收以及接收数据提取
- QT串口程序已16进制接受和发送数据
- C#串口介绍以及简单串口通信程序设计实现
- C#串口介绍以及简单串口通信程序设计实现
- 串口通信程序中十六进制格式发送和接收实现
- WinCE 6.0 增加IOCTL以及在应用中读取调试串口输入
- ATK-NEO-6M GPS模块实验(STM32F10X,中移物联网麒麟座开发板)串口4,DMA读取程序源码
- C++的一个split小程序以及csv读取方式
- [CSR8] 分享一个CSR8670串口收发程序
- STM32学习笔记3——怎样将整型变量转换为字符变量 然后串口 或者LCD发送出来(STM32) 以及sprintf的用法
- Java串口编程:串口数据的发送与监听读取
- 一个串口通信程序,适用于3g模块发送简单AT指令
- [源码]51单片机读取MPU6050通过串口发送——源码
- linux串口收发程序
- CC2540 OSAL 学习其中原理,以及 给任务 添加 一个事件(定时发送串口消息)
- 发送邮件程序报错454 Authentication failed以及POP3和SMTP简介
- WinCE 6.0 增加IOCTL以及在应用中读取调试串口输入
- JAVA 编写的串口 读写 程序 以及乱码程序
- 垃圾引用防治补丁以及发送引用修正补丁的自动安装程序
- TX2平台下can总线收发功能的实现(三)——发送队列异步io接收程序