STM32MP157实现串口接收数据上云-MP157连接4G模块和电脑

文章目录

  • 前言
  • 一.打开设备文件
  • 二.串口初始化
  • 三.多线程
  • 四.程序的移植和执行
  • 五.源码(转载请注明出处)
  • 结语


前言

本篇分享:

这次将会用几篇博客分享STM32MP157实现串口接收数据上云的一个基础功能,实现STM32MP157的串口在接收到数据时能上传至服务器,让用户可以随时随地查看一个设备的实时信息。

在上一篇博客中我们已经使用minicom测试过STM32MP157的串口功能,本篇将分享如何使用电脑串口调试助手向MP157发送数据,进而实现数据上云


使用代码实现步骤:

本代码中串口通信主要分为四个步骤

1.打开串口设备文件,获取设备句柄fd
2.配置串口的参数
3.利用select函数检测串口设备可进行读写
4.应用read、write函数实现串口读写操作

一.打开设备文件

在Linux中,设备文件一般都位于/dev下,其中连接4G模块的为STM32MP157上的串口7,设备文件为/dev/ttySTM3

首先,打开串口,得到串口设备的文件描述符,代码如下所示,这里将open函数返回的文件描述符用serportfd_PC保存

这里代码中没有直接将设备文件地址写入,而是选择在执行程序时自行传入参数,写死直接将argc[1]改为“/dev/ttySTM3”即可

open函数这里用到了三个标志,其中
O_RDWR作用为使以可读可写方式打开;
O_NOCTTY为使打开的文件不会成为该进程的控制终端。如果没有指定这个标志,那么任何一个输入都将会影响用户的进程;
O_NDELAY作用为在读取不到数据或是写入缓冲区已满会马上返回,而不会阻塞等待。

serportfd_PC = open(argv[1],O_RDWR|O_NOCTTY|O_NDELAY);
if(serportfd_PC < 0){
	printf("%s open faild\r\n",argv[1]);
	return -1;
}

二.串口初始化

使用STM32MP157上的串口,还需要对串口进行初始化。

在STM32库函数中对串口初始化时有USART_InitStruct串口初始化结构体,在Linux下串口驱动头文件termios.h中也有类似的结构体termios_t

在结构体中主要对c_cflag进行配置,其中主要有波特率和数据帧格式包括数据位个数、停止位,校验位等,配置的方式多为或和与操作,具体代码如下所示:

/*头文件*/
#include 

/*串口配置*/
bzero(ter_s,sizeof(*ter_s));//清空ter_s字符串
ter_s->c_cflag |= CLOCAL | CREAD; //激活本地连接与接受使能 
ter_s->c_cflag &= ~CSIZE;//失能数据位屏蔽
/*数据帧格式设置*/
ter_s->c_cflag |= CS8;//8位数据位 
ter_s->c_cflag &= ~CSTOPB;//1位停止位 
ter_s->c_cflag &= ~PARENB;//无校验位 
/*VTIME和VMIN都取0,即使串口读不到任何数据,函数read也会立即返回*/
ter_s->c_cc[VTIME] = 0;//设置等待时间
ter_s->c_cc[VMIN] = 0;//设置最小接收字符长度
/*波特率设置*/
cfsetispeed(ter_s,B115200);//设置输入波特率
cfsetospeed(ter_s,B115200);//设置输出波特率
/*清除串口数据*/
tcflush(serportfd_PC,TCIOFLUSH) ;//清除串口所有缓存数据
/*使串口配置生效*/
if(tcsetattr(serportfd_PC,TCSANOW,ter_s) != 0){
    printf("com set error!\r\n");
    return -1;
}
/*提示串口配置完成信息*/
printf("serial-PC is ready!\n");
return 0;

三.多线程

代码main函数的主循环作用是在接收到外部传输的数据使能将其通过4G模块上传至云端,代码如下:

while (1)//主线程-接收电脑串口传输数据
{
     FD_ZERO(&rd);//清空rd
     FD_SET(serportfd_PC,&rd);//将serportfd_PC添加进rd中
     if(select(serportfd_PC+1,&rd,NULL,NULL,NULL)<0)//检测设备是否可读
         perror("select");
     if(FD_ISSET(serportfd_PC,&rd))//如果设备可读
     {
         while(read(serportfd_PC,rece_data,64)>0)
         {
             printf("Successfully received data!\n");
             sprintf(send_data,"AT+MPUB=\"/sys/a1cdS8zCRA0/863488054279453/thing/event/property/post\",1,0,\"{\\22id\\22:1661139282955,\\22params\\22:{\\22CurrentVoltage\\22:%s},\\22version\\22:\\221.0\\22,\\22method\\22:\\22thing.event.property.post\\22}\"\r",rece_data);
             write(serportfd_4G,send_data,strlen(send_data));//向4G模块发送AT指令
         }
     }
 }

为了能让STM32MP157向4G模块发送AT指令时能看见其中通讯的过程,在向4G模块发送指令的同时里还需要一个循环来不断输出4G模块返回的数据。

这里增加一个线程以实现该功能。

/*头文件*/
#include 

/*创建线程*/
pthread_t id;
pthread_create(&id,NULL,serial_lsd,&serportfd_4G);//创建线程

/*接受串口7返回数据线程代码*/
void *serial_lsd(void *d)//接受串口7返回数据线程
{
    int tfd=*(int *)d;
    char rec_data[256];
    fd_set rd;
    
    while (1)
    {
        FD_ZERO(&rd);//清空rd
        FD_SET(tfd,&rd);//将tfd添加进rd中
        if(select(tfd+1,&rd,NULL,NULL,NULL)<0)//检查设备是否可读
            perror("select");
        if(FD_ISSET(tfd,&rd))//如果可读则读取并打印数据
        {
            while(read(tfd,rec_data,1)>0)
            {
                printf("%s",rec_data);
            }
        }
    }
}

四.程序的移植和执行

将代码写好后使用交叉编译工具对.c文件进行编译(要链接pthread库),得到STM3232MP157能执行的ARM类型的可执行文件

在这里插入图片描述
再利用WinSCP这样的工具将可执行文件发送至开发板,步骤为:
a.开发板连接上网络后ifconfig查看当前ip地址
b.在Ubuntu输入scp 文件名 用户名@开发板ip:保存文件路径即可
如:scp uart [email protected]:/home/root

STM32MP157实现串口接收数据上云-MP157连接4G模块和电脑_第1张图片
接着,在终端输入chmod 777 uart更改文件的权限。

最后传参执行即可,第一个参数是和电脑连接的串口设备文件,第二个是和4G模块连接的串口设备文件

STM32MP157实现串口接收数据上云-MP157连接4G模块和电脑_第2张图片
使用任意的串口调试助手向STM32MP157发送数据。
进而通过4G模块传输至云平台。

STM32MP157实现串口接收数据上云-MP157连接4G模块和电脑_第3张图片
登录云平台,发现设备在线并已成功接收数据。

STM32MP157实现串口接收数据上云-MP157连接4G模块和电脑_第4张图片
至此,使用电脑串口调试助手向MP157发送数据,进而实现数据上云已实现。

五.源码(转载请注明出处)

STM32MP157实现串口接收数据上云-MP157连接4G模块和电脑_第5张图片


结语

以上就是全部内容,如有错误请批评指正。

你可能感兴趣的:(STM32MP157,stm32,单片机,arm,嵌入式硬件,物联网)