STM32通过广和通ADP-L610-Arduino进行TCP/IP通信
Posted Weasker威斯克
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32通过广和通ADP-L610-Arduino进行TCP/IP通信相关的知识,希望对你有一定的参考价值。
STM32通过广和通L610进行TCP/IP通信
一、 写在前面
本次参加嵌入式大赛,使用了广和通的ADP-L610-Arduino板子进行通信。项目要求大概是本地上传数据到服务器,服务器接收后发送给客户端,实现数据的传输。在这个项目中需要用到两个客户端,所以需要实现服务端的多线程操作。多线程我具体还没整明白,这篇文章介绍的还是单线程。TCP/IP通信协议的可靠性、可操作性、安全性等几个特征,正好是我这次项目所需要的。前前后后整了两天,写下这篇博客,分享下经验的同时也为自己写下备忘录。
二、材料准备
- STM32开发板
- ADP-L610-Arduino板子
- 公网IP
【注意】:实际上不限于STM32开发板,只要能进行串口通信的板子就行。运营商通常不会提供静态公网IP,所以需要我们购买一个服务器,下面会提供阿里云ECS云服务器的简单使用方法。
三、CS架构TCP/IP通信
Socket在应用层和传输层之间的一个抽象层,它把 TCP/IP 层复杂的操作抽象为几个简单的接口,供应用层调用实现进程在网络中的通信。Socket 起源于 UNIX,在 UNIX 一切皆文件的思想下,进程间通信就被冠名为文件描述符。Socket 保证了不同计算机之间的通信,也就是网络通信。对于网站,通信模型是服务器与客户端之间的通信。两端都建立了一个 Socket 对象,然后通过 Socket 对象对数据进行传输。通常服务器处于一个无限循环,等待客户端的连接。
本示例代码的头文件是linux平台的,可以让服务端循环等待客户端连接,但目前仅支持单线程连接,多线程连接等我用上了会更新。
1.服务端server.c
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<sys/wait.h>
#define PORT 8088 /*端口号*/
#define BACKLOG 1 /*最大监听数*/
int main(){
int sockfd,new_fd; /*socket句柄和建立连接后的句柄*/
struct sockaddr_in my_addr; /*本方地址信息结构体,下面有具体的属性赋值*/
struct sockaddr_in their_addr; /*对方地址信息*/
int sin_size;
int client;
sockfd=socket(AF_INET,SOCK_STREAM,0); //建立socket
if(sockfd==-1){
printf("socket failed:%d",errno);
return -1;
}
my_addr.sin_family=AF_INET; /*该属性表示接收本机或其他机器传输*/
my_addr.sin_port=htons(PORT); /*端口号*/
my_addr.sin_addr.s_addr=htonl(INADDR_ANY); /*IP,括号内容表示本机IP*/
bzero(&(my_addr.sin_zero),8); /*将其他属性置0*/
if(bind(sockfd,(struct sockaddr*)&my_addr,sizeof(struct sockaddr))<0){
//绑定地址结构体和socket
printf("bind error");
return -1;
}
listen(sockfd,BACKLOG); //开启监听 ,第二个参数是最大监听数
char recvbuf[100];
char sendbuf[]="[\\tServer]:server is recieved!";
while(1){
printf("[\\tServer]:waitting for connecting\\n");
client = accept(sockfd,(struct sockaddr*)&their_addr,&sin_size);
if(client < 0){
printf("[\\tClient]:connect fail!\\n");
continue;
}
else{
printf("[\\tServer]:**********************************\\n");
printf("[\\tServer]:connect success!port:%d\\n",PORT);
}
printf("[\\tServer]:waitting for messege....\\n");
while(1){
int DataNum = recv(client,recvbuf,100,0);
recvbuf[DataNum]='\\0';
if(strcmp(recvbuf,"exit") == 0) break;
if(strcmp(recvbuf,"systemexit") == 0) return 0;
printf("[\\tRecv]:%s\\n",recvbuf);
send(client,sendbuf,strlen(sendbuf),0);
}
printf("[\\tClient]:client exit\\n\\n\\n");
}
close(sockfd);
return 0;
}
2.客户端
通过ADP-L610-Arduino的TCP服务来连接。
四、服务器环境搭建
1.进入阿里云官网,点击产品->热门产品->云服务器ECS,随便买一个服务器。
2.进入控制台里的安全组
3.点击创建规则,自定义端口的值需要与服务端server.c中的端口号宏定义相同。
4.通过FileZilla将服务器程序server.c发送到服务器上,并在服务器上运行该程序。
四、开发板配置
1.将MCU和ADP-L610-Arduino的串口收发连接上。给两个开发版供电。
2.使用STM32CubeMX配置连接好的针脚。本示例中,USART1是与L610连接的串口,USART3是stlink的串口。二者的配置参数相同。
3.导出工程文件后,通过keil进行编辑。
3.1进入usart.c中,添加以下代码。
#include <stdio.h>
int fputc(int ch,FILE *f) /*重映射printf为串口1(MCU与L610之间)发送*/
{
uint8_t temp=ch;
HAL_UART_Transmit(&huart1,&temp,1,2);
return temp;
}
3.2在main.c中添加以下代码。
void Creat_TCP(void) /*创建tcp连接*/
{
HAL_Delay(3000);
/*通过串口1向L610发送该指令进行TCP连接*/
printf("AT+MIPOPEN=1,,\\"139.196.82.153\\",8088,0\\r\\n");
HAL_Delay(3000);
}
void Send_Data(char *bufferdata) /*发送数据*/
{
HAL_Delay(2000);
printf("AT+MIPSEND=1,13\\r\\n"); /*通知L610即将发送定长数据,长度为13*/
printf( "%s",bufferdata); /*数据内容*/
HAL_Delay(2000);
}
int i;
Creat_TCP();
for(i=0;i<5;i++){
Send_Data(senddata);
HAL_Delay(1000);
}
4.将程序烧写进MCU并运行即可完成功能。
五、注意事项
我是根据官方说明文档整理出来的,把一些对开发板启动后的初始化、检测都去除了,可以说非常精简,但是简单的同时也可能会出现错误。这个代码没有打印log信息的功能,因此运行程序时如果出错就挺麻烦。建议用到TCP的朋友还是好好写一个打印log的功能吧,可以用USART3做。
这个示例只是大致讲了下L610连接TCP服务器的步骤,我也是废了一定的功夫才整好的,如果有帮到你的话,请点个赞哟。
以上是关于STM32通过广和通ADP-L610-Arduino进行TCP/IP通信的主要内容,如果未能解决你的问题,请参考以下文章
STM32通过广和通ADP-L610-Arduino进行TCP/IP通信
STM32通过广和通ADP-L610-Arduino进行TCP/IP通信