头文件
#ifndef __SERIAL_H__
#define __SERIAL_H__
int serial_init(const char *devpath, int baudrate);
ssize_t serial_recv(int fd, void *buf, size_t count);
ssize_t serial_send(int fd, const void *buf, size_t count);
ssize_t serial_recv_exact_nbytes(int fd, void *buf, size_t count);
ssize_t serial_send_exact_nbytes(int fd, const void *buf, size_t count);
int serial_exit(int fd);
#endif
串口文件
备注很清晰就不多加备注了,如果串口不一样修改一下波特率等就可以直接使用了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <termios.h>
#include “serial.h”
/*********************************************************************************
* Description: 串口初始化
* Input: devpath:串口设备文件路径
* Output: baudrate:波特率
* Return: 无
* Others: 无。
**********************************************************************************/
int serial_init(const char *devpath, int baudrate)
{
int fd;
struct termios oldtio, newtio;
assert(devpath != NULL);
fd = open(devpath, O_RDWR | O_NOCTTY);
if (fd == -1) {
perror("serial->open");
return -1;
}
tcgetattr(fd, &oldtio); /* save current port settings */
memset(&newtio, 0, sizeof(newtio));
newtio.c_cflag = baudrate | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
newtio.c_lflag = 0; /* set input mode (non-canonical, no echo,...) */
newtio.c_cc[VTIME] = 40; /* set timeout value, n * 0.1 S */
newtio.c_cc[VMIN] = 0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
return fd;
}
/*********************************************************************************
* Description: 串口接收
* Input: fd:串口设备描述符
* count:接收数据长度
* Output: buf:接收buf,用户提供,保证有效性。
* Return: >=0 接收了的实际数据长度,<0表示失败。
* Others: 无。
**********************************************************************************/
ssize_t serial_recv(int fd, void *buf, size_t count)
{
ssize_t ret;
assert(buf != NULL);
ret = read(fd, buf, count);
if (ret == -1)
perror("serial->send");
return ret;
}
/*********************************************************************************
* Description: 串口发送
* Input: fd:串口设备描述符
* buf:发送buf,用户提供,保证有效性。
* count:发送数据长度
* Output: 无。
* Return: >=0 发送了的实际数据长度,<0表示失败。
* Others: 无。
**********************************************************************************/
ssize_t serial_send(int fd, const void *buf, size_t count)
{
ssize_t ret;
assert(buf != NULL);
ret = write(fd, buf, count);
if (ret == -1)
perror("serial->send");
return ret;
}
/*********************************************************************************
* Description: 大数据的串口接收
* Input: fd:串口设备描述符
* count:接收数据长度
* Output: buf:接收buf,用户提供,保证有效性。
* Return: >0 接收了的实际数据长度,<=0表示失败。
* Others: 该接口要么接收完整用户传入长度数据,要么返回失败。
**********************************************************************************/
ssize_t serial_recv_exact_nbytes(int fd, void *buf, size_t count)
{
ssize_t ret;
ssize_t total = 0;
assert(buf != NULL);
while (total != count) {
ret = read(fd, buf + total, count - total);
if (ret == -1) {
perror("serial->recv");
total = -1;
break;
} else if (ret == 0) {
fprintf(stdout, "serial->recv: timeout or end-of-file\n");
total = 0;
break;
} else
total += ret;
}
return total;
}
/*********************************************************************************
* Description: 大数据的串口发送
* Input: fd:串口设备描述符
* buf:发送buf,用户提供,保证有效性。
* count:发送数据长度
* Output: 无。
* Return: >=0 发送了的实际数据长度,<0表示失败。
* Others: 该接口要么发送完整用户传入长度数据,要么返回失败。。
**********************************************************************************/
ssize_t serial_send_exact_nbytes(int fd, const void *buf, size_t count)
{
ssize_t ret;
ssize_t total = 0;
assert(buf != NULL);
while (total != count) {
ret = write(fd, buf + total, count - total);
if (ret == -1) {
perror("serial->send");
total = -1;
break;
} else
total += ret;
}
return total;
}
/*********************************************************************************
* Description: 串口退出
* Input: fd:设备描述符
* Output: 无
* Return: 无
* Others: 无。
**********************************************************************************/
int serial_exit(int fd)
{
if (close(fd)) {
perror("serial->exit");
return -1;
}
return 0;
}
串口通信操作
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <errno.h>
#include <poll.h>
#include <sys/ioctl.h>
#include "serial.h"
char cmd[5]= {0};
int cfd;
unsigned char cmdbuf[5]={0xff,0x00,0x00,0x00,0xff};
int main()
{
int fd=serial_init("/dev/ttyATH0", 9600);
if( fd < 0)
{
perror("init_serial");
return -1;
}
if(fd == 0)
{
return -1;
}
int sfd = socket(AF_INET,SOCK_STREAM,0);//socket
if(sfd < 0)
{
perror("socket");
return -1;
}
struct sockaddr_in saddr,caddr;
saddr.sin_family=AF_INET;
saddr.sin_port=htons(6666);
saddr.sin_addr.s_addr = inet_addr("192.168.1.1");
int opt = 1;
setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,(const void *)&opt, sizeof(opt));
int ret = bind(sfd,(struct sockaddr*)&saddr,sizeof(struct sockaddr_in));
if(ret < 0)
{
perror("bind:");
return -1;
}
ret = listen(sfd, 5);
if(ret < 0)
{
perror("listen");
return -1;
}
socklen_t caddrlen = 0;
while(1)
{
cfd = accept(sfd,(struct sockaddr*)&caddr,&caddrlen);
if(-1 == cfd)
{
perror("accept");
return -1;
}
while(1)
{
int ret=read(cfd,cmd,sizeof(cmd));//读取客户端指令
if(ret<0)
{
perror("read");
break;
}
else if(ret == 0)
{
printf("客户端关闭");
break;
}
if(cmdbuf[0] == 0xff && cmdbuf[4] == 0xff)
{
if(strncmp(cmd, "u", 1) == 0)//判断客户端发送的请求是否是"u"
{
//给小车写前进命令
printf("cmd=%s\n",cmdbuf);
cmdbuf[2] = 0x01;
write(fd, cmdbuf, sizeof(cmdbuf));
}
else if(strncmp(cmd, "d", 1) == 0)//判断客户端发送的请求是否是"d"
{
//给小车写后退命令
printf("cmd=%s\n",cmd);
cmdbuf[2] = 0x02;
write(fd, cmdbuf, sizeof(cmdbuf));
}
else if(strncmp(cmd, "r", 1) == 0)//判断客户端发送的请求是否是"r"
{
//给小车写右转命令
printf("cmd=%s\n",cmd);
cmdbuf[2] = 0x04;
write(fd, cmdbuf, sizeof(cmdbuf));
}
else if(strncmp(cmd, "l", 1) == 0)//判断客户端发送的请求是否是"l"
{
//给小车写左转命令
printf("cmd=%s\n",cmd);
cmdbuf[2] = 0x03;
write(fd, cmdbuf, sizeof(cmdbuf));
}
else if(strncmp(cmd, "s", 1) == 0)//判断客户端发送的请求是否是"s"
{
//给小车写停止命令
printf("cmd=%s\n",cmd);
cmdbuf[2] = 0x00;
write(fd, cmdbuf, sizeof(cmdbuf)); //
}
}
}
close(cfd);
}
close(sfd);
}
这里主要就是控制小车的移动,没有涉及到驱动等等,所以还是比较的简单,这里有一份小车的通信协议附上
下一篇介绍摄像头,已经写了转码的代码,但是没用上。下一篇一起附上