首页 优德88下载正文

板蓝根泡面,linux uart使用开发(ttyS*设备)《Rice linux 学习开发》-优德88手机客户端

admin 优德88下载 2019-07-15 160 0

    写这篇文章的原因:由于在linux开发串口运用的时分,遇到了问题,让遇到相同问题的人少走点弯路:

    ①读串口数据的时,需求承受换行符才干回来。

    ②承受数据时,一个字节一个字节的回来。无法承受完多个字节在回来。

关于 linux的开发板来说,串口的驱动是不需求咱们去开发,我现在是在内核4.9上开发,只需求修正一下设备树就能够了。所以直接对设备文件进拜访就能够了。

linux运用串口的办法:

1.串口装备的头文件:

#include  <termios.h>    /*POSIX 终端操控界说*/

2.串口波特率的设置:


波特率

B4800

4800

B9600

9600

B67500

67500

B115200

115200

修正波特率是运用cfsetispeed()和cfsetospeed()函数来操作。

例如:要将波特率修正为115200:

    cfsetispeed(&opts, B115200);

    cfsetospeed(&opts,B115200);

3.串口特点装备:

串口的特点界说在结构体struct termios,其头文件#include<asm/termbits.h>,结构体界说如下:

#define NCCS 19
struct termios { tcflag_t c_iflag; /* 输入参数 */ tcflag_t c_oflag; /* 输出参数 */ tcflag_t c_cflag; /* 操控参数*/ tcflag_t c_lflag; /* 本地形式 */ tcflag_t c_ispeed; /* 输入波特率 */ tcflag_t c_ospeed; /* 输出波特率 */ cc_t c_line; /* 线操控 */ cc_t c_cc[NCCS]; /* 操控字符*/}

对串口特点的获取和设置有两个:

① tcsetattr(int fd,  int opt_DE, termios *ptr) ,回来值:成功回来0,失利回来-1。

fd:文件描绘符

opt_DE:选项值,可供挑选:

    (1)TCSANOW:  不等数据传输完毕就当即改动特点

    (2)TCSADRAIN:等候一切数据传输完毕才改动特点

    (3)TCSAFLUSH:清空输入输出缓冲区才改动特点

*ptr:指向termios结构的指针

②tcgetsttr(int fd, termios *ptr),回来值:成功回来0,失利回来-1。

 fd:待操作的文件描绘符

*ptr:指向termios结构的指针

4.特点描绘:

:c_iflag:

IGNBRK:疏忽输入中的 BREAK 状况。

BRKINT:假如设置了 IGNBRK,将疏忽 BREAK。假如没有设置,可是设置了 BRKINT,那么 BREAK 将使得输入和输出行列被改写,假如终端是一个前台进程组的操控终端,这个进程组中一切进程将收到 SIGINT 信号。假如既未设置IGNBRK 也未设置 BRKINT,BREAK 将视为与 NUL 字符同义,除非设置了 PARMRK,这种情况下它被视为序列 /377 /0 /0。

IGNPAR:疏忽桢过错和奇偶校验错。

PARMRK:假如没有设置 IGNPAR,在有奇偶校验错或桢过错的字符前刺进 /377 /0。假如既没有设置 IGNPAR 也没有设置PARMRK,将有奇偶校验错或桢过错的字符视为 /0。

INPCK:启用输入奇偶检测。

ISTRIP:去掉第八位。

INLCR:将输入中的 NL 翻译为CR。

IGNCR:疏忽输入中的回车。

ICRNL:将输入中的回车翻译为新行 (除非设置了 IGNCR)。

IUCLC:(不属于 POSIX) 将输入中的大写字母映射为小写字母。

IXON:启用输出的 XON/XOFF 流操控。

IXANY:(不属于 POSIX.1;XSI) 答应任何字符来从头开端输出。(?)

IXOFF:启用输入的 XON/XOFF 流操控。

IMAXBEL:(不属于 POSIX) 当输入行列满时响零。Linux 没有完成这一位,总是将它视为已设置。

②c_oflag

OPOST:启用详细完成自行界说的输出处理。其他 c_oflag 标志常量界说在 POSIX 1003.1-2001 中,除非别的阐明。

OLCUC:(不属于 POSIX) 将输出中的小写字母映射为大写字母。

ONLCR:(XSI) 将输出中的新行符映射为回车-换行。

OCRNL:将输出中的回车映射为新行符

ONOCR:不在第 0 列输出回车。

ONLRET:不输出回车。

OFILL:发送填充字符作为延时,而不是运用守时来延时。

OFDEL:(不属于 POSIX) 填充字符是 ASCII DEL (0177)。假如不设置,填充字符则是 ASCII NUL。

NLDLY:新行延时掩码。取值为 NL0 和 NL1

CRDLY:回车延时掩码。取值为 CR0CR1CR2,或 CR3

TABDLY:水平跳格延时掩码。取值为 TAB0TAB1TAB2TAB3 (或 XTABS)。取值为 TAB3,即 XTABS,将扩展跳格为空格 (每个跳格符填充 8 个空格)。(?)

BSDLY:回退延时掩码。取值为 BS0 或 BS1。(从来没有被完成过)

VTDLY:竖直跳格延时掩码。取值为 VT0 或 VT1

FFDLY:进表延时掩码。取值为 FF0 或 FF1

③c_cflag

CBAUD(不属于 POSIX) 波特率掩码 (4+1 位)。

CBAUDEX(不属于 POSIX) 扩展的波特率掩码 (1 位),包含在 CBAUD 中。

(POSIX 规则波特率存储在 termios 结构中,并未准确指定它的方位,而是供给了函数 cfgetispeed() 和 cfsetispeed() 来存取它。一些体系运用 c_cflag 中 CBAUD 挑选的位,其他体系运用独自的变量,例如 sg_ispeed 和 sg_ospeed 。)

CSIZE字符长度掩码。取值为 CS5, CS6, CS7, 或 CS8。

CSTOPB设置两个间断位,而不是一个。

CREAD翻开承受者。

PARENB答应输出发生奇偶信息以及输入的奇偶校验。

PARODD输入和输出是奇校验。

HUPCL在最终一个进程封闭设备后,下降 modem 操控线 (挂断)。(?)

CLOCAL疏忽 modem 操控线。

LOBLK(不属于 POSIX) 从非当时 shell 层堵塞输出(用于 shl )。(?)

CIBAUD(不属于 POSIX) 输入速度的掩码。CIBAUD 各位的值与 CBAUD 各位相同,左移了 IBSHIFT 位。

CRTSCTS(不属于 POSIX) 启用RTS/CTS (硬件) 流操控。

④c_lflag

ISIG当承受到字符 INTR,QUIT, SUSP, 或 DSUSP 时,发生相应的信号。

ICANON启用规范形式 (canonical mode)。答应运用特别字符EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT, STATUS, 和WERASE,以及按行的缓冲。

XCASE(不属于 POSIX; Linux 下不被支撑) 假如一起设置了 ICANON,终端只要大写。输入被转换为小写,除了以 / 前缀的字符。输出时,大写字符被前缀 /,小写字符被转换成大写。

ECHO回显输入字符。

ECHOE假如一起设置了 ICANON,字符 ERASE 擦除前一个输入字符,WERASE 擦除前一个词。

ECHOK假如一起设置了 ICANON,字符 KILL 删去当时行。

ECHONL假如一起设置了 ICANON,回显字符 NL,即便没有设置 ECHO。

ECHOCTL(不属于 POSIX) 假如一起设置了 ECHO,除了 TAB, NL, START, 和 STOP 之外的 ASCII 操控信号被回显为 ^X, 这儿 X 是比操控信号大0x40 的 ASCII 码。例如,字符 0x08 (BS) 被回显为 ^H。

ECHOPRT(不属于 POSIX) 假如一起设置了 ICANON 和 IECHO,字符在删去的一起被打印。

ECHOKE(不属于 POSIX) 假如一起设置了 ICANON,回显 KILL 时将删去一行中的每个字符,好像指定了 ECHOE 和ECHOPRT 相同。

DEFECHO(不属于 POSIX) 只在一个进程读的时分回显。

FLUSHO(不属于 POSIX; Linux 下不被支撑) 输出被改写。这个标志能够经过键入字符 DISCARD 来开关。

NOFLSH制止在发生 SIGINT, SIGQUIT 和 SIGSUSP 信号时改写输入和输出行列。

TOSTOP向企图写操控终端的后台进程组发送 SIGTTOU 信号。

PENDIN(不属于 POSIX; Linux 下不被支撑) 在读入下一个字符时,输入行列中一切字符被从头输出。(bash 用它来处理 typeahead)

IEXTEN启用完成自界说的输入处理。这个标志有必要与 ICANON 一起运用,才干解说特别字符 EOL2,LNEXT,REPRINT 和 WERASE,IUCLC 标志才有用。

⑤c_cc[],数组界说了特别的操控字符。符号下标 (初始值) 和意义为:

VINTR:(003, ETX, Ctrl-C, or also0177, DEL, rubout) 间断字符。宣布 SIGINT 信号。当设置 ISIG 时可被辨认,不再作为输入传递。

VQUIT:(034, FS, Ctrl-/) 退出字符。宣布 SIGQUIT 信号。当设置 ISIG 时可被辨认,不再作为输入传递。

VERASE:(0177, DEL, rubout, or 010,BS, Ctrl-H, or also #) 删去字符。删去上一个还没有删掉的字符,但不删去上一个 EOF 或行首。当设置 ICANON 时可被辨认,不再作为输入传递。

VKILL:(025, NAK, Ctrl-U, or Ctrl-X,or also @) 中止字符。删去自上一个 EOF 或行首以来的输入。当设置 ICANON 时可被辨认,不再作为输入传递。

VEOF:(004, EOT, Ctrl-D) 文件尾字符。更准确地说,这个字符使得 tty 缓冲中的内容被送到等候输入的用户程序中,而不用比及 EOL。假如它是一行的榜首个字符,那么用户程序的 read() 将回来 0,指示读到了 EOF。当设置ICANON 时可被辨认,不再作为输入传递。

VMIN:非 canonical 形式读的最小字符数。

VEOL:(0, NUL) 附加的行尾字符。当设置 ICANON 时可被辨认。

VTIME:非 canonical 形式读时的延时,以十分之一秒为单位。

VEOL2:(not in POSIX; 0, NUL) 另一个行尾字符。当设置 ICANON 时可被辨认。

VSWTCH:(not in POSIX; not supportedunder Linux; 0, NUL) 开关字符。(只为 shl 所用。)

VSTART:(021, DC1, Ctrl-Q) 开端字符。从头开端被 Stop 字符间断的输出。当设置 IXON 时可被辨认,不再作为输入传递。

VSTOP:(023, DC3, Ctrl-S) 间断字符。间断输出,直到键入 Start 字符。当设置 IXON 时可被辨认,不再作为输入传递。

VSUSP:(032, SUB, Ctrl-Z) 挂起字符。发送 SIGTSTP 信号。当设置 ISIG 时可被辨认,不再作为输入传递。

VDSUSP:(not in POSIX; not supportedunder Linux; 031, EM, Ctrl-Y) 延时挂起信号。当用户程序读到这个字符时,发送 SIGTSTP 信号。当设置 IEXTEN 和 ISIG,而且体系支撑作业办理时可被辨认,不再作为输入传递。

VLNEXT:(not in POSIX; 026, SYN,Ctrl-V) 字面上的下一个。引证下一个输入字符,撤销它的任何特别意义。当设置IEXTEN 时可被辨认,不再作为输入传递。

VWERASE:(not in POSIX; 027, ETB,Ctrl-W) 删去词。当设置 ICANON 和 IEXTEN 时可被辨认,不再作为输入传递。

VREPRINT:(not in POSIX; 022, DC2,Ctrl-R) 从头输出未读的字符。当设置 ICANON 和 IEXTEN 时可被辨认,不再作为输入传递。

VDISCARD:(not in POSIX; not supportedunder Linux; 017, SI, Ctrl-O) 开关:开端/完毕丢掉未完成的输出。当设置 IEXTEN 时可被辨认,不再作为输入传递。

VSTATUS:(not in POSIX; not supportedunder Linux; status request: 024, DC4, Ctrl-T).

:VIME和VMIN需求合作运用,联系如下:

1、VTIME=0,VMIN=0:此刻即便读取不到任何数据,函数read也会回来,回来值是0。

2、VTIME=0,VMIN>0:read调用一向堵塞,直到读到VMIN个字符后当即回来。

3、VTIME>0,VMIN=0:read调用读到数据则当即回来,不然将为每个字符最多等候 VTIME*100ms 时刻。

4、VTIME>0,VMIN>0:read调用将坚持堵塞直到读取到榜首个字符,读到了榜首个字符之后开端计时,尔后若时刻到了VTIME*100ms 或许时刻未到但已读够了VMIN个字符则会回来。若在时刻未到之前又读到了一个字符(但此刻读到的总数仍不行VMIN)则计时从头开端(即每个字符都有VTIME*100ms的超时时刻)。

代码例程:

设置波特率:

void set_baudrate(struct termios *set_serial, unsigned long int baud_rate){    int baud = B115200;    switch(baud_rate)    {        case 2400:            baud = B2400;            break;        case 4800:            baud = B4800;            break;        case 9600:            baud = B9600;            break;        case 19200:            baud = B19200;            break;        case 38400:            baud = B38400;            break;        case 57600:            baud = B57600;            break;        case 115200:            baud = B115200;            break;        default:            baud = B115200;            break;    }    cfsetispeed(set_serial, baud);    cfsetospeed(set_serial, baud);}

设置数据位:

void set_databits(struct termios *set_serial, unsigned int data_bits){    switch(data_bits)    {        case 5:            set_serial->c_cflag |= CS5;            break;        case 6:            set_serial->c_cflag |= CS6;            break;        case 7:            set_serial->c_cflag |= CS7;            break;        case 8:            set_serial->c_cflag |= CS8;            break;        default:            set_serial->c_cflag |= CS8;            break;    }}

设置校验位:

void set_parity(struct termios *set_serial, char parity){    switch(parity)    {        case 'N':            set_serial->c_cflag &= ~PARENB;     //no parity check            break;        case 'O':            set_serial->c_cflag |= PARENB;      //odd check            set_serial->c_cflag &= ~PARODD;            break;        case 'E':            set_serial->c_cflag |= PARENB;      //even check            set_serial->c_cflag |= PARODD;            break;        default:            set_serial->c_cflag &= ~PARENB;            break;    }}

间断位:

void set_stopbits(struct termios *set_serial, unsigned int stop_bits){    if(stop_bits == 2)    {        set_serial->c_cflag |= CSTOPB;  //2 stop bits    }    else    {        set_serial->c_cflag &= ~CSTOPB; //1 stop bits    }}

串口装备函数:

void set_option(unsigned int baud_rate, unsigned int data_bits, char parity, unsigned int stop_bits){    struct termios opts;    tcgetattr(m_dev, &opts);
set_baudrate(&opts, baud_rate);
opts.c_cflag |= CLOCAL|CREAD;
set_parity(&opts, parity); set_stopbits(&opts, stop_bits); set_databits(&opts, data_bits);
opts.c_cflag &= ~CRTSCTS;
opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw input opts.c_oflag &= ~OPOST; // raw output
opts.c_cc[VTIME]=1; opts.c_cc[VMIN]=1023;
tcsetattr(m_dev, TCSANOW, &opts);}

发送数据:

int send_data(int fd, const char *data, int datalen){    int len = 0;    len = write(m_dev, data, datalen);    if(len == datalen)    {        return 0;    }    else    {        tcflush(m_dev, TCOFLUSH);        return -1;    }}

接纳函数:

int receive(int fd, char *data, int datalen){    int read_len;    if((read_len = read(m_dev, data, datalen))>0)    {        return read_len;    }    else    {        return -1;    }}

主函数:

int main( int argc, char *argv[]){    int fd;    int ret;    char buff[1024];    char senddata[] = "uart";
fd= open("/dev/ttyS2", O_RDWR | O_NOCTTY | O_NONBLOCK); if(fd <= 0) { printf("uart open fail\n"); return -1; } fcntl(fd, F_SETFL, 0);
set_option(115200, 8, 'N', 1);

while (1) { ret = receive(fd, buff, sizeof(buff)); buff[ret] = 0; printf("receive data : %s\n", buff);
send_data(fd, senddata, sizeof(senddata)); } close(fd); return 0;}

完好代码:https://download.csdn.net/download/jiafanluo/11231218



版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

最近发表

    优德88手机客户端_w88官网_w88

    http://sud-rentals.com/

    |

    Powered By

    使用手机软件扫描微信二维码

    关注我们可获取更多热点资讯

    w88出品