• 树莓派进阶之路 (041)


    系统环境:

      主机:Linux ubuntu 5.4.0-45-generic #49~18.04.2-Ubuntu SMP Wed Aug 26 16:29:02 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

      树莓派:Linux raspberrypi 4.19.97-v7+ #1294 SMP Thu Jan 30 13:15:58 GMT 2020 armv7l GNU/Linux

    串口要求以及相关配置方案:

    // -------------------------------------------------------------------------------------------------------- 华丽的分割线 --------------------------------------------------------------------------------------------------------------------------

    简单的使用串口通信,波特率要求不高(波特率500k以下),可以简单的配置使用:

    1、简单配置通系统通信串口:使用《树莓派进阶之路 (022) - 串口篇 - 通过串口连接控制树莓派》配置结果如下:

    2、通过  raspi-config 关闭系统和串口的链接(Interfacing Options => Serial =》Select =》ok =》Finish )

    选择:Interfacing Options

     

    选择:Serial-》Select

     

     选择:ok

     选择:Finish

     3、删除配置启动引导配置文件(/boot/cmdline.txt)的串口配置(console=serial0,115200)

    sudo vim /boot/cmdline.txt

     4、重启(reboot)

     5、文件测试

    main.c

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <errno.h>
      4 #include <unistd.h>
      5 #include <stdlib.h>
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 #include <stdint.h>
      9 #include <stdarg.h>
     10 #include <string.h>
     11 #include <termios.h>
     12 #include <unistd.h>
     13 #include <fcntl.h>
     14 #include <sys/ioctl.h>
     15 #include <sys/types.h>
     16 #include <sys/stat.h>
     17 
     18 #define par_type  long
     19 
     20 // ----------------------------------------------------------------------------------------
     21 int serialOpen (const char *device, const long baud)
     22 {
     23   struct termios options ;
     24   speed_t myBaud ;
     25   int     status, fd ;
     26 
     27   switch (baud)
     28   {
     29     case      50:    myBaud =      B50 ; break ;
     30     case      75:    myBaud =      B75 ; break ;
     31     case     110:    myBaud =     B110 ; break ;
     32     case     134:    myBaud =     B134 ; break ;
     33     case     150:    myBaud =     B150 ; break ;
     34     case     200:    myBaud =     B200 ; break ;
     35     case     300:    myBaud =     B300 ; break ;
     36     case     600:    myBaud =     B600 ; break ;
     37     case    1200:    myBaud =    B1200 ; break ;
     38     case    1800:    myBaud =    B1800 ; break ;
     39     case    2400:    myBaud =    B2400 ; break ;
     40     case    4800:    myBaud =    B4800 ; break ;
     41     case    9600:    myBaud =    B9600 ; break ;
     42     case   19200:    myBaud =   B19200 ; break ;
     43     case   38400:    myBaud =   B38400 ; break ;
     44     case   57600:    myBaud =   B57600 ; break ;
     45     case  115200:    myBaud =  B115200 ; break ;
     46     case  230400:    myBaud =  B230400 ; break ;
     47     case  460800:    myBaud =  B460800 ; break ;
     48     case  500000:    myBaud =  B500000 ; break ;
     49     case  576000:    myBaud =  B576000 ; break ;
     50     case  921600:    myBaud =  B921600 ; break ;
     51     case 1000000:    myBaud = B1000000 ; break ;
     52     case 1152000:    myBaud = B1152000 ; break ;
     53     case 1500000:    myBaud = B1500000 ; break ;
     54     case 2000000:    myBaud = B2000000 ; break ;
     55     case 2500000:    myBaud = B2500000 ; break ;
     56     case 3000000:    myBaud = B3000000 ; break ;
     57     case 3500000:    myBaud = B3500000 ; break ;
     58     case 4000000:    myBaud = B4000000 ; break ;
     59 
     60     default:
     61       return -2 ;
     62   }
     63 
     64   if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
     65     return -1 ;
     66 
     67   fcntl (fd, F_SETFL, O_RDWR) ;
     68 
     69 // Get and modify current options:
     70 
     71   tcgetattr (fd, &options) ;
     72 
     73     cfmakeraw   (&options) ;
     74     cfsetispeed (&options, myBaud) ;
     75     cfsetospeed (&options, myBaud) ;
     76 
     77     options.c_cflag |= (CLOCAL | CREAD) ;
     78     options.c_cflag &= ~PARENB ;
     79     options.c_cflag &= ~CSTOPB ;
     80     options.c_cflag &= ~CSIZE ;
     81     options.c_cflag |= CS8 ;
     82     options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
     83     options.c_oflag &= ~OPOST ;
     84 
     85     options.c_cc [VMIN]  =   0 ;
     86     options.c_cc [VTIME] = 100 ;    // Ten seconds (100 deciseconds)
     87 
     88   tcsetattr (fd, TCSANOW, &options) ;
     89 
     90   ioctl (fd, TIOCMGET, &status);
     91 
     92   status |= TIOCM_DTR ;
     93   status |= TIOCM_RTS ;
     94 
     95   ioctl (fd, TIOCMSET, &status);
     96 
     97   usleep (10000) ;    // 10mS
     98 
     99   return fd ;
    100 }
    101 // ----------------------------------------------------------------------------------------
    102 struct  serial_test_data{
    103     int fd;
    104     unsigned int Features;
    105     unsigned char buf[1024];
    106     unsigned long long  H_count;
    107     unsigned long long  L_count;
    108 };
    109 // ----------------------------------------------------------------------------------------
    110 long baud_value;
    111 // 传参处理函数
    112 // main  收发状态 波特率 设备地址  发送数据
    113 int main_Parameter_handling_function(par_type serial_addr, int argc, char* argv[]){
    114     struct  serial_test_data *serial = (struct  serial_test_data *)serial_addr;
    115     baud_value = 115200;
    116     if(1 == argc){printf("请配置参数: 0 发送模式,1接受模式
    ");printf("请配置波特率:默认115200
    ");return 1;}
    117     if(argc == 2){printf("默认115200
    ");if(0 == atoi(argv[1]))serial->Features = 0;else if(1 == atoi(argv[1]))serial->Features = 1;}
    118     if(argc == 3){
    119         if(0 == atoi(argv[1]))serial->Features = 0;
    120         else if(1 == atoi(argv[1]))serial->Features = 1;
    121         baud_value = atoi(argv[2]);
    122     }
    123     return 0;
    124 }
    125 //  串口
    126 int Serial_Parameter_handling_function(par_type serial_addr,const long baud,const char * serial_device){
    127     struct  serial_test_data *serial = (struct  serial_test_data *)serial_addr;
    128     int ret ;
    129     if ((serial->fd = serialOpen (serial_device, baud)) < 0){
    130         fprintf (stderr, "Unable to open serial device: %s
    ", strerror (errno)) ;
    131         ret = 1 ;
    132   }else {
    133       tcflush (serial->fd, TCIOFLUSH) ;
    134       memset(serial->buf,0,strlen(serial->buf));
    135       serial-> H_count = 0;
    136       serial-> L_count = 0;
    137       ret =  0;
    138   }
    139   return ret;
    140 }
    141 // ----------------------------------------------------------------------------------------
    142 // ----------------------- write
    143 // char
    144 void Serial_write_char(const int fd, const unsigned char c){write (fd, &c, 1) ;}
    145 //  string
    146 void Serial_write_string(const int fd, const char *s){write (fd, s, strlen (s));}
    147 //  ----------------------- read
    148 int Serial_read_char(const int fd){
    149     unsigned char x ;
    150     if (read (fd, &x, 1) != 1)return -1 ;
    151     return ((int)x) & 0xFF ;
    152 }
    153 // ----------------------------------------------------------------------------------------
    154 void Serial_data(par_type serial_addr,const char *s){
    155     struct  serial_test_data *serial = (struct  serial_test_data *)serial_addr;
    156     int len =  write (serial->fd, s, strlen (s));
    157   //  printf("len = %d  strlen (s) = %d
    ",len,strlen (s));
    158     if(len == strlen (s)){
    159       serial->L_count = serial->L_count + strlen (s);
    160         if (serial->L_count > 1000000000) {
    161           serial->L_count = serial->L_count - 1000000000;
    162           serial-> H_count = serial-> H_count + 1;
    163         }
    164     }
    165 }
    166 // ----------------------------------------------------------------------------------------
    167 int main(int argc, char *argv[]){
    168     struct serial_test_data serial0;
    169     int ret;
    170     if(main_Parameter_handling_function((par_type)&serial0,argc,argv))return 1;            // main 函数处理
    171     if(Serial_Parameter_handling_function((par_type)&serial0,baud_value,"/dev/serial0"));  //  串口处理函数
    172     while(1){
    173       if (0 == serial0.Features){
    174         sprintf(serial0.buf,"jikexianfeng %lld
    ",serial0.L_count);
    175         Serial_data((par_type)&serial0,serial0.buf);
    176       }
    177       else if (1 == serial0.Features) printf("%c", Serial_read_char(serial0.fd));
    178       else{
    179         close(serial0.fd);ret = 1;
    180       }
    181     }
    182     return ret;
    183 }

    编译:gcc main.c -o main

    1 sudo ./main 收发模式 波特率(可省略,默认115200)
    2 sudo ./main 0     // 发送模式
    3 sudo ./main 1     // 接收模式

    // -------------------------------------------------------------------------------------------------------- 华丽的分割线 --------------------------------------------------------------------------------------------------------------------------

    默认stc51单片机举例,代码方法比较全面,选择适合的自己的就行。

    本代码默认支持8位的lcd排灯,需要扩列的自行修改代码。

    创作不易,转载说明出处,谢谢!

     // --------------------------------------------------------------------------------------------------------

  • 相关阅读:
    设计模式之四 代理模式
    设计模式之四 建造者模式
    设计模式之三 模板模式
    设计模式之二 工厂模式
    如何使用Json-lib
    Java LoggingAPI 使用方法
    设计模式之一 单例模式
    Scrapy教程
    Scrapy简介
    Scrapy安装向导
  • 原文地址:https://www.cnblogs.com/jikexianfeng/p/13625497.html
Copyright © 2020-2023  润新知