差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

后一修订版
前一修订版
template:temp_uart [2022/12/28 19:31]
ljy 创建
template:temp_uart [2023/02/21 18:31] (当前版本)
wjj
行 1: 行 1:
-系统下操作 UART 的方式测试串口,以 COM2 测试为例:+系统下操作 UART 的测试串口,以 J_RS232 TX3\RX3 测试为例:
  
-COM2 设备节点为:+J_RS232 TX3\RX3 设备节点为:
  
-  /dev/ttyXRUSB0+ /dev/ttysWK2
  
-C参考代码如下:+C参考UART高低电平输入代码如下:
  
 <code C> <code C>
 +#include <stdio.h>
 +#include <stdlib.h>
 +#include <string.h>
 +#include <unistd.h>
 #include <sys/types.h> #include <sys/types.h>
 #include <sys/stat.h> #include <sys/stat.h>
 #include <fcntl.h> #include <fcntl.h>
-#include <unistd.h> 
 #include <termios.h> #include <termios.h>
-#include <stdio.h> +#include <errno.h> 
-#include <string.h> +int set_opt(int,int,int,char,int);
-#include <stdlib.h>+
  
-#define UART_DEVICE     "/dev/ttyXRUSB1//uart设备文件名称+void main(){ 
 + int fd,nByte; 
 + char *uart3 = "/dev/ttyS2"
 + char bufferR[2]; 
 + char bufferW[2];
  
-int main(int argcchar *argv[]+ memset(bufferR'\0', 2); 
-{+ memset(bufferW, '\0', 2);
  
-    int fd, res; + if((fd=open(uart3,O_RDWR,0777))<0) 
-    struct termios  oldtio, newtio; +
-    char  ch; + printf("failed\n"); 
-    char buf[256] = {0}; +
-  + else{ 
-//-----------打开uart设备文件------------------ + printf("success\n"); 
-    fd = open(UART_DEVICE, O_RDWR|O_NOCTTY);//没有设置O_NONBLOCK。所以这里read和write是堵塞操作 + set_opt(fd, 1152008'N', 1); 
-    if (fd < 0) { +
-        perror(UART_DEVICE); +
-        exit(1); +
-    +
-    else +
-     printf("Open %s successfully\n", UART_DEVICE); +
-     +
-//-----------设置操作參数-----------------------  +
-    tcgetattr(fd, &oldtio);//获取当前操作模式參数 +
-    memset(&newtio0sizeof(newtio)); +
-  +
- //波特率=115200 数据位=8 使能数据接收  +
-    newtio.c_cflag = B115200|CS8|CLOCAL|CREAD; +
-    newtio.c_iflag = IGNPAR+
  
-    tcflush(fdTCIFLUSH);//清空输入缓冲区和输出缓冲区 +
-    tcsetattr(fd, TCSANOW&newtio);//设置新的操作參+ 
 + 
 + while(1){  
 + 
 + nByte = 0; 
 + 
 + memset(bufferR'\0', 2); 
 + memset(bufferW, '\0', 2); 
 + 
 +          // printf("hello\n"); 
 +   if((nByte = read(fd, bufferR1)) == 1){      //MCU串口发送接收都是单字节(单字符)函 
 + 
 + 
 +     printf("receive:%c\n",bufferR[0]); 
 +  
 + bufferW[0] = 'A'; 
 + 
 + write(fd,bufferW,1);                    //串口发送单字节(单字符)  buffer[0] = data 
 + 
 + 
 + memset(bufferR, '\0', 2); 
 +     memset(bufferW, '\0', 2); 
 +  
 + nByte = 0; 
 +   } 
 + 
 +
 + 
 + close(fd);
   
-//------------向urat发送数据------------------- +}
-    res=write(fd, "Begin Uart tx", 16); +
-    while(1) { +
-    //从控制台终端获取数据,然后通过uart发送出去,直到接收到!字符 +
-        while((ch=getchar()) != '!') { +
-            buf[0]=ch; +
-            res=write(fd, buf, 1); +
-        } +
-       +
-        buf[0]=ch; +
-        buf[1]=' '; +
-        res = write(fd, buf, 2); +
-        break; +
-    } +
-//-------------从uart接收数据------------------- +
-    while(1) { +
-    res = read(fd, buf, 255);//程序将在这里挂起,直到从uart接收到数据(堵塞操作) +
-    if (res == 0)  +
-  continue; +
-   +
-  buf[res] = ' '; +
-  printf("res = %d, buf = %s\n", res, buf);//将uart接收到的字符打印出来 +
-  if (buf[0] == '!')//uart接收到!字符后退出while +
-  break; +
-  } +
-//------------关闭uart设备文件,恢复原先參数-------- +
-    close(fd); +
-    printf("Close %s\n", UART_DEVICE); +
-    tcsetattr(fd, TCSANOW, &oldtio); //恢复原先的设置+
  
-    return 0;+//串口通用初始化函数 
 +int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop) 
 +
 + struct termios newtio,oldtio;//定义结构体newtio和oldtio 
 + //将原串口的数据取到oldtio 
 + if  ( tcgetattr( fd,&oldtio)  !=  0) {  
 + perror("SetupSerial 1"); 
 + return -1; 
 +
 + //将newio清零和设置c_cflag 
 + 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;//读取最小字符数为0 
 + 
 + tcflush(fd,TCIFLUSH);//清空缓冲区 
 +  
 + //使配置生效 
 + if((tcsetattr(fd,TCSANOW,&newtio))!=0) 
 +
 + perror("com set error"); 
 + return -1; 
 +
 + // printf("set done!\n\r"); 
 + return 0;
 } }
 +
 </code> </code>
 +
 +交叉编译源码:
 +
 +  aarch64-linux-gnu-gcc -o uart uart.c
  
 将编译好的程序使用 scp 拷贝到 3399 主板上,执行测试: 将编译好的程序使用 scp 拷贝到 3399 主板上,执行测试:
  
-{{:arm:rk3399:linux:uart编程-1.png?600|}}+{{:arm:rk3399:linux:r39s2_uart.c.png?600|}}
打印/导出