//linux c: 串口設置
//串口操作無非以下幾個:
//1 打開
//2 設置串口屬性
//3 read write
//struct termios能夠表明一切串口屬性,這里不詳細說明.
//詳見 【Linux公開課】串口屬性設置 http://mp.weixin.qq.com/s?src=3×tamp=1467340907&ver=1&signature=2hx5roS7br3*GBJVmZQ0Om2X3KMAONfWdT1SSPB2fMDoc68n3k6nqofouSMF3UWy8HMv58IMyIT4XiugpDSQVEPSubo8oSDt*BcWwUVgdqvSUypVfgz8arph5*9QxamrlcafmoPA9fk42FwIjITW6A==
//以及 Linux應用程序開發 http://hilinux.com/man/linuxdev/ch09.html, 這篇文章對串口結構體做了比較詳細的說明
struct termios {
tcflag_t c_iflag; /* 輸入參數 */
tcflag_t c_oflag; /* 輸出參數 */
tcflag_t c_cflag; /* 控制參數*/
tcflag_t c_ispeed; /* 輸入波特率 */
tcflag_t c_ospeed; /* 輸出波特率 */
cc_t c_line; /* 線控制 */
cc_t c_cc[NCCS]; /* 控制字符*/
};
//xereno的串口代碼是太繁亂,只做對比確認用.
//下面摘抄一段網絡代碼進行分析:
//串口操作示例
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <asm/termios.h> // 在linux x86下面用#include <termios.h>
#include "serial.h"
#define DEV_NAME "/dev/ttyS1" //同自己的驅動寫的名字
int set_port_attr (int fd,int baudrate, int databit, const char *stopbit, char parity, int vtime,int vmin );
static void set_baudrate (struct termios *opt, unsigned int baudrate);
static void set_data_bit (struct termios *opt, unsigned int databit);
static void set_stopbit (struct termios *opt, const char *stopbit);
static void set_parity (struct termios *opt, char parity);
int main (int argc, char *argv[])
{
int fd;
int len, i,ret;
char buf[] = "hello ZLG!";
fd = open(DEV_NAME, O_RDWR | O_NOCTTY); //如果是在linux x86下面做實驗, 這個設備是有問題的, 可不要這一步, 用fd=0直接定位到當前的終端來進行實驗.
if(fd < 0) {
perror(DEV_NAME);
return -1;
}
ret = set_port_attr (fd, B115200, 8, "1", 'N',150,255 ); /* 115200 8n1 */
if(ret < 0) {
printf("set uart arrt faile \n");
exit(-1);
}
len = write(fd, buf, sizeof(buf)); /* 向串口發送字符串 */
if (len < 0) {
printf("write data error \n");
return -1;
}
len = read(fd, buf, sizeof(buf)); /* 在串口讀取字符串 */
if (len < 0) {
printf("read error \n");
return -1;
}
printf("%s \n", buf); /* 打印在串口讀取的字符串 */
return(0);
}
//自定義終端屬性設置函數具體定義如下
//設置終端屬性的時候注意,有的項目是通過與&,而有的項目是通過或|. 不要混淆誤解.
int set_port_attr (int fd,int baudrate, int databit, const char *stopbit, char parity, int vtime,int vmin )
{
struct termios opt;
tcgetattr(fd, &opt); //獲取初始設置
set_baudrate(&opt, baudrate);
set_data_bit(&opt, databit);
set_parity(&opt, parity);
set_stopbit(&opt, stopbit);
opt.c_cflag &= ~CRTSCTS;// 不使用硬件流控制
opt.c_cflag |= CLOCAL | CREAD; //CLOCAL--忽略 modem 控制線,本地連線, 不具數據機控制功能, CREAD--使能接收標志
/*
IXON--啟用輸出的 XON/XOFF 流控制
IXOFF--啟用輸入的 XON/XOFF 流控制
IXANY--允許任何字符來重新開始輸出
IGNCR--忽略輸入中的回車
*/
opt.c_iflag &= ~(IXON | IXOFF | IXANY);
opt.c_oflag &= ~OPOST; //啟用輸出處理
/*
ICANON--啟用標准模式 (canonical mode)。允許使用特殊字符 EOF, EOL,
EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, 和 WERASE,以及按行的緩沖。
ECHO--回顯輸入字符
ECHOE--如果同時設置了 ICANON,字符 ERASE 擦除前一個輸入字符,WERASE 擦除前一個詞
ISIG--當接受到字符 INTR, QUIT, SUSP, 或 DSUSP 時,產生相應的信號
*/
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
opt.c_cc[VMIN] = vmin; //設置非規范模式下的超時時長和最小字符數:
opt.c_cc[VTIME] = vtime; //VTIME與VMIN配合使用,是指限定的傳輸或等待的最長時間
tcflush (fd, TCIFLUSH); /* TCIFLUSH-- update the options and do it NOW */
return (tcsetattr (fd, TCSANOW, &opt)); /* TCSANOW--改變立即發生 */
}
//自定義set_baudrate()函數
//使用set_baudrate()函數設置串口輸入/輸出波特率為115200的代碼為:set_baudrate(&opt, B115200));
//通常來說,串口的輸入和輸出波特率都設置為同一個值,如果要分開設置,就要分別調用cfsetispeed , cfsetospeed
static void set_baudrate (struct termios *opt, unsigned int baudrate)
{
cfsetispeed(opt, baudrate);
cfsetospeed(opt, baudrate);
}
//自定義set_stopbit函數
//在set_stopbit()函數中,stopbit參數可以取值為:“1”(1位停止位)、“1.5”(1.5位停止位)和“2”(2位停止位)。
static void set_stopbit (struct termios *opt, const char *stopbit)
{
if (0 == strcmp (stopbit, "1")) {
opt->c_cflag &= ~CSTOPB; /* 1位停止位t */
} else if (0 == strcmp (stopbit, "1.5")) {
opt->c_cflag &= ~CSTOPB; /* 1.5位停止位 */
}else if (0 == strcmp (stopbit, "2")) {
opt->c_cflag |= CSTOPB; /* 2 位停止位 */
}else {
opt->c_cflag &= ~CSTOPB; /* 1 位停止位 */
}
}
//set_data_bit函數
//CSIZE--字符長度掩碼。取值為 CS5, CS6, CS7, 或 CS8
static void set_data_bit (struct termios *opt, unsigned int databit)
{
opt->c_cflag &= ~CSIZE;
switch (databit) {
case 8:
opt->c_cflag |= CS8;
break;
case 7:
opt->c_cflag |= CS7;
break;
case 6:
opt->c_cflag |= CS6;
break;
case 5:
opt->c_cflag |= CS5;
break;
default:
opt->c_cflag |= CS8;
break;
}
}
//set_parity函數
//在set_parity函數中,parity參數可以取值為:‘N’和‘n’(無奇偶校驗)、‘E’和‘e’(表示偶校驗)、‘O’和‘o’(表示奇校驗)。
static void set_parity (struct termios *opt, char parity)
{
switch (parity) {
case 'N': /* 無校驗 */
case 'n':
opt->c_cflag &= ~PARENB;
break;
case 'E': /* 偶校驗 */
case ‘e‘:
opt->c_cflag |= PARENB;
opt->c_cflag &= ~PARODD;
break;
case 'O': /* 奇校驗 */
case ‘o‘:
opt->c_cflag |= PARENB;
opt->c_cflag |= ~PARODD;
break;
default: /* 其它選擇為無校驗 */
opt->c_cflag &= ~PARENB;
break;
}
}
mcu svn:
https://123.57.81.221/svn/xida/trunk/mcu/stm32