現象:
1.主機是嵌入式平臺,當外部串口指令以10fps,每幀資料10個位元組以內發送時,主機串口接收正常。
2.當指令發送速度提高時(大概有100fps),會出現接收卡頓的情況,即有幾秒讀到空白資料,然后一次性讀到快取區積累的資料。
3.該現象發生在波特率設定小于等于19200時出現,通訊波特率設定到115200后該現象消失。
4.用電腦串口工具接收外部串口是正常的,并未出現該現象。
在外部串口波特率(19200)無法改變的情況下,怎么配置串口引數去除該現象?
uj5u.com熱心網友回復:
接收端基于Linux開發配置介面代碼如下
static int uart_setup( int fd, int baudrate, int flow_ctrl, int databits, int parity, int stopbits )
{
//串口主要設定結構體termios <termios.h>
struct termios options;
int baud_val;
/**1. tcgetattr函式用于獲取與終端相關的引數。
*引數fd為終端的檔案描述符,回傳的結果保存在termios結構體中 */
tcgetattr( fd, &options );
/**2. 修改所獲得的引數*/
//設定串口輸入波特率和輸出波特率
switch( baudrate )
{
case 115200:
baud_val = B115200;
break;
case 57600:
baud_val = B57600;
break;
case 38400:
baud_val = B38400;
break;
case 19200:
baud_val = B19200;
break;
case 9600:
baud_val = B9600;
break;
case 4800:
baud_val = B4800;
break;
case 2400:
baud_val = B2400;
break;
case 1200:
baud_val = B1200;
break;
case 300:
baud_val = B300;
break;
default :
printf("Unsupported baudrate\n");
return (-1);
}
cfsetispeed( &options, baud_val );
cfsetospeed( &options, baud_val );
options.c_cflag |= ( CLOCAL | CREAD );//設定控制模式狀態,本地連接,接收使能
//設定資料流控制
switch( flow_ctrl )
{
case 0 ://不使用流控制
options.c_cflag &= ~CRTSCTS;
break;
case 1 ://使用硬體流控制
options.c_cflag |= CRTSCTS;
break;
case 2 ://使用軟體流控制
options.c_cflag |= IXON | IXOFF | IXANY;
break;
default :
printf("Unsupported flow control\n");
return (-1);
}
//設定資料位
options.c_cflag &= ~CSIZE;//字符長度,屏蔽其他標志位,設定資料位之前一定要屏掉這個位
switch ( databits )
{
case 5 :
options.c_cflag |= CS5;
break;
case 6 :
options.c_cflag |= CS6;
break;
case 7 :
options.c_cflag |= CS7;
break;
case 8 :
options.c_cflag |= CS8;
break;
default :
printf("Unsupported data size\n");
return (-1);
}
//設定校驗位
switch ( parity )
{
case 'n':
case 'N': //無奇偶校驗位。
options.c_cflag &= ~PARENB;
options.c_iflag &= ~INPCK;
break;
case 'o':
case 'O'://設定為奇校驗
options.c_cflag |= (PARODD | PARENB);
options.c_iflag |= INPCK;
break;
case 'e':
case 'E'://設定為偶校驗
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= INPCK;
break;
case 's':
case 'S': //設定為空格
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CSTOPB;
break;
default:
printf("Unsupported parity\n");
return (-1);
}
// 設定停止位
switch ( stopbits )
{
case 1:
options.c_cflag &= ~CSTOPB;
break;
case 2:
options.c_cflag |= CSTOPB;
break;
default:
printf("Unsupported stop bits\n");
return (-1);
}
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 0;
options.c_oflag = 0;
options.c_lflag = 0;
options.c_iflag &= ~(ICRNL | IXON);
//修改輸出模式,原始資料輸出
options.c_oflag &= ~OPOST;
/**3. 設定新屬性,TCSANOW:所有改變立即生效*/
tcflush( fd, TCIFLUSH );//溢位資料可以接收,但不讀
tcsetattr( fd, TCSANOW, &options );
return 0;
}
串口接收介面代碼如下
static int uart_recv( int fd, char *data, int datalen )
{
int len = 0, ret = 0;
fd_set fs_read; /* 先宣告一個 fd_set 集合來保存我們要檢測的 fd句柄 */
struct timeval tv_timeout;
FD_ZERO( &fs_read ); /* 用select函式之前先把集合清零 */
FD_SET( fd, &fs_read ); /* 把要檢測的句柄fd加入到集合里 */
tv_timeout.tv_sec = 0;//( 10*20/115200 + 2 ); /*設定等待最長時間*/
tv_timeout.tv_usec = 16000;
ret = select( fd+1, &fs_read, NULL, NULL, &tv_timeout ); /* 檢測我們上面設定到集合fs_read里的句柄是否有可讀資訊 */
//printf("ret = %d\n", ret);
if( ret < 0 )
{
perror("select");/* 這說明select函式出錯 */
return -1;
}
else
{ /* 說明等待時間還未到設定時間,fd的狀態發生了變化 */
/* ret這個回傳值記錄了發生狀態變化的句柄的數目,由于我們只監視了fd這一個句柄,所以這里一定ret=1,如果同時有多個句柄發生變化回傳的就是句柄的總和了 */
/* 這里我們就應該從fd這個句柄里讀取資料了,因為select函式已經告訴我們這個句柄里有資料可讀 */
if ( FD_ISSET( fd, &fs_read ) ) /* 先判斷一下socket這外被監視的句柄是否真的變成可讀的了 */
{
len = read( fd, data, datalen ); /* 讀取fd句柄里的資料 */
//printf("len = %d\n", len);
return len;
}
}
return 0;
}
uj5u.com熱心網友回復:
使用串口的DMA接收,在主回圈或者定時任務里進行串口接收DMA資料的處理。uj5u.com熱心網友回復:
接收程式耗時太多,優化代碼,用DMA,加例外處理。uj5u.com熱心網友回復:
還有,設定優化編譯引數也能加快轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/95704.html
標籤:單片機/工控
上一篇:求助 RX480 盈通游戲高手TOP 1340原廠 bioss
下一篇:keil 按鍵問題咨詢大神
