本篇分享:
这次将会用几篇博客分享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
接着,在终端输入chmod 777 uart更改文件的权限。
最后传参执行即可,第一个参数是和电脑连接的串口设备文件,第二个是和4G模块连接的串口设备文件。
使用任意的串口调试助手向STM32MP157发送数据。
进而通过4G模块传输至云平台。
至此,使用电脑串口调试助手向MP157发送数据,进而实现数据上云已实现。
以上就是全部内容,如有错误请批评指正。