#项目实现相关# | 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;
}