#项目实现相关# | Linux、C | Ubuntu环境下用select单个串口传感器数据读写

#项目实现相关# | Linux、C | Ubuntu环境下select多路复用串口读写

目录

体温

结果图

代码

血氧传感器

效果图

代码


体温

结果图

代码

/*

体温

*/





#include <string.h>

#include <stdio.h>

#include <unistd.h>

#include <fcntl.h>

#include <stdlib.h>

#include <sys/types.h>

#include <termios.h>

#include <sys/stat.h>

 

 

#include <sys/stat.h>

#include <fcntl.h>

#include <termios.h>

#include <errno.h>

 

int set_opt(int ,int , int , char , int );

void main()

{

	int fd,nByte,len=0;

	unsigned char uartBodyTemperature[]={0XFF,0XC9,0X03,0XA3,0XA0};	//体温

	

	char *uart = "/dev/ttyUSB1";

	fd_set recv_fd;

	struct timeval tv;

	unsigned char buff[513];

	unsigned char *c;

	c = &buff;

	int i = 0,j=0;

	int res = 0;

	int cnt = 0;//发送计数

	int recv_flag=0;

	int CKSUM = 0;

	double temperature = 0;

	double temp_value[16];

	unsigned char temp_buf[16];



	//打开串口设备

	if((fd=open(uart,O_RDWR|O_NONBLOCK|O_NOCTTY))<0)

	{

		printf("open error\n");

	}else

	{

		printf("%s open success!",uart);

		//设置波特率等参数

		set_opt(fd,115200,8,'N',1);

		tv.tv_sec = 1;

		tv.tv_usec = 0;



		//进行写启动命令,仅一次即可

		if( (res = write(fd,uartBodyTemperature,sizeof(uartBodyTemperature)))<0) 	{

			perror("write:");

		}

		printf("write uartBodyTemperature command success!\n");

		printf("write %d bytes.\n", res);



		//大循环读取数据

		while(1){

			FD_ZERO(&recv_fd);

			FD_SET(fd, &recv_fd);



			while(FD_ISSET(fd, &recv_fd)){

				if(select(fd+1, &recv_fd, NULL, NULL, NULL) < 0 ){

					printf("select error\n");

				}else{

					read(fd,c,1);

					 printf("%02X %02d   ",*c,len);

					buff[len] = *c;



					if (len > 7)

					{

						//判断是否接受到正确数据帧

						if ((buff[len-2]==0xFF)&& (buff[len-1]==0xC9)&&(buff[len]==0x05)  )

					 	{

							// printf("%02X%02X%02X   ",buff[len-2],buff[len-1],buff[len]);

					 		// // printf("uartBodyTemperature    ");

							 recv_flag = 1;

							 CKSUM = buff[len];

							 printf("\nrecv_flag=%d ",recv_flag);

					 	}

						

						//开始接受具体参数

						 if (recv_flag == 1)

						 {

							temp_buf[j] = buff[len];



							// //作为测试打印输出

							// printf("j=%d     ",j);						

							// printf("temp_buf[%d] =%02X    buff[%d]=%02X\n",j, temp_buf[j] ,len, buff[len]);	

							

							j++;



							//接受到固定字节的数据

							if ( j >= CKSUM)

							 {

								//开始进行解析								



								//判断是否存入临时数组

								printf("\ntemp_buf[*] : \n");

								for (int k = 0; k < CKSUM; k++)

								{

									printf("[%d] =%02X\t",k,temp_buf[k]);

								}

								printf("\n");

								

								//打印输出具体体温摄氏度

								printf(" TWH= %d  TWL=%d  \n", temp_buf[3],temp_buf[4]);

								temperature = (temp_buf[3]*256 + temp_buf[4] )/10.0;

								printf("temperature is : %.1lf \n", temperature);



								//存储计算出来的温度数值

								temp_value[j] = temperature;

								printf("temp_value[%d] = %.1lf \n",j,temp_value[j]);

								

								//每接收完一组数据则清0

								 j=0;	

								 recv_flag = 0;		

								printf("recv_flag=%d\n",recv_flag);	

								memset(temp_buf,0,sizeof(temp_buf));



								//验证是否对临时数组置0

								printf("temp_buf[*] : \n");

								for (int m = 0; m < CKSUM; m++)

								{

									printf("[%d] =%02X\t",m,temp_buf[m]);

								}

								printf("\n");

							 }

						 }						

					}					



					len ++;

					if (len%7 ==0) {

						printf("\n");

					}



					if (len == 500)  {

						len = 0;

					}

					  

					fflush(stdout);

				}

			}

		}

	}

}





int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

    struct termios newtio,oldtio;

    if  ( tcgetattr( fd,&oldtio)  !=  0) { 

        perror("SetupSerial 1");

        return -1;

    }



    bzero( &newtio, sizeof( newtio ) );

    newtio.c_cflag  |=  CLOCAL | CREAD;

    newtio.c_cflag &= ~CSIZE;



    switch( nBits )

    {

        case 7:

            newtio.c_cflag |= CS7;

            break;

        case 8:

            newtio.c_cflag |= CS8;

            break;

    }

    

    switch( nEvent )

    {

    case 'O':

        newtio.c_cflag |= PARENB;

        newtio.c_cflag |= PARODD;

        newtio.c_iflag |= (INPCK | ISTRIP);

        break;

    case 'E': 

        newtio.c_iflag |= (INPCK | ISTRIP);

        newtio.c_cflag |= PARENB;

        newtio.c_cflag &= ~PARODD;

        break;

    case 'N':  

        newtio.c_cflag &= ~PARENB;

        break;

    }



    switch( nSpeed )

    {

        case 2400:

            cfsetispeed(&newtio, B2400);

            cfsetospeed(&newtio, B2400);

            break;

        case 4800:

            cfsetispeed(&newtio, B4800);

            cfsetospeed(&newtio, B4800);

            break;

        case 9600:

            cfsetispeed(&newtio, B9600);

            cfsetospeed(&newtio, B9600);

            break;

        case 115200:

            cfsetispeed(&newtio, B115200);

            cfsetospeed(&newtio, B115200);

            break;

        case 460800:

            cfsetispeed(&newtio, B460800);

            cfsetospeed(&newtio, B460800);

            break;

        default:

            cfsetispeed(&newtio, B9600);

            cfsetospeed(&newtio, B9600);

            break;

    }



    if( nStop == 1 )

        newtio.c_cflag &=  ~CSTOPB;

    else if ( nStop == 2 )

        newtio.c_cflag |=  CSTOPB;



    newtio.c_cc[VTIME]  = 0;

    newtio.c_cc[VMIN] = 0;

    tcflush(fd,TCIFLUSH);



    if((tcsetattr(fd,TCSANOW,&newtio))!=0)

    {

        perror("com set error");

        return -1;

    }

    printf("Serial port setup completed!\n\r");

    return 0;

}





血氧传感器

效果图

代码

/*
血氧
*/

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <termios.h>
#include <sys/stat.h>
 
 
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
 
int set_opt(int ,int , int , char , int );
void main()
{
	int fd,nByte,len=0;
	unsigned char uartBloodOxygen[]={0XFF,0XC7,0X03,0XA3,0XA0};	//血氧
	
	char *uart = "/dev/ttyUSB0";
	fd_set recv_fd;
	struct timeval tv;
	unsigned char buff[513];
	unsigned char *c;
	c = &buff;
	//	memset(buff,0,sizeof(buff));
	int i = 0,j=0;
	int res = 0;
	int cnt = 0;//发送计数
	int recv_flag=0;
	int CKSUM = 0;
	double temperature = 0;
	double temp_value[16];
	unsigned char temp_buf[16];

	//打开串口设备
	if((fd=open(uart,O_RDWR|O_NONBLOCK|O_NOCTTY))<0)
	{
		printf("open error\n");
	}else
	{
		printf("%s open success!",uart);
		//设置波特率等参数
		set_opt(fd,115200,8,'N',1);
		tv.tv_sec = 1;
		tv.tv_usec = 0;

		//进行写启动命令,仅一次即可
		if( (res = write(fd,uartBloodOxygen,sizeof(uartBloodOxygen)))<0) 	{
			perror("write:");
		}
		printf("write uartBloodOxygen command success!\n");
		printf("write %d bytes.\n", res);

		//大循环读取数据
		while(1){
			FD_ZERO(&recv_fd);
			FD_SET(fd, &recv_fd);

			while(FD_ISSET(fd, &recv_fd)){
				if(select(fd+1, &recv_fd, NULL, NULL, NULL) < 0 ){
					printf("select error\n");
				}else{
					read(fd,c,1);
					 printf("%02X %02d   ",*c,len);
					buff[len] = *c;

					if (len > 7)
					{
						//判断是否接受到正确数据帧
						if ((buff[len-2]==0xFF)&& (buff[len-1]==0xC7)&&(buff[len]==0x06)  )
					 	{
							// printf("%02X%02X%02X   ",buff[len-2],buff[len-1],buff[len]);
					 		// // printf("uartBodyTemperature    ");
							 recv_flag = 1;
							 CKSUM = buff[len];
							 printf("\nrecv_flag=%d \n",recv_flag);
					 	}
						
						//开始接受具体参数
						 if (recv_flag == 1)
						 {
							temp_buf[j] = buff[len];

                            // //作为测试打印输出
							// printf("j=%d     ",j);						
							// printf("temp_buf[%d] =%02X    buff[%d]=%02X\n",j, temp_buf[j] ,len, buff[len]);	
							
                            j++;

							//接受到固定字节的数据
							if ( j >= CKSUM)
							 {
								//开始进行解析								

								//判断是否存入临时数组
                                printf("\ntemp_buf[*] :  \n");
								for (int k = 0; k < CKSUM; k++)
								{
									printf("[%d] =%02X\t",k,temp_buf[k]);
								}
								printf("\n");

								//打印输出具体血氧传感器相关参数
								printf("血容积脉搏波形幅值 : %d \n", temp_buf[3]);
                                printf("血氧饱和度 : %d%% \n", temp_buf[4]);
                                printf("心率 : %d次/分钟 \n", temp_buf[5]);
								
								//每接收完一组数据则清0
								 j=0;	
								 recv_flag = 0;		
								printf("recv_flag=%d\n",recv_flag);	
								memset(temp_buf,0,sizeof(temp_buf));

								//验证是否对临时数组置0
                                printf("temp_buf[*] : \n");
								for (int m = 0; m < CKSUM; m++)
								{
									printf("[%d] =%02X\t",m,temp_buf[m]);
								}
                                printf("\n");
							 }
						 }						
					}					

					len ++;
					if (len%8 ==0) {
						printf("\n");
					}

					if (len == 500)  {
						len = 0;
					}
					  
					fflush(stdout);
				}
			}
		}
	}
}


int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
    struct termios newtio,oldtio;
    if  ( tcgetattr( fd,&oldtio)  !=  0) { 
        perror("SetupSerial 1");
        return -1;
    }

    bzero( &newtio, sizeof( newtio ) );
    newtio.c_cflag  |=  CLOCAL | CREAD;
    newtio.c_cflag &= ~CSIZE;

    switch( nBits )
    {
        case 7:
            newtio.c_cflag |= CS7;
            break;
        case 8:
            newtio.c_cflag |= CS8;
            break;
    }
    
    switch( nEvent )
    {
    case 'O':
        newtio.c_cflag |= PARENB;
        newtio.c_cflag |= PARODD;
        newtio.c_iflag |= (INPCK | ISTRIP);
        break;
    case 'E': 
        newtio.c_iflag |= (INPCK | ISTRIP);
        newtio.c_cflag |= PARENB;
        newtio.c_cflag &= ~PARODD;
        break;
    case 'N':  
        newtio.c_cflag &= ~PARENB;
        break;
    }

    switch( nSpeed )
    {
        case 2400:
            cfsetispeed(&newtio, B2400);
            cfsetospeed(&newtio, B2400);
            break;
        case 4800:
            cfsetispeed(&newtio, B4800);
            cfsetospeed(&newtio, B4800);
            break;
        case 9600:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
        case 115200:
            cfsetispeed(&newtio, B115200);
            cfsetospeed(&newtio, B115200);
            break;
        case 460800:
            cfsetispeed(&newtio, B460800);
            cfsetospeed(&newtio, B460800);
            break;
        default:
            cfsetispeed(&newtio, B9600);
            cfsetospeed(&newtio, B9600);
            break;
    }

    if( nStop == 1 )
        newtio.c_cflag &=  ~CSTOPB;
    else if ( nStop == 2 )
        newtio.c_cflag |=  CSTOPB;

    newtio.c_cc[VTIME]  = 0;
    newtio.c_cc[VMIN] = 0;
    tcflush(fd,TCIFLUSH);

    if((tcsetattr(fd,TCSANOW,&newtio))!=0)
    {
        perror("com set error");
        return -1;
    }
    printf("Serial port setup completed!\n\r");
    return 0;
}


 

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值