我是靠谱客的博主 怕孤独便当,最近开发中收集的这篇文章主要介绍stm32学习笔记-通过串口3使用wifi模块连接新大陆云平台一、使用USB转TTL模块测试连接云平台。二、stm32配置串口1,串口3,并进行简单测试。三、编写为wifi模块服务的文件。,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
文章目录
- 一、使用USB转TTL模块测试连接云平台。
- 二、stm32配置串口1,串口3,并进行简单测试。
- Tool.h (usart.c配置使用到这里的 **MY_NVIC_Init()** 函数)
- usart.h
- usart.c
- main.c
- 现象结果
- 三、编写为wifi模块服务的文件。
- esp_8622wifi.h
- esp_8622wifi.c
- main.c
- 现象结果
一、使用USB转TTL模块测试连接云平台。
AT指令代码:
连接新大陆云平台
AT //检测wifi模块是否一安装
AT+CWMODE=1 //STA模式
AT+CWJAP="pengchun","p2952870" //连接wifi热点
AT+CIPSTART="TCP","120.77.58.34",8700 //建立TCP连接
AT+CIPSEND=84 //发送数据包长度,自己根据数据包更改长度
{"t":1,"device":"pzlbban","key":"34903414c53e412985abea331ed13c50","ver":"v0.0.0.0"}//握手连接报文
AT+CIPSEND=51
{"t":3,"datatype":1,"datas":{"lock":1},"msgid":123} //传感器数据上传
AT+CIPSEND=7
"$#AT#" //心跳包
窗口助手观察现象
握手连接响应
+IPD,19:{"status":0,"t":2}
上传传感数据响应
+IPD,31:{"msgid":123,"status":0,"t":4}
二、stm32配置串口1,串口3,并进行简单测试。
串口1用来把串口3接收到的数据打印到PC机的串口助手上。
串口3与ATK_ESP8266WIFI模块交互,用来发送AT指令,接收WIFI模块的响应信息。
配置如下:
Tool.h (usart.c配置使用到这里的 MY_NVIC_Init() 函数)
#ifndef TOOL_H
#define TOOL_H
#include "stm32f10x.h"
#define GPIOA_ODR (GPIOA_BASE+0x0C)
#define GPIOA_IDR (GPIOA_BASE+0x08)
#define GPIOB_ODR (GPIOB_BASE+0x0C)
#define GPIOB_IDR (GPIOB_BASE+0x08)
#define GPIOC_ODR (GPIOC_BASE+0x0C)
#define GPIOC_IDR (GPIOC_BASE+0x08)
#define GPIOD_ODR (GPIOD_BASE+0x0C)
#define GPIOD_IDR (GPIOD_BASE+0x08)
#define GPIOE_ODR (GPIOE_BASE+0x0C)
#define GPIOE_IDR (GPIOE_BASE+0x08)
#define BitBand(Addr,bitNum) *((volatile unsigned long *)((Addr&0xf0000000)+0x2000000+((Addr&0xfffff)<<5)+(bitNum<<2)))
#define PAout(n) BitBand(GPIOA_ODR,n)
#define PAin(n) BitBand(GPIOA_IDR,n)
#define PBout(n) BitBand(GPIOB_ODR,n)
#define PBin(n) BitBand(GPIOB_IDR,n)
#define PCout(n) BitBand(GPIOC_ODR,n)
#define PCin(n) BitBand(GPIOC_IDR,n)
#define PDout(n) BitBand(GPIOD_ODR,n)
#define PDin(n) BitBand(GPIOD_IDR,n)
#define PEout(n) BitBand(GPIOE_ODR,n)
#define PEin(n) BitBand(GPIOE_IDR,n)
#define led1 PBout(5)
#define led2 PEout(5)
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_Subpriority,u8 NVIC_Channel,u32 NVIC_Group);
#endif
usart.h
#ifndef USART1_H
#define USART1_H
#include "stm32f10x.h"
#include "stdarg.h"
#include <stdio.h>
#include <string.h>
#include "Tool.h"
#define EN_USART1_RX 0 //串口接收使能。
#define EN_USART3_RX 1 //串口接收使能。
#define USART1_REC_LEN 500
#define USART3_REC_LEN 500
#define USART3_SEND_LEN 500
#ifdef EN_USART1_RX //如果使能了接收中断
extern u16 USART1_RX_STA;//USART1状态标志变量。
extern u8 USART1_RX_BUF[USART1_REC_LEN];
#endif
#ifdef EN_USART3_RX //如果使能了接收中断
extern u16 USART3_RX_STA;
extern u8 USART3_RX_BUF[USART3_REC_LEN];
extern u8 USART3_TX_BUF[USART3_SEND_LEN];
#endif
void usart1_init(u32 baundRate);
void usart3_init(u32 baundRate);
void u3_printf(char* fmt,...);
void USART3_Clear_RxBuf(void);
#endif
usart.c
#include "usart.h"
/*****************************************************************************************
* Function Name : fputc
* Descrption : 重定向这个C库(stdio) printf函数 文件流->串口USART1
* Input : ch ,*f
* Output : None
* Return : None
*****************************************************************************************/
int fputc(int ch,FILE *f)
{
//将ch送给USART1
USART_SendData(USART1,ch);
//等待发送完毕
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
//返回ch
return ch;
}
void usart1_init(u32 baundRate)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef usartst;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
usartst.USART_BaudRate = baundRate;
usartst.USART_WordLength = USART_WordLength_8b;
usartst.USART_StopBits = USART_StopBits_1;
usartst.USART_Parity = USART_Parity_No;
usartst.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
usartst.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
USART_Init(USART1,&usartst);
USART_Cmd(USART1,ENABLE);
#ifdef EN_USART1_RX //如果使能了接收中断
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
MY_NVIC_Init(3, 2, USART1_IRQn, NVIC_PriorityGroup_2); //中断分组2
#endif
}
void usart3_init(u32 baundRate)
{
USART_InitTypeDef usartst;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能USART3,GPIOA时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);//注意usart3再apb1
//USART3_TX GPIOB.10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.10
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIOB.11
USART_DeInit(USART3); //复位串口3
usartst.USART_BaudRate = baundRate;
usartst.USART_WordLength = USART_WordLength_8b;
usartst.USART_StopBits = USART_StopBits_1;
usartst.USART_Parity = USART_Parity_No;
usartst.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
usartst.USART_Mode = USART_Mode_Rx|USART_Mode_Tx;
USART_Init(USART3,&usartst);
USART_Cmd(USART3,ENABLE);
#ifdef EN_USART3_RX //如果使能了接收中断
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启串口接受中断
MY_NVIC_Init(2, 3, USART3_IRQn, NVIC_PriorityGroup_2); //中断分组2
#endif
}
//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
void u3_printf(char* fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART3_TX_BUF,fmt,ap);
va_end(ap);
i=strlen((const char*)USART3_TX_BUF); //此次发送数据的长度
for(j=0;j<i;j++) //循环发送数据
{
while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART3,USART3_TX_BUF[j]);
}
}
u16 USART1_RX_STA = 0;
u8 USART1_RX_BUF[USART1_REC_LEN];
//USART1中断服务程序
void USART1_IRQHandler(void)
{
u8 Res;
//USART1中断服务程序只有一个,得判断是串口的什么中断
//指令判断是否是接收中断
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a 作为结尾,即 按下回车键 结尾)
{
Res =USART_ReceiveData(USART1); //读取接收到的数据
if((USART1_RX_STA&0x8000)==0)//接收未完成
{
if(USART1_RX_STA&0x4000)//接收到了0x0d
{
if(Res!=0x0a)USART1_RX_STA=0;//接收错误,重新开始
else USART1_RX_STA|=0x8000; //接收完成了
}
else //还没收到0X0D
{
if(Res==0x0d)USART1_RX_STA|=0x4000;
else
{
USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ;
USART1_RX_STA++;
if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
u16 USART3_RX_STA = 0;
u8 USART3_RX_BUF[USART3_REC_LEN];
u8 USART3_TX_BUF[USART3_SEND_LEN];
void USART3_Clear_RxBuf(void)
{
memset(USART3_RX_BUF,0x00,USART3_REC_LEN);
}
//USART3中断服务程序
void USART3_IRQHandler(void)
{
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收到数据
{
USART3_RX_BUF[USART3_RX_STA] = USART_ReceiveData(USART3); //读取接收到的数据
USART3_RX_STA++;
if(USART3_RX_STA>USART3_REC_LEN)//缓存区溢出
{USART3_RX_STA = 0x0000;}
}
}
main.c
#include "stm32f10x.h"
#include "bsp_systick.h"
#include "led.h"
#include "exti.h"
#include "Tool.h"
#include "usart.h"
void Stm32_Clock_Init(void)
{
/*----------使用外部RC晶振----------*/
RCC_DeInit() ;
//初始化为缺省值
RCC_HSEConfig(RCC_HSE_ON); //使 能外部的高速时钟
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET); //等 待外部高速时钟使能就绪
//Flash 2 wait state
RCC_HCLKConfig (RCC_SYSCLK_Div1) ;
//HCLK = SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1) ;
//PCLK2 =HCLK
RCC_PCLK1Config(RCC_HCLK_Div2) ;
//PCLK1 = HCLR/2
RCC_PLLConfig (RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); //PLLCLK = 8MHZ * 9 =72MHZ
RCC_PLLCmd(ENABLE) ;
//Enable PLLCLK
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //Wait till PLLCLK is ready
RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK) ;
//Select PLL as system clock
while (RCC_GetSYSCLKSource () !=0x08) ;
//wait till PLL is used as system clock source
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
}
u8 check_AT_Respose(u8 *string)
{
printf("接收到模块响应数据为:n%sn",USART3_RX_BUF);
if(strstr((const char*)USART3_RX_BUF,(const char*)string) != 0)
{
printf("接收到期待的响应 %s",string);
USART3_RX_STA = 0;
memset(USART3_RX_BUF,0x00,USART3_REC_LEN);
return 1;
}
else
{
printf("未接收到期待的响应 %s",string);
USART3_RX_STA = 0;
memset(USART3_RX_BUF,0x00,USART3_REC_LEN);
return 0;
}
}
/*****************************************************************************************
* Function Name : sentATCmd
* Descrption : 使用串口3发送AT指令
* Input : string 发送内容,lenth发送内容的长度
* Output : None
* Return : None
*****************************************************************************************/
u8 sentATCmd(u8 *cmd,u8 times)
{
u8 i;
for(i=0;i<times;i++)
{
u3_printf("%srn",cmd);
printf("已发送指令:%sn",cmd);
SysTick_Delay_ms(1500);
SysTick_Delay_ms(1500);
if(check_AT_Respose("OK"))
return 1;
printf("发送指令响应错误,1.5s后重新发送指令:%sn",cmd);
SysTick_Delay_ms(1500);
}
return 0;
}
void wifi_Test(void)
{
u8 *instruction = "";
instruction="AT";
sentATCmd(instruction,3);
SysTick_Delay_ms(1500);
instruction="AT+GMR";
sentATCmd(instruction,3);
SysTick_Delay_ms(1500);
instruction="AT+CWMODE=1";
sentATCmd(instruction,3);
SysTick_Delay_ms(1500);
instruction="AT+CWJAP="pengchun","p2952870"";
sentATCmd(instruction,3);
SysTick_Delay_ms(1500);
instruction="AT+CIFSR";
sentATCmd(instruction,3);
SysTick_Delay_ms(1500);
}
int main(void)
{
//Stm32_Clock_Init();
led_init();
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
exti_init();
usart1_init(9600);
usart3_init(115200);
led1 = 0;
led2 = 0;
printf("system start!n");
while(1)
{
wifi_Test();
}
}
现象结果
可以观察到wifi模块响应的响应。
在此测试中发现连接wifi热点响应时间较慢,编程时应该给予更多的响应时间。
三、编写为wifi模块服务的文件。
遇到的问题:如何usart3接收到的数据时一次发送过来的数据?
解决:通过延时读RXBUF,把这段时间内发送过来的数据看作一次连续发送的数据。
esp_8622wifi.h
#ifndef ESP_8622WIFI_H
#define ESP_8622WIFI_H
#include "usart.h"
#include "stm32f10x.h"
#include "bsp_systick.h"
#include "string.h"
//WiFi连接
//云平台连接
//数据上传
//命令上传
#define DeviceID "AIPickUpClothes"//设备表标识
#define SecretKey "0a7a1d29d34748dca7dfe19543b16098"//密钥
u8 sentATCmd(u8 *cmd,u8 *ack,u8 times);
u8 sentData(u8 *data,u8 *ack,u8 times);
u8 connect_Wifi(void);
u8 connect_Cloud(void);
u8 ESP8266_sensorSend(u8 *sensorTag,u8 sensorValue,u8 tryTimes);
#endif
esp_8622wifi.c
#include "esp_8622wifi.h"
/*****************************************************************************************
* Function Name : check_AT_Respose
* Descrption : 使用串口3发送AT指令
* Input : string 期待的响应内容
* Output : None
* Return : None
*****************************************************************************************/
u8 check_AT_Respose(u8 *string)
{
printf("n接收到模块响应数据为:n%s",USART3_RX_BUF);
if(strstr((const char*)USART3_RX_BUF,(const char*)string) != 0)
{
printf("n接收到期待的响应 %s",string);
USART3_RX_STA = 0;
memset(USART3_RX_BUF,0x00,USART3_REC_LEN);
return 1;
}
else
{
printf("n未接收到期待的响应 %s",string);
USART3_RX_STA = 0;
memset(USART3_RX_BUF,0x00,USART3_REC_LEN);
return 0;
}
}
/*****************************************************************************************
* Function Name : sentATCmd
* Descrption : 使用串口3发送AT指令
* Input : string 发送内容,ack期许的应答,times重试次数
* Output : None
* Return : None
*****************************************************************************************/
u8 sentATCmd(u8 *cmd,u8 *ack,u8 times)
{
u8 i;
for(i=0;i<times;i++)
{
u3_printf("%srn",cmd);
printf("n已发送指令:%s",cmd);
SysTick_Delay_ms(1500);
if(check_AT_Respose(ack))
return 1;
printf("n发送指令响应错误,1.5s后重新发送指令:%s",cmd);
SysTick_Delay_ms(1500);
}
return 0;
}
/*******************************************************************
*函数:u8 ESP8266_IpSend(u8 *data,u8 *ack,u8 lenth,u8 times)
*功能:发送数据函数
*输入:
u8 *data, 发送的数据氨?
u8 *ack, 期待的响应
u8 sensor, 传感数值
u8 tryTimes 若不成功尝试发送次数
*输出:
return = 1 ,sucess
return = 0 ,error
*特殊说明:
*******************************************************************/
u8 ESP8266_IpSend(u8 *data,u8 *ack,u8 lenth,u8 tryTimes)
{
u8 i;
u8 CIPSEND[USART3_SEND_LEN];
memset(CIPSEND,0x00,USART3_SEND_LEN);
sprintf((char *)CIPSEND,"AT+CIPSEND=%d",lenth);
for(i=0;i<tryTimes;i++)
{
u3_printf("%srn",CIPSEND);
SysTick_Delay_ms(100);
if(check_AT_Respose("OK"))
{
u3_printf("%s",data);
printf("n已经发送数据报:%s",data);
SysTick_Delay_ms(500);
if(check_AT_Respose(ack))
return 1;
printf("n数据响应错误,1.5s后重新发送指令:%s",data);
SysTick_Delay_ms(1500);
}
else
{
printf("CIPSEND发生错误!");
}
}
return 0;
}
/*******************************************************************
*函数:ESP8266_SendSensor
*功能:发送传感数据到服务器
*输入:
u8 *SensorTag, 对象标签名称
u8 sensor, 传感数值
u8 tryTimes 若不成功尝试发送次数
*输出:
return = 1 ,sucess
return = 0 ,error
*特殊说明:
函数流程:
1、拼接json数据包
2、发送数据包
3、
*******************************************************************/
u8 ESP8266_sensorSend(u8 *sensorTag,u8 sensorValue,u8 tryTimes)
{
u8 jsonTemp[USART3_SEND_LEN];
memset(jsonTemp,0x00,USART3_SEND_LEN);
sprintf((char*)jsonTemp,"{"t":3,"datatype":1,"datas":{"%s":%d},"msgid":001}",sensorTag,sensorValue);
if(ESP8266_IpSend(jsonTemp,""status":0",strlen((char*)jsonTemp),tryTimes))
return 1;
return 0;
}
/*******************************************************************
*函数:connect_Wifi
*功能:连接上wifi热点
*输入:None
*输出:
return = 1 ,sucess
return = 0 ,error
*特殊说明:
函数流程:
1、检测wifi模块
2、设置为sta模式
3、连接wifi热点
*******************************************************************/
u8 connect_Wifi(void)
{
u8 *instruction="AT";
if(sentATCmd(instruction,"OK",3))//检测wifi模块
{
SysTick_Delay_ms(1000);
instruction="AT+CWMODE=1";
if(sentATCmd(instruction,"OK",3))//设置为sta模式
{
SysTick_Delay_ms(1500);
instruction="AT+CWJAP="pengchun","p2952870"";
if(sentATCmd(instruction,"OK",5))//连接wifi热点
{
return 1;
}
}
}
return 0;
}
/*******************************************************************
*函数:connect_Cloud
*功能:连接上新大陆云平台
*输入:None
*输出:
return = 1 ,sucess
return = 0 ,error
*特殊说明:
函数流程:
1、检测wifi模块
2、设置为sta模式
3、连接wifi热点
*******************************************************************/
u8 connect_Cloud(void)
{
u8 *instruction = "";
instruction="AT+CIPSTART="TCP","120.77.58.34",8700";
if(sentATCmd(instruction,"OK",3))
{
u8 IPDATA[200];
memset(IPDATA,0x00,200);
sprintf((char *)IPDATA,"{"t":1,"device":"%s","key":"%s","ver":"v0.0.0.0"}",DeviceID,SecretKey);
if(ESP8266_IpSend(IPDATA,"{"status":0,"t":2}",strlen((char*)IPDATA),3))
{
printf("与云平台握手连接成功");
return 1;
}
}
return 0;
}
main.c
#include "stm32f10x.h"
#include "bsp_systick.h"
#include "led.h"
#include "exti.h"
#include "Tool.h"
#include "usart.h"
#include "esp_8622wifi.h"
u8 wifiConnected = 0;
u8 cloudConnected = 0;
int main(void)
{
led_init();
exti_init();
usart1_init(9600);
usart3_init(115200);
led1 = 0;
led2 = 0;
printf("system start!n");
while(1)
{
if(wifiConnected == 0)
if(connect_Wifi())
wifiConnected=1;
if((wifiConnected == 1) && (cloudConnected == 0))
if(connect_Cloud())
cloudConnected=1;
SysTick_Delay_ms(1500);
ESP8266_sensorSend("temperature",30,3);
}
}
现象结果
串口助手结果
查看云平台历史传感数据,云平台一直接收到temperature的传感数据。
最后
以上就是怕孤独便当为你收集整理的stm32学习笔记-通过串口3使用wifi模块连接新大陆云平台一、使用USB转TTL模块测试连接云平台。二、stm32配置串口1,串口3,并进行简单测试。三、编写为wifi模块服务的文件。的全部内容,希望文章能够帮你解决stm32学习笔记-通过串口3使用wifi模块连接新大陆云平台一、使用USB转TTL模块测试连接云平台。二、stm32配置串口1,串口3,并进行简单测试。三、编写为wifi模块服务的文件。所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复