STM32/STM8技术论坛
直播中

casy

12年用户 229经验值
擅长:嵌入式技术
私信 关注
[经验]

【MYD-YA157C开发板试用连载】+ UART子系统介绍与测评

首先,介绍一下tty设备驱动,这个是基础。 串口终端(/dev/ttySn)
        串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。有段时间串行端口设备通常被称为终端设备,那时它的最大用途就是用来连接终端,所以这些串行端口所对应的设备名称是/dev/tts/0(或/dev/ttyS0)、/dev/tts/1(或/dev /ttyS1)等,设备号分别是(4,0)、(4,1)等(对应于win系统下的COM1、COM2等)。若要向一个端口发送数据,可以在命令行上把标准输出重定向到这些特殊文件名上即可。
       例如,在命令行提示符下键入:echo tekkaman> /dev/ttyS1会把“tekkaman”发送到连接在ttyS1(COM2)端口的设备上。
       在2.6以后的内核中,部分三星芯片(例如S3C24x0等)将串口终端设备节点命名为ttySACn。ti的Omap系列芯片从2.6.37开始芯片自带的UART设备开始使用专有的的omap-uart驱动,故设备节点命名为ttyOn,以区别于使用8250驱动时的设备名“ttySn”。
      在mp1开发板中,我们使用uart1进行评测:


源代码如下:
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. #include
  10. #include

  11. #define FALSE 1
  12. #define TRUE 0

  13. char *recchr="We received:"";

  14. void print_usage();

  15. int speed_arr[] = {
  16.         B921600, B460800, B230400, B115200, B57600, B38400, B19200,
  17.         B9600, B4800, B2400, B1200, B300,
  18. };

  19. int name_arr[] = {
  20.         921600, 460800, 230400, 115200, 57600, 38400,  19200,  
  21.         9600,  4800,  2400,  1200,  300,  
  22. };

  23. void set_speed(int fd, int speed)
  24. {
  25.         int   i;
  26.         int   status;
  27.         struct termios   Opt;
  28.         tcgetattr(fd, &Opt);

  29.         for ( i= 0;  i < sizeof(speed_arr) / sizeof(int);  i++) {
  30.                 if  (speed == name_arr[i])        {
  31.                         tcflush(fd, TCIOFLUSH);
  32.                         cfsetispeed(&Opt, speed_arr[i]);
  33.                         cfsetospeed(&Opt, speed_arr[i]);
  34.                         status = tcsetattr(fd, TCSANOW, &Opt);
  35.                         if  (status != 0)
  36.                                 perror("tcsetattr fd1");
  37.                                 return;
  38.                 }
  39.                 tcflush(fd,TCIOFLUSH);
  40.            }

  41.         if (i == 12){
  42.                 printf("tSorry, please set the correct baud rate!nn");
  43.                 print_usage(stderr, 1);
  44.         }
  45. }
  46. /*
  47.         *[url=home.php?mod=space&uid=2666770]@Brief[/url]   设置串口数据位,停止位和效验位
  48.         *[url=home.php?mod=space&uid=3142012]@param[/url]  fd     类型  int  打开的串口文件句柄*
  49.         *@param  databits 类型  int 数据位   取值 为 7 或者8*
  50.         *@param  stopbits 类型  int 停止位   取值为 1 或者2*
  51.         *@param  parity  类型  int  效验类型 取值为N,E,O,,S
  52. */
  53. int set_Parity(int fd,int databits,int stopbits,int parity)
  54. {
  55.         struct termios options;
  56.         if  ( tcgetattr( fd,&options)  !=  0) {
  57.                 perror("SetupSerial 1");
  58.                 return(FALSE);
  59.         }
  60.         options.c_cflag &= ~CSIZE ;
  61.         switch (databits) /*设置数据位数*/ {
  62.         case 7:
  63.                 options.c_cflag |= CS7;
  64.         break;
  65.         case 8:
  66.                 options.c_cflag |= CS8;
  67.         break;
  68.         default:
  69.                 fprintf(stderr,"Unsupported data sizen");
  70.                 return (FALSE);
  71.         }
  72.        
  73.         switch (parity) {
  74.         case 'n':
  75.         case 'N':
  76.                 options.c_cflag &= ~PARENB;   /* Clear parity enable */
  77.                 options.c_iflag &= ~INPCK;     /* Enable parity checking */
  78.         break;
  79.         case 'o':
  80.         case 'O':
  81.                 options.c_cflag |= (PARODD | PARENB);  /* 设置为奇效验*/
  82.                 options.c_iflag |= INPCK;             /* Disnable parity checking */
  83.         break;
  84.         case 'e':
  85.         case 'E':
  86.                 options.c_cflag |= PARENB;     /* Enable parity */
  87.                 options.c_cflag &= ~PARODD;   /* 转换为偶效验*/
  88.                 options.c_iflag |= INPCK;       /* Disnable parity checking */
  89.         break;
  90.         case 'S':       
  91.         case 's':  /*as no parity*/
  92.                 options.c_cflag &= ~PARENB;
  93.                 options.c_cflag &= ~CSTOPB;
  94.         break;
  95.         default:
  96.                 fprintf(stderr,"Unsupported parityn");
  97.                 return (FALSE);
  98.         }
  99.         /* 设置停止位*/  
  100.           switch (stopbits) {
  101.            case 1:
  102.             options.c_cflag &= ~CSTOPB;
  103.           break;
  104.         case 2:
  105.                   options.c_cflag |= CSTOPB;
  106.           break;
  107.         default:
  108.                   fprintf(stderr,"Unsupported stop bitsn");
  109.                   return (FALSE);
  110.         }
  111.           /* Set input parity option */
  112.           if (parity != 'n')
  113.             options.c_iflag |= INPCK;
  114.           options.c_cc[VTIME] = 150; // 15 seconds
  115.             options.c_cc[VMIN] = 0;

  116.         options.c_lflag &= ~(ECHO | ICANON);

  117.           tcflush(fd,TCIFLUSH); /* Update the options and do it NOW */
  118.           if (tcsetattr(fd,TCSANOW,&options) != 0) {
  119.             perror("SetupSerial 3");
  120.                   return (FALSE);
  121.         }
  122.         return (TRUE);
  123. }

  124. /**
  125.         *@breif 打开串口
  126. */
  127. int OpenDev(char *Dev)
  128. {
  129.         int fd = open( Dev, O_RDWR );         //| O_NOCTTY | O_NDELAY
  130.         if (-1 == fd) { /*设置数据位数*/
  131.                    perror("Can't Open Serial Port");
  132.                    return -1;
  133.         } else
  134.                 return fd;
  135. }


  136. /* The name of this program */
  137. const char * program_name;

  138. /* Prints usage information for this program to STREAM (typically
  139. * stdout or stderr), and exit the program with EXIT_CODE. Does not
  140. * return.
  141. */

  142. void print_usage (FILE *stream, int exit_code)
  143. {
  144.     fprintf(stream, "Usage: %s option [ dev... ] n", program_name);
  145.     fprintf(stream,
  146.             "t-h  --help     Display this usage information.n"
  147.             "t-d  --device   The device ttyS[0-3] or ttySCMA[0-1]n"
  148.             "t-b  --baudrate Set the baud rate you can selectn"
  149.             "t               [230400, 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300]n"
  150.             "t-s  --string   Write the device datan");
  151.     exit(exit_code);
  152. }



  153. /*
  154.         *@breif  main()
  155. */
  156. int main(int argc, char *argv[])
  157. {
  158.         int  fd, next_option, havearg = 0;
  159.         char *device;
  160.         int i=0,j=0;
  161.         int nread;                        /* Read the counts of data */
  162.         char buff[512];                /* Recvice data buffer */
  163.         pid_t pid;
  164.         char *xmit = "1234567890"; /* Default send data */
  165.         int speed, send_mode = 0;
  166.         const char *const short_options = "hd:s:b:m:";

  167.         const struct option long_options[] = {
  168.                 { "help",   0, NULL, 'h'},
  169.                 { "device", 1, NULL, 'd'},
  170.                 { "string", 1, NULL, 's'},
  171.                 { "baudrate", 1, NULL, 'b'},
  172.                 { "send/recv mode", 0, NULL, 'm'},
  173.                 { NULL,     0, NULL, 0  }
  174.         };
  175.        
  176.         program_name = argv[0];

  177.         do {
  178.                 next_option = getopt_long (argc, argv, short_options, long_options, NULL);
  179.                 switch (next_option) {
  180.                         case 'h':
  181.                                 print_usage (stdout, 0);
  182.                         case 'd':
  183.                                 device = optarg;
  184.                                 havearg = 1;
  185.                                 break;
  186.                         case 'b':
  187.                                 speed = atoi(optarg);
  188.                                 break;
  189.                         case 's':
  190.                                 xmit = optarg;
  191.                                 havearg = 1;
  192.                                 break;
  193.                         case 'm':
  194.                                 send_mode = atoi(optarg);
  195.                                 break;
  196.                         case -1:
  197.                                 if (havearg)  break;
  198.                         case '?':
  199.                                 print_usage (stderr, 1);
  200.                         default:
  201.                                 abort ();
  202.                 }
  203.         }while(next_option != -1);

  204.         sleep(1);
  205.         fd = OpenDev(device);

  206.         if (fd > 0) {
  207.                 set_speed(fd, speed);
  208.         } else {
  209.                 fprintf(stderr, "Error opening %s: %sn", device, strerror(errno));
  210.                 exit(1);
  211.         }

  212.         if (set_Parity(fd,8,1,'N')== FALSE) {
  213.                 fprintf(stderr, "Set Parity Errorn");
  214.                 close(fd);
  215.                 exit(1);
  216.         }
  217. #if 0
  218.         pid = fork();       

  219.         if (pid < 0) {
  220.                 fprintf(stderr, "Error in fork!n");
  221.         } else if (pid == 0){
  222. #endif
  223.     if (send_mode){
  224.                 while(1) {
  225.                         printf("%s SEND: %sn",device, xmit);
  226.                         write(fd, xmit, strlen(xmit));
  227.                         sleep(1);
  228.                         i++;
  229.                 }
  230.     }else {
  231.                 while(1) {
  232.                         nread = read(fd, buff, sizeof(buff));
  233.                         if (nread > 0) {
  234.                                 buff[nread] = '\0';
  235.                                 printf("%s RECV[%d]: %sn", device, nread, buff);
  236.                         }
  237.                 }
  238.         }
  239.         close(fd);
  240.         exit(0);
  241. }

最后,加上makefile:
  1. include ../env.mk
  2. TARGET = $(notdir $(CURDIR))
  3. objs := $(patsubst %c, %o, $(shell ls *.c))
  4. $(TARGET)_test:$(objs)
  5.         $(CC) -o $@ $^
  6. %.o:%.c
  7.         $(CC) -c -o $@ [        DISCUZ_CODE_392        ]lt;
  8. clean:
  9.         rm -f  $(TARGET)_test *.all *.o
执行测试结果:
程序开辟一个进程,每隔1s向终端中输出字符串 “1234567890”。




回帖(1)

casy

2020-5-27 14:20:21
感谢分享,赞
举报

更多回帖

发帖
×
20
完善资料,
赚取积分