主要分成
- 打开串口
- 关闭串口
- 发送字符、字符串
- 发送格式化字符串
- 等待接收字符的数量
- 接收一个字符
- 释放缓冲区
一、模块代码
用到的头文件
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <string.h>
#include <stdarg.h>
1、打开串口
int serialOpen (const char *device, const int baud)
{
struct termios options ;
speed_t myBaud ;
int status, fd ;
switch (baud)
{
case 50: myBaud = B50 ; break ;
case 75: myBaud = B75 ; break ;
case 110: myBaud = B110 ; break ;
case 134: myBaud = B134 ; break ;
case 150: myBaud = B150 ; break ;
case 200: myBaud = B200 ; break ;
case 300: myBaud = B300 ; break ;
case 600: myBaud = B600 ; break ;
case 1200: myBaud = B1200 ; break ;
case 1800: myBaud = B1800 ; break ;
case 2400: myBaud = B2400 ; break ;
case 4800: myBaud = B4800 ; break ;
case 9600: myBaud = B9600 ; break ;
case 19200: myBaud = B19200 ; break ;
case 38400: myBaud = B38400 ; break ;
case 57600: myBaud = B57600 ; break ;
case 115200: myBaud = B115200 ; break ;
case 230400: myBaud = B230400 ; 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 | TCSAFLUSH, &options) ;
ioctl (fd, TIOCMGET, &status);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ; // 10mS
return fd ;
}
2、关闭串口
void serialClose (const int fd)
{
close (fd) ;
}
3、发送字符、字符串
void serialPutchar (const int fd, const unsigned char c)
{
write (fd, &c, 1) ;
}
void serialPuts (const int fd, const char *s)
{
write (fd, s, strlen(s)) ;
}
4、发送格式化字符串
void serialPrintf (const int fd, const char *message, ...)
{
va_list argp ;
char buffer [1024] ;
va_start (argp, message) ;
vsnprintf (buffer, 1023, message, argp) ;
va_end (argp) ;
serialPuts (fd, buffer) ;
}
5、等待接收字符的数量
int serialDataAvail (const int fd)
{
int result ;
if (ioctl (fd, FIONREAD, &result) == -1)
return -1 ;
return result ;
}
6、接收一个字符
int serialGetchar (const int fd)
{
uint8_t x ;
if (read (fd, &x, 1) != 1)
return -1 ;
return ((int)x) & 0xFF ;
}
6、释放缓冲区
void serialFlush (const int fd)
{
tcflush (fd, TCIOFLUSH) ;
}
二、模块测试
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
int running = 1;
void sig_handle(int sig)
{
if(sig == SIGINT) running = 0;
}
int main()
{
signal(SIGINT, sig_handle);
int fd;
if(wiringPiSetup() < 0){
printf("wiringPi setup failed.\n");
return 1;
}
int baudrate = 115200;
// 打开串口
//if((fd = serialOpen("/dev/ttyS0", baudrate)) < 0){
if((fd = serialOpen("/dev/ttyAMA0",baudrate)) < 0){
printf("serial open failed.\n");
return 1;
}
printf("serial test output ...\n");
serialPrintf(fd, "0123456789abcdef"); // 发送
while(running)
{
int sz = serialDataAvail(fd); // 待接收的字符数量
if(sz > 0)
{
printf("size %d, ", sz);
char *buff =(char*)malloc(sz);
printf("recv: ");
for(int i = 0; i < sz; i++){
int c = serialGetchar(fd);
//if(c != -1)
buff[i] = c;
}
printf("%s\n", buff);
free(buff);
serialPrintf(fd, buff);
}
else{
usleep(50000); // 必要的延时
}
}
serialClose(fd);
printf("close serial.\n");
return 0;
}