系统环境:
主机: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排灯,需要扩列的自行修改代码。
// --------------------------------------------------------------------------------------------------------