串口简介(实在不知道怎么开头)
百度百科说:一条信息的各位数据被逐位按顺序传送的通讯方式称为串行通讯。
特点在于逐位传输,而在Linux系统中,我们使用的串口还有一个特点是全双工的
所以我们可以总结出在Linux串口开发中需要注意的:1、波特率设置 2、全双工传输
实操
本文代码基于wiringPi库进行开发
进行代码编写前根据用户手册可以对将要使用的串口进行启用,跟上一章说到的一样,在orangepiEnv.txt中的overlays=语句后添加对应串口编号(用哪个自己查对应编号),重启使配置文件生效
重启后输入命令
ls /dev/ttyS*
查看可用串口
香橙派5会显示如下的串口
其中ttyS9是调试串口,所以用户共有4个串口可使用
现在来到代码实现
根据我们之前说的串口特点:波特率设置,全双工传输
串口指定与波特率设置wiringPi库已经写好了,只需要在orangepiEnv.txt里启用对应串口就行
而全双工可以用多线程实现
代码下收
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <stdlib.h>
int fd;
void* Sendhandler()
{
char *sendBuf;
sendBuf = (char *)malloc(32*sizeof(32));
while(1){
memset(sendBuf,'\0',32);
scanf("%s",sendBuf);
while(*sendBuf){
serialPutchar (fd, *sendBuf++) ;
}
}
}
void* Revhandler()
{
while(1){
while (serialDataAvail(fd))
{
printf ("%c", serialGetchar(fd)) ;
fflush (stdout) ;
}
}
}
int main ()
{
int count ;
unsigned int nextTime ;
pthread_t idSend;
pthread_t idRev;
if ((fd = serialOpen ("/dev/ttyS5", 115200)) < 0)
{
fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno));
return 1 ;
}
pthread_create(&idSend, NULL,Sendhandler,NULL);
pthread_create(&idRev, NULL,Revhandler,NULL);
if (wiringPiSetup () == -1)
{
fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
return 1 ;
}
while(1){sleep(10);}
printf ("\n") ;
return 0 ;
上面是我们根据串口的特点来进行的代码开发
下面回到Linux原生串口开发
在通过51单片机对串口模块的学习中我们曾经写过这样的初始化函数
而在原生串口的开发中我们也需要对波特率,停止位,数据位等串口属性做设置
因此针对香橙派5我根据原生串口的代码做了一下修改:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "wiringSerial.h"
int mySerialOpen(const char *device,const int baud)
{
struct termios options ;
speed_t myBaud ;
int status, fd ;
switch (baud)
{
case 9600 : myBaud = B9600; break;
case 115200 : myBaud = B115200;break;
case 1500000:myBaud = B1500000;break;
default:
return -2;
}
if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
return -1 ;
fcntl (fd, F_SETFL, O_RDWR) ;
// Get and modify current options:
tcgetattr (fd, &options) ;
cfmakeraw (&options) ;
cfsetispeed (&options, myBaud) ;
cfsetospeed (&options, myBaud) ;
options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~PARENB ;
options.c_cflag &= ~CSTOPB ;
options.c_cflag &= ~CSIZE ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;
options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 100 ; // Ten seconds (100 deciseconds)
tcsetattr (fd, TCSANOW, &options) ;
ioctl (fd, TIOCMGET, &status);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ; // 10mS
return fd ;
}
void serialSendString (const int fd, const unsigned char *s,int len)
{
int ret;
ret = write (fd, s, len);
if (ret < 0)
printf("Serial Puts Error\n");
}
int serialGetString(const int fd, unsigned char *buffer)
{
int n_read = 0;
n_read = read(fd,buffer,32);
return n_read;
}
至此,串口开发讲完了