小车项目整理

1、摄像头模块

测试程序(main.c)

#include "cam.h"
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>

int main()
{
	unsigned int width,height,size,ismjpeg,index;
	unsigned char *jpeg_ptr = NULL;
	width = 320;
	height = 240;
	int fd = camera_init("/dev/video0",&width, &height, &size, &ismjpeg);
	if(fd < 0)
	{
		return -1;
	}
	camera_start(fd);
	signal(SIGPIPE, SIG_IGN);
	int i = 0;
	for(i = 0; i < 10; i++)
	{
		camera_dqbuf(fd,(void **) &jpeg_ptr, &size, &index);
		printf("jpeg_ptr:%p\tsize:%d\n",jpeg_ptr,size);
		char fn[10] = {0};
		sprintf(fn,"%d.jpg",i);
		int myf = open(fn, O_WRONLY | O_CREAT, 0664);
		write(myf, jpeg_ptr, size);
		close(myf);
		sleep(5);
		camera_eqbuf(fd, index);
	}
	camera_stop(fd);
	camera_exit(fd);
	return 0;
}

依赖的摄像头驱动程序

cam.h 头文件

#ifndef __CAM_H__
#define __CAM_H__
#include <sys/types.h>

/*store picture buf*/
struct cam_buf
{
	void *start;
	size_t length;
};

int camera_init(char *devpath, unsigned int *width, unsigned int *height, unsigned int *size, unsigned int *ismjpeg);
int camera_start(int fd);
int camera_dqbuf(int fd, void **buf, unsigned int *size, unsigned int *index);
int camera_eqbuf(int fd, unsigned int index);
int camera_stop(int fd);
int camera_exit(int fd);
#endif

cam.c

#include <stdio.h>
#include "cam.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/videodev2.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/time.h>
#include <errno.h>

#define REQBUFS_COUNT 4

struct v4l2_requestbuffers reqbufs;
struct cam_buf bufs[REQBUFS_COUNT];

int camera_init(char *devpath, unsigned int *width, unsigned int *height, unsigned int *size, unsigned int *ismjpeg)
{
	int i;
	int fd = -1;
	int ret;
	struct v4l2_buffer vbuf;
	struct v4l2_format format;
	struct v4l2_capability capability;

	/*open device of video*/
	if((fd = open(devpath, O_RDWR)) == -1)
	{
		perror("open");
		return -1;
	}

	/*ioctl look support drives*/
	ret = ioctl(fd, VIDIOC_QUERYCAP, &capability);
	if(ret == -1)
	{
		perror("camera->init");
		return -1;
	}

	/*look support video capture yes or no*/
	if(!(capability.capabilities & V4L2_CAP_VIDEO_CAPTURE))
	{
		fprintf(stderr, "camera->init: device can not supprot V4L2_CAP_VIDEO_CAPTURE.\n");
		close(fd);
		return -1;
	}

	/*look device support video stream yes or no*/
	if(!(capability.capabilities & V4L2_CAP_STREAMING))
	{
		fprintf(stderr,"camera->init: device can not support V4L2_CAP_STREAMING.\n");
		close(fd);
		return -1;
	}

	/*set capture format MJPEG*/
	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	format.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
	format.fmt.pix.width = *width;
	format.fmt.pix.height = *height;
	format.fmt.pix.field = V4L2_FIELD_ANY;

	ret = ioctl(fd, VIDIOC_S_FMT, &format);
	if(ret == -1)
	{
		perror("camera init");
		return -1;
	}
	else
	{
		*ismjpeg = 0;
		fprintf(stdout, "camera->init: picture format is mjpeg\n");
		goto get_fmt;
	}

	/*set capture format YUYV*/
	memset(&format, 0, sizeof(format));
	format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;			//永远都是这个类型
	format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;		//设置采集图片的格式
	format.fmt.pix.width = *width;
	format.fmt.pix.height = *height;
	format.fmt.pix.field = V4L2_FIELD_ANY;				//设置图片一行一行的采集
	ret = ioctl(fd, VIDIOC_S_FMT, &format);				//ioctl	是设置生效
	if(ret == -1)
	{
		perror("camera init");
	}
	else 
	{
		fprintf(stdout, "camera->init: picture format is yuyv\n");
		*ismjpeg = 1;
		goto get_fmt;
	}

get_fmt:
	ret = ioctl(fd, VIDIOC_G_FMT, &format);
	if (ret == -1) 
	{
		perror("camera init");
		return -1;
	}
	/*向驱动申请缓存*/
	memset(&reqbufs, 0, sizeof(struct v4l2_requestbuffers));
	reqbufs.count	= REQBUFS_COUNT;					//缓存区个数
	reqbufs.type	= V4L2_BUF_TYPE_VIDEO_CAPTURE;
	reqbufs.memory	= V4L2_MEMORY_MMAP;					//设置操作申请缓存的方式:映射 MMAP
	ret = ioctl(fd, VIDIOC_REQBUFS, &reqbufs);			
	if (ret == -1) 
	{	
		perror("camera init");
		close(fd);
		return -1;
	}

	/*循环映射并入队*/
	for (i = 0; i < reqbufs.count; i++)
	{
		/*真正获取缓存的地址大小*/
		memset(&vbuf, 0, sizeof(struct v4l2_buffer));
		vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		vbuf.memory = V4L2_MEMORY_MMAP;
		vbuf.index = i;
		ret = ioctl(fd, VIDIOC_QUERYBUF, &vbuf);
		if (ret == -1) 
		{
			perror("camera init");
			close(fd);
			return -1;
		}
		/*映射缓存到用户空间,通过mmap讲内核的缓存地址映射到用户空间,并切和文件描述符fd相关联*/
		bufs[i].length = vbuf.length;
		bufs[i].start = mmap(NULL, vbuf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, vbuf.m.offset);
		if (bufs[i].start == MAP_FAILED)
		{
			perror("camera init");
			close(fd);
			return -1;
		}
		/*每次映射都会入队,放入缓冲队列*/
		vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
		vbuf.memory = V4L2_MEMORY_MMAP;
		ret = ioctl(fd, VIDIOC_QBUF, &vbuf);
		if (ret == -1) {
			perror("camera init");
			close(fd);
			return -1;
		}
	}
	/*返回真正设置成功的宽.高.大小*/
	*width = format.fmt.pix.width;
	*height = format.fmt.pix.height;
	*size = bufs[0].length;

	return fd;
}

int camera_start(int fd)
{
	int ret;

	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	/*ioctl控制摄像头开始采集*/
	ret = ioctl(fd, VIDIOC_STREAMON, &type);
	if (ret == -1) 
	{
		perror("camera->start");
		return -1;
	}
	fprintf(stdout, "camera->start: start capture\n");
	return 0;
}

int camera_dqbuf(int fd, void **buf, unsigned int *size, unsigned int *index)
{
	int ret;
	fd_set fds;
	struct timeval timeout;
	struct v4l2_buffer vbuf;

	while (1) 
	{
		FD_ZERO(&fds);
		FD_SET(fd, &fds);
		timeout.tv_sec = 4;
		timeout.tv_usec = 0;
		ret = select(fd + 1, &fds, NULL, NULL, &timeout);	//使用select机制,保证fd有图片的时候才能出对
		if (ret == -1) 
		{
			perror("camera->dbytesusedqbuf");
			if (errno == EINTR)
				continue;
			else
				return -1;
		}
		else if (ret == 0) 
		{
			fprintf(stderr, "camera->dqbuf: dequeue buffer timeout\n");
			return -1;
		} 
		else 
		{
			vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
			vbuf.memory = V4L2_MEMORY_MMAP;
			ret = ioctl(fd, VIDIOC_DQBUF, &vbuf);	//出队,也就是从用户空间取出图片
			if (ret == -1) 
			{
				perror("camera->dqbuf");
				return -1;
			}
			*buf = bufs[vbuf.index].start;
			*size = vbuf.bytesused;
			*index = vbuf.index;
			return 0;
		}
	}
}

int camera_eqbuf(int fd, unsigned int index)
{
	int ret;
	struct v4l2_buffer vbuf;

	vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	vbuf.memory = V4L2_MEMORY_MMAP;
	vbuf.index = index;
	ret = ioctl(fd, VIDIOC_QBUF, &vbuf);		//入队
	if (ret == -1) 
	{
		perror("camera->eqbuf");
		return -1;
	}
	return 0;
}

int camera_stop(int fd)
{
	int ret;
	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
	if (ret == -1) 
	{
		perror("camera->stop");
		return -1;
	}
	fprintf(stdout, "camera->stop: stop capture\n");
	return 0;
}

int camera_exit(int fd)
{
	int i;
	int ret;
	struct v4l2_buffer vbuf;
	vbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	vbuf.memory = V4L2_MEMORY_MMAP;
	for (i = 0; i < reqbufs.count; i++) 
	{
		ret = ioctl(fd, VIDIOC_DQBUF, &vbuf);
		if (ret == -1)
			break;
	}
	for (i = 0; i < reqbufs.count; i++)
		munmap(bufs[i].start, bufs[i].length);
	fprintf(stdout, "camera->exit: camera exit\n");
	return close(fd);
}

2、串口模块

serial.h

#ifndef __SERIAL_H__
#define __SERIAL_H__
	/*
	 *function_name: uart_set
	 *function: configure uart arguments
	 *arguments:
	 *	int fd: open serial device return the file descriptor
	 *	int speed: baud rate
	 *	int flow_ctrl: flow control
	 *	int databits: data bits
	 *	int stopbits: stop bits
	 *	int parity: parity
	 *return: 0 is success, -1 is error.
	 */
	int uart_set(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity);

	/*
	 *function_name: init_uart
	 *function: init uart(open the serial device and configure uart arguments)
	 *arguments: void
	 *return: serial device file descriptor is success, -1 is error. 
	 */
	int init_uart();

	/*
	 *function_name: writecmd
	 *function: send str by serial port
	 *arguments:
	 *	int fd: serial device file descriptor
	 *	const char *str: control command
	 *return: sucess return write data len, -1 is error.
	 */
	int writecmd(int fd, const unsigned char *str);

	/*
	 *function_name: recvmsg
	 *function: recv message form serial ports.
	 *arguments:
	 *	int fd: serial device file descriptor
	 *	char *buf: send buf
	 *	int data_len: want to send buf len
	 *return: success is len(>0), -1 is error.
	 */
	int myrecvmsg(int fd, char *buf, int data_len);
#endif

serial.c

#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include "serial.h"
#include <poll.h>
#include <sys/select.h>

//int uart_set(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity);
//int init_uart();
//int writecmd(const char *str);

int writecmd(int fd, const unsigned char *str)
{
	if(fd < 0)
	{
		puts("fd < 0");
		return -1;
	}

	if(NULL == str)
	{
		puts("str is null pointer.");
		return -1;
	}
/*
	unsigned char buf[5] = {0xff, 0x00, 0x00, 0x00, 0xff};
	if(strstr(str, "go_starght"))
	{
		buf[2] = 0x01;
	}
	else if(strstr(str, "go_back"))
	{
		buf[2] = 0x02;
	}
	else if(strstr(str, "go_left"))
	{
		buf[2] = 0x03;
	}
	else if(strstr(str, "go_right"))
	{
		buf[2] = 0x04;
	}
	else if(strstr(str, "stop"))
	{
		buf[2] = 0x00;
	}
*/
	static struct pollfd fds;
	fds.fd = fd;
	fds.events = POLLOUT;
	fds.revents = 0;

	/*60 second timeout*/
	int ret = poll(&fds, 1, 600);
	if(0 >= ret)
	{
		perror("[write_serial]poll");
		return -1;
	}

	if(fds.revents & POLLOUT)
	{
		ret = write(fd, str, 2);
		int i = 0;
		for(i = 0; i < 2; i++)
		{
			printf("%x ",str[i]);
		}
		printf("\nret = %d\n",ret);
		return ret;
	}
	else
	{
		return -1;
	}
}

int init_uart()
{
	//serial_init
	//open ttyUSB0
	int fd_ser = -1;
	fd_ser = open("/dev/ttyATH0", O_RDWR | O_NOCTTY);
	if(fd_ser < 0)
	{
		perror("open serial");
		return -1;
	}
	
	//int ret_s = uart_set(fd_ser, 115200, 0, 8, 1, 'N');
	int ret_s = uart_set(fd_ser, 9600, 0, 8, 1, 'N');
	printf("ret_s:%d\n",ret_s);
	printf("serial->init:init serial success.\n");
	
	return fd_ser;
}

int uart_set(int fd, int speed, int flow_ctrl, int databits, int stopbits, int parity)
{
	int i;
	int status;
	int speed_arr[] = {B115200, B19200, B9600, B4800, B2400, B1200, B300};
	int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300};
	
	struct termios options;
	if(tcgetattr(fd, &options) != 0)
	{
		perror("SetupSerial 1");
		return 0;
	}

	//set baud
	for(i = 0; i < sizeof(speed_arr) / sizeof(int); i++)
	{
		if(speed == name_arr[i])
		{
			cfsetispeed(&options, speed_arr[i]);
			cfsetospeed(&options, speed_arr[i]);
		}
	}
	
	options.c_cflag |= CLOCAL;
	options.c_cflag |= CREAD;
	
	switch(flow_ctrl)
	{
		case 0:
			options.c_cflag &= ~CRTSCTS;
			break;
		case 1:
			options.c_cflag &= CRTSCTS;
			break;
		case 2:
			options.c_cflag |= IXON | IXOFF | IXANY;
			break;
	}

	options.c_cflag &= ~CSIZE;
	switch(databits)
	{
		case 5:
			options.c_cflag |= CS5;
			break;
		case 6:
			options.c_cflag |= CS6;
			break;
		case 7:
			options.c_cflag |= CS7;
			break;
		case 8:
			options.c_cflag |= CS8;
			break;
		default:
			puts("Unsupported data size");
			return 0;
	}

	switch(parity)
	{
		case 'n':
		case 'N':
			options.c_cflag &= ~PARENB;
			options.c_iflag &= ~INPCK;
			break;
		case 'o':
		case 'O':
			options.c_cflag |= (PARODD | PARENB);
			options.c_iflag |= INPCK;
			break;
		case 'e':
		case 'E':
			options.c_cflag |= PARENB;
			options.c_cflag |= ~PARODD;
			options.c_iflag |= INPCK;
			break;
		case 's':
		case 'S':
			options.c_cflag &= ~PARENB;
			options.c_cflag &= ~CSTOPB;
			break;
		default:
			puts("Unsupport parity");
			return 0;
	}

	switch (stopbits)
	{
		case 1:
			options.c_cflag &= ~CSTOPB;
			break;
		case 2:
			options.c_cflag |= CSTOPB;
			break;
		default:
			puts("Unsupported stop bits");
			return 0;
	}

	options.c_oflag &= ~OPOST;
	options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
	
	options.c_cc[VTIME] = 1;
	options.c_cc[VMIN] = 1;

	tcflush(fd, TCIFLUSH);
	
	if(tcsetattr(fd, TCSANOW, &options) != 0)
	{
		perror("com set error");
		return 0;
	}
	return 1;
}

int myrecvmsg(int fd, char *buf, int data_len)
{
	if(fd < 0)
	{
		puts("fd < 0");
		return -1;
	}

	if(NULL == buf)
	{
		puts("buf is null.");
		return -1;
	}
	
	//select serial port
	int len, fs_sel;
	fd_set fs_read;
	
	struct timeval time;
	
	FD_ZERO(&fs_read);
	FD_SET(fd, &fs_read);

	time.tv_sec = 10;
	time.tv_usec = 0;

	fs_sel = select(fd+1, &fs_read, NULL, NULL, &time);
	if(fs_sel)
	{
		len = read(fd, buf, data_len);
		return len;
	}
	else
	{
		return -1;
	}
}

3、网络(socket)v1

主要功能:向串口发送消息

net1.h

#ifndef __NET1_H__
#define __NET1_H__
	int init_net1();
	int do_work1(int connfd1);
	
#endif

net1.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>

#include <signal.h>
#include "serial.h"

int init_net1()
{
	int ser_fd1 = -1;
	//socket
	ser_fd1 = socket(AF_INET, SOCK_STREAM, 0);
	if(ser_fd1 < 0)
	{
		puts("socket1 error.");
		return ser_fd1;
	}
	puts("socket1 success.");
	//bind
	struct sockaddr_in myser;
	memset(&myser, 0, sizeof(myser));
	myser.sin_family = AF_INET;
	myser.sin_port = htons(7777);
	myser.sin_addr.s_addr = htonl(INADDR_ANY);
	int ret = bind(ser_fd1, (struct sockaddr *)&myser, sizeof(myser));
	if(ret != 0)
	{
		puts("bind1 error.");
		close(ser_fd1);
		ser_fd1 = -1;
		return ser_fd1;
	}
	puts("bind1 success.");
	//listen
	ret = listen(ser_fd1, 5);
	if(ret != 0)
	{
		puts("listen1 error.");
		close(ser_fd1);
		ser_fd1 = -1;
		return ser_fd1;
	}
	puts("listen1 success.");
	return ser_fd1;
}


// 向串口发送消息
int do_work1(int connfd1)
{
	if(connfd1 < 0)
	{
		puts("connfd1 < 0");
		return -1;
	}
	int fd_uart = init_uart();
	char cmd[50];
	memset(cmd, 0, sizeof(cmd));
	int ret;
	while(1)
	{
		memset(cmd, 0, sizeof(cmd));
		ret = recv(connfd1, cmd, sizeof(cmd), 0);
		if(ret > 0)
		{
			if(strcmp(cmd,"qq") == 0);
			{
				writecmd(fd_uart,"qq");
			}
			else if(strcmp(cmd,"hh") == 0);
			{
				writecmd(fd_uart,"hh");
			}
			else if(strcmp(cmd,"ll") == 0);
			{
				writecmd(fd_uart,"ll");
			}
			else if(strcmp(cmd,"rr") == 0);
			{
				writecmd(fd_uart,"rr");
			}
			else if(strcmp(cmd,"ss") == 0);
			{
				writecmd(fd_uart,"ss");
			}
		}
	}
	close(fd_uart);
	return 0;
}

对do_work改进

int do_work1(int connfd1)
{
	if(connfd1 < 0)
	{
		puts("connfd1 < 0");
		return -1;
	}
	puts("do work1");
	int fd_uart = init_uart();
	char cmd[50];
	char zxc[]={0xff,0x00,0x00,0x00,};
	memset(cmd, 0, sizeof(cmd));
	int ret;
	while(1)
	{
		memset(cmd, 0, sizeof(cmd));
		ret = recv(connfd1, cmd, sizeof(cmd), 0);
		if(ret > 0)
		{
			if(strcmp(cmd,"q") == 0);
			{
				zxc[2] = 0x01;
				writecmd(fd_uart,zxc);
			}
			if(strcmp(cmd,"h") == 0);
			{
				zxc[2] = 0x02;
				writecmd(fd_uart,zxc);
			}
			if(strcmp(cmd,"l") == 0);
			{
				zxc[2] = 0x03;
				writecmd(fd_uart,zxc);
			}
			if(strcmp(cmd,"r") == 0);
			{
				zxc[2] = 0x04;
				writecmd(fd_uart,zxc);
			}
			if(strcmp(cmd,"s") == 0);
			{
				zxc[2] = 0x00;
				writecmd(fd_uart,zxc);
			}
		}
	}
	return 0;
}

4、网络(socket)v2

相比于上一版本,这一版本多了几个函数用于通信

同时开两个,用到了net1、mynet

主要功能:发送连续的图片信息

测试 main.c

#include "mynet.h"
#include "serial.h"
#include "net1.h"
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
	int ser_fd = init_net();
	int ser_fd1 = init_net1();
	if(ser_fd < 0)
	{
		puts("init_net error.");
		return -1;
	}
	if(ser_fd1 < 0)
	{
		puts("init_net1 error.");
		return -1;
	}
	int connfd = -1;
	int connfd1 = -1;
	struct sockaddr_in mycli;
	int len = sizeof(mycli);
	
	connfd = accept(ser_fd, (struct sockaddr *)&mycli, &len);
	//struct sockaddr_in mycli;
	//int len = sizeof(mycli);
	connfd1 = accept(ser_fd1, (struct sockaddr *)&mycli, &len);
	if(connfd < 0)
	{
		puts("accept error.");
		close(ser_fd);
		return -1;
	}
	puts("accept success.");
	if(connfd1 < 0)
	{
		puts("accept1 error.");
		close(ser_fd1);
		return -1;
	}
	puts("accept1 success.");
	do_work(connfd);
	do_work1(connfd1);
	
	close(ser_fd);
	close(ser_fd1);

	return 0;
}

mynet.h

#ifndef __MYNET_H__
#define __MYNET_H__
	int init_net();
	int do_work(int connfd);
	int get_file_name(char *filename, char *cmd);
	int get_req(char *myreq, char *cmd);
	int get_file_len(int fd);
#endif

mynet.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include "cam.h"
#include <signal.h>

int init_net()
{
	int ser_fd = -1;
	//socket
	ser_fd = socket(AF_INET, SOCK_STREAM, 0);
	if(ser_fd < 0)
	{
		puts("socket error.");
		return ser_fd;
	}
	puts("socket success.");
	//bind
	struct sockaddr_in myser;
	memset(&myser, 0, sizeof(myser));
	myser.sin_family = AF_INET;
	myser.sin_port = htons(8888);
	myser.sin_addr.s_addr = htonl(INADDR_ANY);
	int ret = bind(ser_fd, (struct sockaddr *)&myser, sizeof(myser));
	if(ret != 0)
	{
		puts("bind error.");
		close(ser_fd);
		ser_fd = -1;
		return ser_fd;
	}
	puts("bind success.");
	//listen
	ret = listen(ser_fd, 5);
	if(ret != 0)
	{
		puts("listen error.");
		close(ser_fd);
		ser_fd = -1;
		return ser_fd;
	}
	puts("listen success.");
	return ser_fd;
}

int get_file_name(char *filename, char *cmd)
{
	if(NULL == filename && NULL == cmd)
	{
		puts("get_file_name:error.");
		return -1;
	}

	char *p = cmd+4;
	int len = strlen(cmd);
	cmd[len-1] = 0;
	strcpy(filename, p);
	return 0;
}

int get_req(char *myreq, char *cmd)
{
	if(NULL == myreq && NULL == cmd)
	{
		puts("get_req:error.");
		return -1;
	}

	char *p = cmd;
	int i = 0;
	while(*p != ' ')
	{
		myreq[i] = *p;
		i++;
		p++;
	}
	myreq[i] = 0;
	return 0;
}

int get_file_len(int fd)
{
	if(fd < 0)
	{
		puts("get file len error.");
		return -1;
	}
	int len = lseek(fd, 0, SEEK_SET);
	len = lseek(fd, 0, SEEK_END);
	return len;
}

int do_work(int connfd)
{
	if(connfd < 0)
	{
		puts("connfd < 0");
		return -1;
	}
	puts("do_work");
	char cmd[50];
	memset(cmd, 0, sizeof(cmd));
	int ret = recv(connfd, cmd, sizeof(cmd), 0);
	if(ret > 0)
	{
		unsigned int width,height,size,ismjpeg,index;
		unsigned char *jpeg_ptr = NULL;
		width = 320;
		height = 240;
		int fd = camera_init("/dev/video0",&width, &height, &size, &ismjpeg);
		if(fd < 0)
		{
			return -1;
		}
		camera_start(fd);
		signal(SIGPIPE, SIG_IGN);

		//puts(cmd);
		char filename[40] = {0};
		get_file_name(filename,cmd);
		puts(filename);
		char req[5] = {0};
		get_req(req,cmd);
		puts(req);
		if(strcmp(req,"get") == 0)
		{
			while(1)
			{
				camera_dqbuf(fd,(void **) &jpeg_ptr, &size, &index);
				char filelen[20] = {0};
				sprintf(filelen,"len:%d",size);
				puts(filelen);
				send(connfd, filelen, 20, 0);
				send(connfd, jpeg_ptr, size, 0);
				camera_eqbuf(fd, index);
			}
			camera_stop(fd);
			camera_exit(fd);
		}
		else
		{
			camera_stop(fd);
			camera_exit(fd);
		}
	}
	return 0;
}

5、电机模块(32)

stm32f1

主程序 main.c

/**
  ******************************************************************************
  * File Name          : main.c
  * Description        : Main program body
  ******************************************************************************
  *
  * COPYRIGHT(c) 2021 STMicroelectronics
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"

/* USER CODE BEGIN Includes */
#define MOTOR_A_EN_GPIO GPIOA
#define MOTOR_A_EN_PIN GPIO_PIN_0

#define MOTOR_A_CON1_GPIO GPIOA
#define MOTOR_A_CON1_PIN GPIO_PIN_2
	 
#define MOTOR_A_CON2_GPIO GPIOB
#define MOTOR_A_CON2_PIN GPIO_PIN_9


	 
#define MOTOR_B_CON1_GPIO GPIOA
#define MOTOR_B_CON1_PIN GPIO_PIN_1
	 
#define MOTOR_B_CON2_GPIO GPIOC
#define MOTOR_B_CON2_PIN GPIO_PIN_9
	 
#define MOTOR_B_EN_GPIO GPIOA
#define MOTOR_B_EN_PIN GPIO_PIN_3
/* USER CODE END Includes */

/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim2;

UART_HandleTypeDef huart1;

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM2_Init(void);
static void MX_USART1_UART_Init(void);

/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
void Change_Pulse(uint16_t left,uint16_t right);
void go_left(void);
void go_right(void);
void Straight(void);
void StraightB(void);
void Stop(void);

/* USER CODE END PFP */

/* USER CODE BEGIN 0 */
uint8_t c[2] = {0};
/* USER CODE END 0 */

int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();

  /* USER CODE BEGIN 2 */
	HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
	HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_4);
	
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
		HAL_UART_Receive_IT(&huart1, c, 2);
  /* USER CODE BEGIN 3 */

  }
  /* USER CODE END 3 */

}

/** System Clock Configuration
*/
void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;

  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);

  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

}

/* TIM2 init function */
void MX_TIM2_Init(void)
{

  TIM_MasterConfigTypeDef sMasterConfig;
  TIM_OC_InitTypeDef sConfigOC;

  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 800;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 999;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  HAL_TIM_PWM_Init(&htim2);

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig);

  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 999;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1);

  HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_4);

}

/* USART1 init function */
void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 9600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  HAL_UART_Init(&huart1);

}

/** Configure pins as 
        * Analog 
        * Input 
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct;

  /* GPIO Ports Clock Enable */
  __GPIOA_CLK_ENABLE();
  __GPIOC_CLK_ENABLE();
  __GPIOB_CLK_ENABLE();

  /*Configure GPIO pins : PA1 PA2 */
  GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  /*Configure GPIO pin : PC9 */
  GPIO_InitStruct.Pin = GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  /*Configure GPIO pins : PB6 PB7 PB8 PB9 */
  GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart ==&huart1)
	{
		
		
		if(c[0] == 'q')
		{
			Straight();
			
		}
		else if(c[0] == 'h')
		{
			StraightB();
			
		}
		else if(c[0] == 'l')
		{
			go_left();
		
		}
		else if(c[0] == 'r')
		{
			go_right();
		
		}
		else if(c[0] == 's')
		{
			Stop();
		
		}
			
	}
}
void Change_Pulse(uint16_t left,uint16_t right)
{
	__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_1, left);
  __HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4, right);
	
}
//-----------------------------------------------
void go_left(void)//向左矫正
 {
	Change_Pulse(0,200);
  HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);
	HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET);
 }
//------------------------------------------------
 void go_right(void)//向右矫正
 {
	Change_Pulse(200,0);
  HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);
	HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET);
 }
//-----------------------------------------------------
void Straight(void)	//直行
{
	Change_Pulse(200,200);
	HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_SET);
	HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_SET); 
}
void StraightB(void)	//直行往后
{
	Change_Pulse(200,200);
	HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_SET);
	HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_SET);
	HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_RESET); 
}
void Stop(void)	//停止
{
	Change_Pulse(0,0);
	HAL_GPIO_WritePin(MOTOR_A_CON1_GPIO, MOTOR_A_CON1_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_A_CON2_GPIO, MOTOR_A_CON2_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_B_CON1_GPIO, MOTOR_B_CON1_PIN, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(MOTOR_B_CON2_GPIO, MOTOR_B_CON2_PIN, GPIO_PIN_RESET);
}

/* USER CODE END 4 */

#ifdef USE_FULL_ASSERT

/**
   * @brief Reports the name of the source file and the source line number
   * where the assert_param error has occurred.
   * @param file: pointer to the source file name
   * @param line: assert_param error line source number
   * @retval None
   */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */

}

#endif

/**
  * @}
  */ 

/**
  * @}
*/ 

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

6、ui模块(接受图片信息和发送指令)

使用qt完成(c++)

last1.pro

#-------------------------------------------------
#
# Project created by QtCreator 2021-07-27T16:30:56
#
#-------------------------------------------------

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = last1
TEMPLATE = app


SOURCES += main.cpp\
        widget.cpp

HEADERS  += widget.h

FORMS    += widget.ui

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QTcpSocket>
#include <QDebug>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->lineEdit_ipaddr->setText("192.168.1.1");
    ui->lineEdit_port->setText("8888");
    ui->lineEdit_port1->setText("7777");
    this->mysck = new QTcpSocket();
    this->myser1 = new QTcpSocket();
    this->flags = 0;
    this->myser1->connectToHost(ui->lineEdit_ipaddr->text(),7777);
    this->setWindowTitle("视频客户端");

    connect(this->mysck, SIGNAL(connected()), this, SLOT(myconnect_success()));
    connect(this->mysck, SIGNAL(readyRead()), this, SLOT(recv_pic_show()));
}

Widget::~Widget()
{
    delete ui;
}

void Widget::on_pushButton_connect_clicked()
{
    this->mysck->connectToHost(ui->lineEdit_ipaddr->text(), ui->lineEdit_port->text().toShort());
}
void Widget::myconnect_success()
{
     ui->label_pic->setText("连接服务器成功");
}

void Widget::on_pushButton_recv_pic_clicked()
{
    ui->label_pic->clear();
    QString cmd = "get 1.jpg\n";
    this->mysck->write(cmd.toLatin1());
}
void Widget::recv_pic_show()
{
    if(this->flags == 0)
    {
        char flen[20] = {0};
        this->mysck->read(flen,20);
        qDebug() << flen;
        this->flags = 1;
        fl = atoi(flen+4);
    }
    else if(this->flags == 1)
    {
        qDebug() << fl;
        char *mypb = NULL;
        mypb = (char *)malloc(fl);
        memset(mypb,0,fl);
        if(this->mysck->bytesAvailable() >= fl)
        {
            this->mysck->read(mypb, fl);
            this->pic = new QPixmap();
            this->pic->loadFromData((unsigned char *)mypb,fl,"jpeg");
            ui->label_pic->setPixmap(*pic);
            this->flags = 0;
        }
    }
}


void Widget::on_pushButton_w_clicked()
{
    this->myser1->write("qq");
}

void Widget::on_pushButton_b_clicked()
{
    this->myser1->write("hh");
}

void Widget::on_pushButton_l_clicked()
{
    this->myser1->write("ll");
}

void Widget::on_pushButton_r_clicked()
{
    this->myser1->write("rr");
}

void Widget::on_pushButton_s_clicked()
{
    this->myser1->write("ss");
}

void Widget::on_pushButton_test_pressed()
{
     this->myser1->write("qq");
}

void Widget::on_pushButton_test_released()
{
    this->myser1->write("ss");
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPixmap>
#include <QTcpSocket>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
public:
    QTcpSocket *mysck,*myser1;
    QPixmap *pic;
    int flags;
    int fl;


private slots:
    void on_pushButton_connect_clicked();
    void myconnect_success();
    void on_pushButton_recv_pic_clicked();
    void recv_pic_show();

    void on_pushButton_w_clicked();

    void on_pushButton_b_clicked();

    void on_pushButton_l_clicked();

    void on_pushButton_r_clicked();

    void on_pushButton_s_clicked();

    void on_pushButton_test_pressed();

    void on_pushButton_test_released();

private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>368</width>
    <height>534</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <widget class="QLabel" name="label_pic">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>70</y>
     <width>320</width>
     <height>240</height>
    </rect>
   </property>
   <property name="minimumSize">
    <size>
     <width>320</width>
     <height>240</height>
    </size>
   </property>
   <property name="text">
    <string>TextLabel</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton_w">
   <property name="geometry">
    <rect>
     <x>140</x>
     <y>370</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>前</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton_l">
   <property name="geometry">
    <rect>
     <x>12</x>
     <y>417</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>左</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton_r">
   <property name="geometry">
    <rect>
     <x>250</x>
     <y>420</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>右</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton_b">
   <property name="geometry">
    <rect>
     <x>140</x>
     <y>470</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>后</string>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton_s">
   <property name="geometry">
    <rect>
     <x>140</x>
     <y>420</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>停</string>
   </property>
  </widget>
  <widget class="QWidget" name="layoutWidget">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>10</y>
     <width>331</width>
     <height>23</height>
    </rect>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout">
    <item>
     <widget class="QLabel" name="label_1">
      <property name="text">
       <string>IP地址:</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QLineEdit" name="lineEdit_ipaddr"/>
    </item>
   </layout>
  </widget>
  <widget class="QWidget" name="layoutWidget">
   <property name="geometry">
    <rect>
     <x>20</x>
     <y>40</y>
     <width>331</width>
     <height>23</height>
    </rect>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout_2">
    <item>
     <widget class="QLabel" name="label_2">
      <property name="text">
       <string>端口号:</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QLineEdit" name="lineEdit_port"/>
    </item>
   </layout>
  </widget>
  <widget class="QWidget" name="layoutWidget">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>330</y>
     <width>351</width>
     <height>30</height>
    </rect>
   </property>
   <layout class="QHBoxLayout" name="horizontalLayout_3">
    <item>
     <widget class="QPushButton" name="pushButton_connect">
      <property name="text">
       <string>连接成功</string>
      </property>
     </widget>
    </item>
    <item>
     <widget class="QPushButton" name="pushButton_recv_pic">
      <property name="text">
       <string>接受视频</string>
      </property>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QLineEdit" name="lineEdit_port1">
   <property name="geometry">
    <rect>
     <x>10</x>
     <y>370</y>
     <width>113</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QPushButton" name="pushButton_test">
   <property name="geometry">
    <rect>
     <x>250</x>
     <y>370</y>
     <width>93</width>
     <height>28</height>
    </rect>
   </property>
   <property name="text">
    <string>测试</string>
   </property>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值