STM32玩转物联网实战篇:01.网络通信前准备
1、准备开发板
在前面我们已经讲完了基础部分的例程,接下来我们正式进入网络通信部分,在此之前,我们需要做些准备,来适配我们的网络通信模块。现在市场上最常用的解决方案就是WIFI和NB,还有在某些要求数据量大、传输速度快的场景会用到的4G,所以我们下面会主要着重以上三个解决方案进行。
开发板功能区分布图
开发板俯视图
网络通信模块对应的串口
由上面的原理图,我们可以知道小熊派的网络通信模块的接口在LPUART1串口上,这个似乎是STM32L系列特有的,它可以通过AT_Switch进行PC和MCU的切换,当你想要用PC调试时,将拨码拨到PC端,然后就可以用网络调试助手进行调试,反之,就是MCU发送AT指令,从而控制网络通信模块。
2、STM32CubeMX生成代码
搜索并选择芯片型号
配置系统时钟
配置时钟树
STM32L4的最高主频可达到80M,最后使HCLK = 80Mhz
即可:
配置GPIO引脚
修改引脚的用户标签(相当于取另一个新名字)
配置串口
配置TIM
计时器更新中断频率计算F:
F = ( arr + 1 )*( psc + 1 ) / 80M 当设置arr = 79,psc = 999时,F = 1000 Hz = 1 K Hz
3、在MDK中编写代码
新建sys.h文件
#ifndef _SYS_H
#define _SYS_H
#include "main.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "stdarg.h"
#include "stdbool.h"
#include "stm32l4xx.h"
#include "usart.h"
//0,不支持os
//1,支持os
#define SYSTEM_SUPPORT_OS 0 //定义系统文件夹是否支持OS#define delay_ms(Delay) HAL_Delay(Delay)void ClearRAM(u8* ram,u32 n);
void USART_SendChar( USART_TypeDef *huart, uint8_t ch );
void USART_SendBuf( USART_TypeDef *huart, uint8_t *str,uint32_t strlen );
void USART_SendString( USART_TypeDef *huart, uint8_t *str);
void UsartPrintf(USART_TypeDef *huart, char *fmt,...);
新建sys.c文件
//清空字节数组
//ram: 待清空的数组
//n: 待清空数组的长度
void ClearRAM(uint8_t* ram,uint32_t n)
{u32 i;for (i = 0;i < n;i++){ram[i] = 0x00;}
}//串口发送字符
//huart: 串口结构体句柄
//ch: 待发送的字符
void USART_SendChar( USART_TypeDef *huart, uint8_t ch )
{while((huart->ISR&0X40)==0);huart->TDR = (uint8_t)ch;
}//串口发送指定长度的字节数组
//huart: 串口结构体句柄
//str: 待发送的字节数组
//strlen: 字节数组长度
void USART_SendBuf( USART_TypeDef *huart, uint8_t *str,uint32_t strlen )
{unsigned int k = 0;do{USART_SendChar(huart,*(str + (k++)));}while( k < strlen );}//串口发送字符串数组
//huart: 串口结构体句柄
//str: 待发送的字符串数组
void USART_SendString( USART_TypeDef *huart, uint8_t *str)
{unsigned int k = 0;do{USART_SendChar(huart,*(str + (k++)));}while(*(str + (k)) != '\0');}//串口发送长度的字符串
//huart: 串口结构体句柄
//str: 待发送的字符串数组
void UsartPrintf(USART_TypeDef *huart, char *fmt,...)
{unsigned char UsartPrintfBuf[200];va_list ap;unsigned char *pStr = UsartPrintfBuf;//RTOS_ENTER_CRITICAL(); //写入多个数据时,进入临界段,放置打断出错va_start(ap, fmt);vsprintf((char *)UsartPrintfBuf, fmt, ap); //格式化va_end(ap);while(*pStr != 0){USART_SendChar(huart,*pStr++);}//RTOS_EXIT_CRITICAL();}
在tim.c下用户区添加以下代码
/* USER CODE BEGIN 0 */
uint32_t time2Count;
/* USER CODE END 0 */
//定时器中断使能
void TIM_Interupt_Enable(void)
{__HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE); //使能定时器更新中断HAL_TIM_Base_Start(&htim2); //启动定时器}
//定时器中断回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2){if(__HAL_TIM_GET_IT_SOURCE(htim,TIM_IT_UPDATE) != RESET) //如果触发了更新中断{if(time2Count++ >= 4294967295UL) //防止数值溢出{time2Count = 0;}__HAL_TIM_CLEAR_IT(htim,TIM_IT_UPDATE); //清除更新中断标志位}}
}
在gpio.h中编写以下代码
/* USER CODE BEGIN Private defines */typedef enum
{LED_OFF = 0,LED_ON,LED_Toggle} LED_ENUM;#define LED_Set(status) status != LED_Toggle ? HAL_GPIO_WritePin( LED_GPIO_Port, LED_Pin, status != LED_ON ? GPIO_PIN_RESET : GPIO_PIN_SET): HAL_GPIO_TogglePin( LED_GPIO_Port, LED_Pin); //利用define可以美化和简短我们的代码,知识点就用到了三目运算符的嵌套判断。/* USER CODE END Private defines */
在usart.h下的用户代码区编写以下代码
/* USER CODE BEGIN Includes */
#if defined ( __CC_ARM )
#pragma anon_unions
#endif
/* USER CODE END Includes *//* USER CODE BEGIN Private defines */#define RX_BUF_MAX_LEN 1024 //最大接收缓存字节数typedef struct
{unsigned short dataLenPre; //上一次的长度数据,用于比较union{unsigned short InfAll;struct {unsigned short dataLen : 15; //接收数据长度unsigned short finishFlag : 1; //接收完成标志}InfBit;};unsigned char rxBuf[RX_BUF_MAX_LEN]; //接收缓存} USART_INFO_STRUCT;#define REC_OK 1 //接收完成标志
#define REC_WAIT 0 //接收未完成标志extern USART_INFO_STRUCT usart1Info;
extern USART_INFO_STRUCT lpuart1Info;/* USER CODE END Private defines *//* USER CODE BEGIN Prototypes */void USART_Interupt_Enable(void);
void USER_UartDMAHandler(UART_HandleTypeDef* huart,USART_INFO_STRUCT* usartInfo);/* USER CODE END Prototypes */
在usart.c下的用户代码区编写以下代码
/* USER CODE BEGIN 0 */#include <stdio.h>USART_INFO_STRUCT usart1Info;
USART_INFO_STRUCT lpuart1Info;int fputc(int ch, FILE *stream)
{/* 堵塞判断串口是否发送完成 */while((USART1->ISR & 0X40) == 0);/* 串口发送完成,将该字符发送 */USART1->TDR = (uint8_t) ch;return ch;
}/* USER CODE END 0 *//* USER CODE BEGIN 1 */void USART_Interupt_Enable(void)
{__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); //空闲中断使能__HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE); //接收中断使能__HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除串口空闲中断标志位__HAL_UART_ENABLE_IT(&hlpuart1,UART_IT_IDLE); //空闲中断使能__HAL_UART_ENABLE_IT(&hlpuart1,UART_IT_RXNE); //接收中断使能__HAL_UART_CLEAR_IDLEFLAG(&hlpuart1); //清除串口空闲中断标志位}void USER_UartDMAHandler(UART_HandleTypeDef* huart,USART_INFO_STRUCT* usartInfo)
{uint32_t ucCh;if(huart->Instance == USART1){if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET) //触发空闲中断{__HAL_UART_CLEAR_IDLEFLAG(huart); //清除串口2空闲中断标志位HAL_UART_DMAStop(huart); //关闭DMAucCh = huart->Instance->ISR; //清除SR状态寄存器ucCh = huart->Instance->RDR; //读取DR数据寄存器 用来清除中断ucCh = hdma_usart1_rx.Instance->CNDTR; //获取DMA中未传输的数据个数usartInfo->InfBit.dataLen = RX_BUF_MAX_LEN - ucCh; //总计数减去未传输的数据个数,得到已经接收的数据个数usartInfo->InfBit.finishFlag = REC_OK; //标志接收成功}HAL_UART_Receive_DMA(huart,usartInfo->rxBuf,RX_BUF_MAX_LEN); //使能DMA接收到buf1}if(huart->Instance == LPUART1){if(__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET) //触发空闲中断{__HAL_UART_CLEAR_IDLEFLAG(huart); //清除串口2空闲中断标志位HAL_UART_DMAStop(huart); //关闭DMAucCh = huart->Instance->ISR; //清除SR状态寄存器ucCh = huart->Instance->RDR; //读取DR数据寄存器 用来清除中断ucCh = hdma_lpuart_rx.Instance->CNDTR; //获取DMA中未传输的数据个数usartInfo->InfBit.dataLen = RX_BUF_MAX_LEN - ucCh; //总计数减去未传输的数据个数,得到已经接收的数据个数usartInfo->InfBit.finishFlag = REC_OK; //标志接收成功}HAL_UART_Receive_DMA(huart,usartInfo->rxBuf,RX_BUF_MAX_LEN); //使能DMA接收到buf1}
}/* USER CODE END 1 */
在stm32l4xx_it.c中的USART1_IRQHandler函数的用户代码区编写以下代码
/*** @brief This function handles USART1 global interrupt.*/
void USART1_IRQHandler(void)
{/* USER CODE BEGIN USART1_IRQn 0 */USER_UartDMAHandler(&huart1,&usart1Info); //用户中断代码/* USER CODE END USART1_IRQn 0 */HAL_UART_IRQHandler(&huart1);/* USER CODE BEGIN USART1_IRQn 1 *//* USER CODE END USART1_IRQn 1 */
}
/*** @brief This function handles LPUART1 global interrupt.*/
void LPUART1_IRQHandler(void)
{/* USER CODE BEGIN LPUART1_IRQn 0 */USER_UartDMAHandler(&hlpuart1,&lpuart1Info); //用户中断代码/* USER CODE END LPUART1_IRQn 0 */HAL_UART_IRQHandler(&hlpuart1);/* USER CODE BEGIN LPUART1_IRQn 1 *//* USER CODE END LPUART1_IRQn 1 */
}
STM32玩转物联网实战篇:01.网络通信前准备相关推荐
- STM32玩转物联网实战篇:2.ESP8266 WIFI模块TCP通信示例详解
1.准备开发板 开发板功能区分布图 开发板俯视图 2.ESP8266简介 ESP8266 WIFI模块内置TCP/IP网络协议,模块支持三种网络模式,AP.STA和AP+STA模式,AP模式: ...
- 51单片机怎么显示当前时间_51单片机玩转物联网基础篇06-LCD1602液晶显示器
前言 本节我们开始学习LCD1602,LCD1602是字符型液晶显示屏,在实际项目中应用非常广泛,学完本节就可以逐步开发一些好玩的应用了. 一.基础知识 1.LCD1602简介 LCD1602是字符型 ...
- 51单片机玩转物联网基础篇05-控制继电器
前言 本节我们开始学习如何使用51单片机控制继电器,有了继电器,我们可以使用单片机输出的低电平控制高电平期间工作,比如继电器接到220V用电器上,可通过单片机智能控制用电器. 一.基础知识 1.继电器 ...
- 玩转Docker实战篇!使用Docker搭建Sinatra Web程序,附加介绍容器关联(Docker Networking、Docker链接)
一.本文目的 前面一篇文章,我们在Docker中搭建了Nginx服务器,并访问了Nginx服务器:https://blog.csdn.net/qq_41453285/article/details/1 ...
- Docker JFrog Artifactory 7.27.10 maven私服(IDEA 实战篇01) linux
文章目录 一.私服配置 1. 账户密码 2. 本地仓库 3. ip/port 二.IntelliJ IDEA 2.1. 创建项目 2.2. 指定配置 2.3. 下载依赖 2.4. 依赖查看 2.5. ...
- 玩转Docker实战篇!使用Docker与Jenkins进行持续集成测试,附加介绍Docker-in-Docker
一.本文目的 在前面的文章中,所有的测试例子都是本地的.围绕着单个开发者的(就是说,如何让本地开发者使用Docker来测试本地网站或者引用程序).现在来看看在多开发者的持续集成测试场景中如何使用Doc ...
- OKR之剑·实战篇06:OKR致胜法宝-氛围业绩双轮驱动(下)
作者:vivo 互联网平台产品研发团队 本文是<OKR 之剑>系列之实战第 6 篇-- 本文介绍团队营造氛围的方法与实践.在业绩方面的探索与输出,在两方面分别总结了一些经验分享给大家. 一 ...
- OKR之剑·总结篇01:如何开好一场OKR复盘会
作者:vivo 互联网平台产品研发团队 本文是<OKR 之剑>系列之总结第 1 篇-- OKR复盘是OKR生命周期中的重要环节,起着承上启下的重要作用.本篇将和你一起探讨什么是OKR复盘. ...
- OKR之剑·实战篇05:OKR致胜法宝-氛围业绩双轮驱动(上)
作者:vivo 互联网平台产品研发团队 本文是<OKR 之剑>系列之实战第 5 篇-- 我们的OKR执行如此顺利,离不开我们的"双轮驱动".类似于亚马逊的"飞 ...
最新文章
- 6月27日任务 配置Tomcat监听80端口、配置Tomcat虚拟主机、Tomcat日志
- 世界机器人大会|人工智能VS人类
- Redis学习笔记(八)——持久化
- 转换php script类型,ECMAScript 类型转换
- 谈谈R中的乱码(一)
- SQL ltrim() 和 rtrim() 函数
- 追踪电子邮件行踪的“眼”
- MySQL抽稀_Android GPS定位轨迹抽稀之道格拉斯-普克(Douglas-Peuker)算法详解
- CrossApp 0.4.2 发布,隆重推出 WebView
- 华为交换机端口vlan详解
- JAVA打字游戏代码
- uni-app h5打包发版到测试和生产环境具体步骤
- 在午睡,手机接连振动,是几个朋友用短信微信问我
- html5 canvas文字标签云3D旋转动画特效
- python中关于命名的例子_利用Python批量重命名文件(给非技术人员的Python实例参考)...
- 数据版“吐槽大会”: 国产综艺节目年终盘点
- oracle创建Triggers
- python 仪表盘 ppt_python+仪表
- NJ4X源码阅读分析笔记系列(一)——项目整体分析 1
- (48)STM32——图片显示实验