| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 网络协议 -> 遥控小车(基于TCP/IP) -> 正文阅读 |
|
[网络协议]遥控小车(基于TCP/IP) |
? ? ? ? 其实我更想用32的板子来完成这个项目,但是老师要求只能用GEC6818的板子,虽然这个板子功能更加全面,但本人还是对32熟悉一些,所以前期还是花了很多时间来研究这块板子,总的来说其实步骤还是差不多的。实现代码在文章最底下。 1、总体设计任务框图 ? 2、设计任务: 本设计是基于粤嵌gec6818开发板完成远端操控小车的操作,小车需要纯手工组装。 要求: 完成各模块功能的构建,使用QT的界面设计和安卓配置作为客户端给服务器端发送数据,在服务器端接收数据并创建子线程处理数据。通过看6818底板电路图发现可使用GPIO_C7、C8、C17和GPIO_E13输出电平给电机供电,并且可通过调节占空比来控制小车速度。 3、功能要求及技术指标
4、 总体设计方案 ????????运用QT实现基本的TCP客户端和服务器端的基本通信,客户端实现与服务器端建立连接、发送数据与断开,服务器端接收客户端数据并创建子线程来处理接收到的数据。再通过UI和安卓界面设计来实现按钮控制小车,再通过给四个GPIO口输出高低电平来控制电机转动和速度,最后实现控制小车。 5 系统测试 客户端:QT版与安卓版 (ps:奥迪rs7是不是你的终极梦想,哈哈哈) ? ? 服务器端:基于粤嵌6818的智能小车 6 使用说明 ????????当你在输入框内输入正确的IP地址以及端口号,点击链接即可成功并在显示窗口显示连接成功,然后就可以通过点击前进,后退,左转,右转,停止来实现控制小车运动,点击断开及失去控制权。 7.附录代码 服务器端: int port = 6666; // GPIOC7的编号为: PAD_GPIO_C + 7 enum { ????PAD_GPIO_A ?????= (0 * 32), ????PAD_GPIO_B ?????= (1 * 32), ????PAD_GPIO_C ?????= (2 * 32), ????PAD_GPIO_D ?????= (3 * 32), ????PAD_GPIO_E ?????= (4 * 32), ????PAD_GPIO_ALV ???= (5 * 32), }; //GPIO模式 #define GPIO_MODE_INPUT ?1 #define GPIO_MODE_OUTPUT ?0 #define THREAD_NUMBER ??????1 ? typedef struct gpio_cfg_t { unsigned int gpio_no; //gpio的编号 unsigned int gpio_mode; // input/output unsigned int init_value; // 当gpio配置成output模式时 ?//指定输出的初始值。 }gpio_cfg_t; typedef struct gpio_value { unsigned int gpio_no; //gpio的编号 unsigned int gpio_value; } gpio_value_t; #define GPIO_CONFIG ?_IOW('G', 1, gpio_cfg_t) #define GPIO_SET_VALUE _IOW('G', 2, gpio_value_t) #define GPIO_GET_VALUE _IOWR('G', 3, gpio_value_t) gpio_cfg_t gpio_init; gpio_value_t gpio_clear; void GPIO_Init(int fd) { gpio_init.gpio_no = PAD_GPIO_C + 7; gpio_init.gpio_mode = GPIO_MODE_OUTPUT; //输出模式 gpio_init.init_value = 0; //初始输出 低电平 ioctl(fd, GPIO_CONFIG, &gpio_init); gpio_init.gpio_no = ?PAD_GPIO_C + 8; ????????gpio_init.gpio_mode = GPIO_MODE_OUTPUT; //输出模式 ????????gpio_init.init_value = 0; //初始输出 低电平 ????????ioctl(fd, GPIO_CONFIG, &gpio_init); ????????gpio_init.gpio_no = ?PAD_GPIO_C + 17; ????????gpio_init.gpio_mode = GPIO_MODE_OUTPUT; //输出模式 ????????gpio_init.init_value = 0; //初始输出 低电平 ????????ioctl(fd, GPIO_CONFIG, &gpio_init); ????????gpio_init.gpio_no = ?PAD_GPIO_E + 13 ; ????????gpio_init.gpio_mode = GPIO_MODE_OUTPUT; //输出模式 ????????gpio_init.init_value = 0; //初始输出 低电平 ????????ioctl(fd, GPIO_CONFIG, &gpio_init); } void clear(int fd) { gpio_clear.gpio_no = PAD_GPIO_C + 7; gpio_clear.gpio_value = 0; ioctl(fd, GPIO_SET_VALUE, &gpio_clear); ????????gpio_clear.gpio_no = PAD_GPIO_C + 8; ????????gpio_clear.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_clear); ????????gpio_clear.gpio_no = PAD_GPIO_C + 17; ????????gpio_clear.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_clear); ????????gpio_clear.gpio_no = ?PAD_GPIO_E + 13; ????????gpio_clear.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_clear); } void forward(int fd) { gpio_value_t gpio_value_1; gpio_value_1.gpio_no = PAD_GPIO_C + 7; gpio_value_1.gpio_value = 1; ioctl(fd, GPIO_SET_VALUE, &gpio_value_1); ????????gpio_value_t gpio_value_2; ????????gpio_value_2.gpio_no = PAD_GPIO_E + 13; ????????gpio_value_2.gpio_value = 1; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_2); ?gpio_value_t gpio_value_C8; ????????gpio_value_C8.gpio_no = PAD_GPIO_C + 8; ????????gpio_value_C8.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C8); ????????gpio_value_t gpio_value_C17; ????????gpio_value_C17.gpio_no = PAD_GPIO_C + 17; ????????gpio_value_C17.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C17); } void back(int fd) { gpio_value_t gpio_value_3; ????????gpio_value_3.gpio_no = PAD_GPIO_C + 8; ????????gpio_value_3.gpio_value = 1; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_3); ????????gpio_value_t gpio_value_4; ????????gpio_value_4.gpio_no = PAD_GPIO_C + 17; ????????gpio_value_4.gpio_value = 1; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_4); ????????gpio_value_t gpio_value_C7; ????????gpio_value_C7.gpio_no = PAD_GPIO_C + 7; ????????gpio_value_C7.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C7); ????????gpio_value_t gpio_value_E13; ????????gpio_value_E13.gpio_no = PAD_GPIO_E + 13; ????????gpio_value_E13.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_E13); } void turn_left(int fd) { gpio_value_t gpio_value_5; gpio_value_5.gpio_no = PAD_GPIO_C + 7; gpio_value_5.gpio_value = 1; ioctl(fd, GPIO_SET_VALUE, &gpio_value_5); ????????gpio_value_t gpio_value_6; ????????gpio_value_6.gpio_no = PAD_GPIO_C + 8; ????????gpio_value_6.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_6); ????????gpio_value_t gpio_value_C17; ????????gpio_value_C17.gpio_no = PAD_GPIO_C + 17; ????????gpio_value_C17.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C17); ????????gpio_value_t gpio_value_E13; ????????gpio_value_E13.gpio_no = PAD_GPIO_E + 13; ????????gpio_value_E13.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_E13); // sleep(1); // forward(fd); } void turn_right(int fd) { gpio_value_t gpio_value_7; gpio_value_7.gpio_no = PAD_GPIO_C + 17; gpio_value_7.gpio_value = 1; ioctl(fd, GPIO_SET_VALUE, &gpio_value_7); ????????gpio_value_t gpio_value_8; ????????gpio_value_8.gpio_no = PAD_GPIO_E + 13; ????????gpio_value_8.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_8); ????????gpio_value_t gpio_value_C7; ????????gpio_value_C7.gpio_no = PAD_GPIO_C + 7; ????????gpio_value_C7.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C7); ????????gpio_value_t gpio_value_C8; ????????gpio_value_C8.gpio_no = PAD_GPIO_C + 8; ????????gpio_value_C8.gpio_value = 0; ????????ioctl(fd, GPIO_SET_VALUE, &gpio_value_C8); // sleep(1); // forward(fd); } /*处理接收客户端消息函数*/ int ret; void *recv_message(void *fd) { int sockfd = *(int *)fd; int i,j,k,n; ????????printf("received from client:%d\n", ret); while(1) { ?? switch(ret) { case 0:clear(sockfd);break; case 1: ????????for(i = 0;i < 10;i++) ?????? ??{ ???????????????? if(i == 0 | i == 4 | i == 7) ??????????????? ?{ ???????????????????????? forward(sockfd); ???????????????? } ??????????????? ?else ??????????????? ?{ ???????????????????????? clear(sockfd); ??????????????? ?} ??????? ?} // forward(sockfd); break; case 2: ????????????????for(j = 0;j < 10;j++) ??????????????????{ ????????????????????????if(j == 0 | j == 4 | j == 7) ?????????????????????????{ ????????????????????????????????back(sockfd); ????????????????????????} ?????????????????????????else ?????????????????????????{ ????????????????????????????????clear(sockfd); ?????????????????????????} ?????????????????} // back(sockfd); break; case 3: ????????????????for(k = 0;k < 10;k++) ??????????????????{ ????????????????????????if(k == 0 |k == 4 |k ==7) ?????????????????????????{ ????????????????????????????????turn_left(sockfd); ????????????????????????} ?????????????????????????else ?????????????????????????{ ????????????????????????????????clear(sockfd); ?????????????????????????} ?????????????????} // turn_left(sockfd); break; case 4: ????????????????for(n = 0;n < 10;n++) ??????????????????{ ????????????????????????if(n == 0 | n == 4 | n == 7) ?????????????????????????{ ????????????????????????????????turn_right(sockfd); ????????????????????????} ?????????????????????????else ?????????????????????????{ ????????????????????????????????clear(sockfd); ?????????????????????????} ?????????????????} // turn_right(sockfd); break; default:printf("recivice error");break; } }//while } int main() { ?????int fd = open("/dev/gec6818_gpios", O_RDWR); ?????if (fd == -1) ?????{ ?????????????perror("failed to open:"); ?????????????return -1; ?????} //声明套接字 int listenfd , connfd; socklen_t clilen; //声明线程ID pthread_t recv_tid , send_tid; //定义地址结构 struct sockaddr_in servaddr , cliaddr; GPIO_Init(fd); /*(1) 创建套接字*/ if((listenfd = socket(AF_INET , SOCK_STREAM , 0)) == -1) { perror("socket error.\n"); exit(1); }//if /*(2) 初始化地址结构*/ bzero(&servaddr , sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(port); /*(3) 绑定套接字和端口*/ if(bind(listenfd , (struct sockaddr *)&servaddr , sizeof(servaddr)) < 0) { perror("bind error.\n"); exit(1); }//if /*(4) 监听*/ if(listen(listenfd , LISTENQ) < 0) { perror("listen error.\n"); exit(1); }//if /*(5) 接受客户请求,并创建线程处理*/ clilen = sizeof(cliaddr); if((connfd = accept(listenfd , (struct sockaddr *)&cliaddr , &clilen)) < 0) { perror("accept error.\n"); exit(1); }//if printf("server: got connection from %s\n", inet_ntoa(cliaddr.sin_addr)); ????????/*创建子线程处理该客户链接接收消息*/ ????????if( pthread_create(&recv_tid , NULL , recv_message, &fd) == -1) ????????{ ????????????????perror("pthread create error.\n"); ????????????????exit(1); ????????} while(1) { ?char buf[MAX_LINE]; memset(buf , 0 , MAX_LINE); int n; if((n = recv(connfd , buf , MAX_LINE , 0)) == -1) { perror("recv error.\n"); exit(1); } sscanf(buf,"%d",&ret); } } 客户端: 安卓: ui->ctnForward->setFixedSize(200,200); ????????ui->ctnBack->setFixedSize(200,200); ????????ui->ctnLeft->setFixedSize(200,200); ????????ui->ctnRight->setFixedSize(200,200); ????????ui->textshow->setFixedSize(800,500); ????????ui->ctnStop->setFixedSize(200,200); ????????ui->ctnStop->move(400,1000); ????????ui->ctnForward->move(400,770); ????????ui->ctnBack->move(400,1230); ????????ui->ctnLeft->move(100,1000); ????????ui->ctnRight->move(700,1000); ????????ui->textshow->move(150,100); ????????ui->lineEditip->setFixedSize(600,100); ????????ui->lineEditport->setFixedSize(600,100); ????????ui->lineEditip->move(360,1500); ????????ui->lineEditport->move(360,1650); ????????ui->labelip->setFixedSize(150,100); ????????ui->labelport->setFixedSize(150,100); ????????ui->labelip->move(150,1500); ????????ui->labelport->move(150,1650); ????????ui->ctnConnect->setFixedSize(200,100); ????????ui->ctnDisconnect->setFixedSize(200,100); ????????ui->ctnConnect->move(200,1900); ????????ui->ctnDisconnect->move(600,1900); ????//连接小车 void?TCPcar2::on_ctnConnect_clicked() { ????//获取IP和端口号 ????QString?ip=ui->lineEditip->text(); ????qint16?port?=?ui->lineEditport->text().toInt();//字符串转换成整形 ????//主动与服务器建立连接 ????tcpSocket->connectToHost(QHostAddress(ip),port); } ????//断开连接 void?TCPcar2::on_ctnDisconnect_clicked() { ????//断开连接 ????????tcpSocket->disconnectFromHost(); ????????tcpSocket->close(); } ????//前进 void?TCPcar2::on_ctnForward_pressed() { ????QString?str1="1"; ???????tcpSocket->write(str1.toUtf8().data());//给小车发送数据????Utf8将qstring转qbytearray??.data()转char ?????????ui->textshow->setText("向前冲冲冲"); ?????????//qDebug()<<"1"; } void?TCPcar2::on_ctnForward_released() { //????QString?str0="0"; //????????tcpSocket->write(str0.toUtf8().data()); //?????????qDebug()<<"0"; } ????//后退 void?TCPcar2::on_ctnBack_pressed() { ????QString?str2="2"; ???????tcpSocket->write(str2.toUtf8().data()); ?????????ui->textshow->setText("倒车请注意哟"); ?????????//qDebug()<<"2"; } void?TCPcar2::on_ctnBack_released() { //????QString?str0="0"; //????tcpSocket->write(str0.toUtf8().data()); //?????qDebug()<<"0"; } ????//左转 void?TCPcar2::on_ctnLeft_pressed() { ????QString?str3="3"; ????????tcpSocket->write(str3.toUtf8().data());//给小车发送数据 ???????????ui->textshow->setText("左转啦"); ???????????//qDebug()<<"3"; } void?TCPcar2::on_ctnLeft_released() { //????QString?str0="0"; //????tcpSocket->write(str0.toUtf8().data()); //?????qDebug()<<"0"; } ????//??右转 void?TCPcar2::on_ctnRight_pressed() { ????QString?str4="4"; ???????tcpSocket->write(str4.toUtf8().data()); ?????????ui->textshow->setText("右转啦"); ?????????//qDebug()<<"4"; } void?TCPcar2::on_ctnRight_released() { //????QString?str0="0"; //????tcpSocket->write(str0.toUtf8().data()); //?????qDebug()<<"0"; } //添加绘图事件,QPixmap(":/image/2.png"));里面加的 //是添加资源的路径, ????//添加背景图 //void?TCPcar2::paintEvent(QPaintEvent?*event) //{ //????QPainter?painter(this); //????painter.drawPixmap(0,0,width(),height(),QPixmap("C:/Users/12085/Pictures/Saved?Pictures/rs7.jpg")); //} void?TCPcar2::on_ctnStop_clicked() { ????QString?str0="0"; ????????tcpSocket->write(str0.toUtf8().data()); ?????????//qDebug()<<"0"; ????????ui->textshow->setText("刹车啦!!!!!!"); } 驱动:
#include <linux/init.h> #include <linux/fs.h> #include <linux/miscdevice.h> MODULE_LICENSE("GPL"); #define GPIO_MODE_INPUT ?1? typedef struct gpio_cfg_t ?? ?unsigned int init_value; // 当gpio配置成output模式时
?? ? ?? ??? ??? ?sprintf(gpio_name, "GPIO%c%d", 'A' + gpio_cfg.gpio_no/32,? ?? ??? ??? ?printk(KERN_INFO "gpio num: %s mode:%s\n", gpio_name, ?? ??? ??? ?if (gpio_cfg.gpio_mode == GPIO_MODE_INPUT) ?? ? ?? ??? ??? ?__gpio_set_value( gpio_value.gpio_no, gpio_value.gpio_value); ?? ??? ?case GPIO_GET_VALUE:
?? ??? ??? ?ret = copy_to_user(ptr, (void*)&gpio_value, sizeof(gpio_value)); ?? ??? ?default:
static struct miscdevice gec_misc =? };
module_init(gec6818_gpio_drv_init); #include <linux/module.h> MODULE_INFO(vermagic, VERMAGIC_STRING); struct module __this_module static const char __module_depends[] |
|
网络协议 最新文章 |
使用Easyswoole 搭建简单的Websoket服务 |
常见的数据通信方式有哪些? |
Openssl 1024bit RSA算法---公私钥获取和处 |
HTTPS协议的密钥交换流程 |
《小白WEB安全入门》03. 漏洞篇 |
HttpRunner4.x 安装与使用 |
2021-07-04 |
手写RPC学习笔记 |
K8S高可用版本部署 |
mySQL计算IP地址范围 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2025年1日历 | -2025/1/8 5:55:02- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |