703n路由器 openwrt 串列埠 不能傳送 0x11 0x13

penglijiang發表於2014-08-24

串列埠不能傳送 0x11 0x13  0x0d ,摸不著頭腦,網上搜尋額下,多次嘗試,獲得完美結局辦法。

首先參考 我這個帖子:703n路由器 刷openwrt 修改 串列埠雙向傳輸和串列埠波特率  http://blog.csdn.net/penglijiang/article/details/38753281

同樣用winscp這個軟體來修改 

貼圖出來,主要是刪除 XONXOFF

 

 

另外貼出補充知識:

轉:在Linux 串列埠程式設計的一些問題解決

Linux下串列埠程式設計的文章網上是滿天飛,但大都是出自一篇文章,而且寫的都是些基本的操作,像控制RTS/CTS等串列埠引腳狀態,接收傳送二進位制資料等,都沒有很好的說明,我在使用中遇到了些問題,寫出來,希望能對大家有所幫助,少走彎路,呵呵!

我使用的作業系統是Redhat9,gcc版本是3.2.2

其實在linux下對串列埠的設定主要是通過termios這個結構體實現的,但是這個結構體卻沒有提供控制RTS或獲得CTS等串列埠引腳狀態的介面,可以通過ioctl系統呼叫來獲得/控制。

獲得:

ioctl(fd, TIOCMGET, &controlbits);

if (controlbits & TIOCM_CTS)

printf(“有訊號\n”);

else

printf(“無訊號\n”);

設定:

ioctl(fd, TIOCMGET, &ctrlbits);

if (flag)

ctrlbits |= TIOCM_RTS;

else

ctrlbits &= ~TIOCM_RTS;

ioctl(fd, TIOCMSET, &ctrlbits);

其實TIOCM_RTS有效後是把串列埠的RTS設定為有訊號,但串列埠的電平為低時是有訊號,為高時為無訊號,和用TIOCMGET獲得的狀態正好相反,也就是說TIOCMGET/TIOCMSET只是獲得/控制串列埠的相應引腳是否有訊號,並不反應當前串列埠的真實電平高低。

網上許多流行的linux串列埠程式設計的版本中都沒對c_iflag(termios成員變數)這個變數進行有效的設定,這樣傳送ASCII碼時沒什麼問題,但傳送二進位制資料時遇到0x0d,0x11和0x13卻會被丟掉。不用說也知道,這幾個肯定是特殊字元,被用作特殊控制了。關掉ICRNL和IXON選項即可解決。

       c_iflag &= ~(ICRNL | IXON);

0x0d 回車符CR

0x11 ^Q VSTART字元

0x13 ^S VSTOP字元

ICRNL 將輸入的CR轉換為NL  

IXON 使起動/停止輸出控制流起作用

在《UNIX環境高階程式設計 第二版》第18章第11小節看到把終端I/O設定為原始模式(串列埠通訊就是終端I/O的原始模式)時輸入屬性設定為

term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

遮蔽了許多屬性,怪不得有人說如果是使用串列埠通訊c_iflag和c_oflag都設定為0就行了!

以下是我的設定的一些重要的串列埠屬性

term.c_cflag |= CLOCAL | CREAD;

term.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);

term.c_oflag &= ~OPOST;

term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
static void request_send(void)
{
    ioctl(fd, TIOCMGET, &status);
    status &= ~TIOCM_RTS;   // RTS 引腳高電平
    ioctl(fd, TIOCMSET, &status);
}
static void clear_send(void)
{
    ioctl(fd, TIOCMGET, &status);
    status |= TIOCM_RTS;    // RTS 引腳低電平
    ioctl(fd, TIOCMSET, &status);
}
int main(int argc, char *argv[])
{
    int fd;
    struct termios opt;
    int len;
    char cmd;
    //待傳送資料
    char sbuf[128]={"Hello,this is a Serial_Port test!\n\0"};
    //使用open函式開啟串列埠,獲得串列埠裝置檔案的檔案描述符
    if((fd=open("/dev/ttyAMA1",O_RDWR| O_NOCTTY))==-1)
    {
        perror("Cannot open the serial port");
        return 1;
    }
    tcgetattr(fd, &opt);
    cfsetispeed(&opt,B115200 );  // 指定輸入波特率,9600bps
    cfsetospeed(&opt,B115200);   //指定輸出波特率,9600bps
    opt.c_cflag&=~CSIZE;
    //將資料位修改為8bit
    opt.c_cflag |=CS8;
    opt.c_cflag |=CBAUD;
    // 無校驗
    opt.c_cflag &= ~PARENB;
     opt.c_cflag   |= IXON|IXOFF|IXANY;   //  軟體資料流控制
//   opt.c_cflag   |=  CRTSCTS;   // 硬體資料流控制
    // opt.c_cflag &= ~CRTSCTS;   // 不使用資料流控制
    tcsetattr(fd, TCSANOW , &opt);
    int status;
    ioctl(fd, TIOCMGET, &status);
    printf("status = x\n", status);
//  status &= ~TIOCM_RTS;   // RTS 引腳高電平
    status |= TIOCM_RTS;    // RTS 引腳低電平
    printf("status = x\n", status);
    ioctl(fd, TIOCMSET, &status);
    ioctl(fd, TIOCMGET, &status);
    printf("status = x\n", status);
    while(1)
    {
        printf("sellect: w|r|q\n");
        cmd = getchar();
        switch(cmd)
        {
            case 'w':
                printf("test write\n");
                //傳送緩衝區位元組數定義
                {
             

相關文章