串口简介
定义
1.设备间的一种通信方式
2.按顺序一位位传送数据
3.双向通信,全双工
4.传输速度相对较慢
串口的电平
异步串行是指UART,通用异步接收,发送。UART包含TTL的串口和RS232串口。
TTL电平是3.3V的,EL806为TTL接口。
RS232是负逻辑电平,5~12V为低电平,-12~-5V为高电平,MDS2710、MDS SD4、 EL805等为RS232接口。
串口标准和协议
串行接口按电气标准及协议来分包括RS-232-C、RS-422、RS485等。RS-232-C、RS-422与RS-485标准只对接口的电气特性做出规定,不涉及接插件、电缆或协议。
RS-232
也称标准串口,最常用的一种[串行通讯接口,比如我们的电脑主机的9针串口,最高速率为20kb/sRS-232是为点对点(即只用一对收、发设备)通讯而设计的,其传送距离最大为约15米。所以RS-232适合本地设备之间的通信
RS-422
由于接收器采用高输入阻抗和发送驱动器比RS232更强的驱动能力,故允许在相同传输线上连接多个接收节点,最多可接10个节点。即一个主设备(Master),其余为从设备(Slave),从设备之间不能通信,所以RS-422支持点对多的双向通信。RS-422的最大传输距离为1219米,最大传输速率为10Mb/s。平衡双绞线的长度与传输速率成反比。
RS-485
从RS-422基础上发展而来的,无论四线还是二线连接方式总线上可多接到32个设备。
串口的接线方式
demo1:
基于wiringPi库的接口(),实现主机与Pi之间的数据传输
代码示例:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <wiringPi.h>
#include <wiringSerial.h>
int fd;
void *sendBuf()
{
char *send_buf;
while(1)
{
send_buf = (char *)malloc(32);
scanf("%s",send_buf);
while(*send_buf)
{
serialPutchar(fd,*send_buf++);
}
}
}
void *getBuf()
{
while(1)
{
while(serialDataAvail(fd))
{
printf("get data: %c\n",serialGetchar(fd));
fflush (stdout) ;
}
}
}
int main ()
{
pthread_t send_data;
pthread_t get_data;
if ((fd = serialOpen ("/dev/ttyS5", 115200)) < 0)
{
fprintf (stderr, "Unable to open serial device: %s\n", strerror (errno)) ;
return 1 ;
}
if (wiringPiSetup () == -1)
{
fprintf (stdout, "Unable to start wiringPi: %s\n", strerror (errno)) ;
return 1 ;
}
pthread_create(&send_data,NULL,sendBuf,NULL);
pthread_create(&get_data,NULL,getBuf,NULL);
while(1);
return 0 ;
}
代码结果示例:
demo2:
linux原生串口实现
代码示例:
func.c
#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>
int serialOpen (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 ;
default:
return -2 ;
}
if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1)
return -1 ;
fcntl (fd, F_SETFL, O_RDWR) ;
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 ;
tcsetattr (fd, TCSANOW, &options) ;
ioctl (fd, TIOCMGET, &status);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ;
return fd ;
}
void serialGet (const int fd,char buf[])
{
int n_read;
n_read = read(fd,buf,128);
if(n_read < 0)
{
printf("read error\n");
}
else
{
if(strlen(buf) > 0)
{
printf("get msg : %s\n",buf);
}
}
}
void serialPut (const int fd,char buf[])
{
int n_write;
n_write = write(fd,buf,128);
if(n_write < 0)
{
printf("write error\n");
}
}
func.h
int serialOpen (const char *device, const int baud);
void serialGet (const int fd,char buf[]);
void serialPut (const int fd,char *buf);
main_pro.c
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include "func.h"
int fd;
void *sendBuf()
{
char buf[128] = {'\0'};
while(1)
{
memset(buf,'\0',128);
scanf("%s",buf);
serialPut (fd,buf);
}
}
void *getBuf()
{
char buf[128] = {'\0'};
while(1)
{
memset(buf,'\0',128);
serialGet (fd,buf);
}
}
void result()
{
pthread_t sendMsg;
pthread_t getMsg;
fd = serialOpen ("/dev/ttyS5",115200);
if(fd < 0)
{
printf("open serial fail\n");
exit(-1);
}
pthread_create(&sendMsg,NULL,sendBuf,NULL);
pthread_create(&getMsg,NULL,getBuf,NULL);
while(1);
}
int main()
{
result();
return 0;
}
代码结果示例: