一、doNB-M5310AM01核心板
1. 硬件资源
M5310A模组
stm32L011
降压电路
串口电平转换电路
LED灯*2 (分别连接至5310和stm32)
其他:nanoSIM、排针接口电路、复位电路......
2. 软件资源:
多平台例程:MSP、STC、stm32F103、stm32L011
还有一系列核心板上所用到的硬件datasheet
3. 核心板原理图
- 电源:buck电路
- 排针接口:常规引出
- UART电平转换:三极管+二极管
- M5310复位电路:按键复位 或 stm32的 PB7控制复位
- 状态指示灯:其一连接到M5310的NETLIGHT引脚,另一连接至stm32的PB1
- NanoSIM卡电路:规范连接
- M5310-A模块:所需引脚引出
- stm32:32.768晶体,复位控制端引出至排针,BOOT0接10K到地,PB6 PB7引出为触点,PA4 5 6 7引出到排针。
着重看串口选择电路:
- LPUART1:stm32
- TXD/RXD:M5310经电平转换后
- TXD IO/RXD IO:排针
-
USART2:stm32
才疏学浅,没见过这个原理图元件,看不懂到底是怎么个接法,默认连接的到底是哪两端。
乍一看,这个符号有点像电阻,可能是左右两端连接?TX RX也对上。但是逻辑上又不对,总不能stm32自己与自己串口通信吧。
摸索好一阵子才弄懂,应该是竖着的两端连接。
USART2 | Header | M5310 | LPUART1 |
---|---|---|---|
TX | TX | TX | RX |
RX | RX | RX | TX |
实物图与表格对应,其中Header与M5310通过0ohm电阻默认连接。
也就是说,默认将M5310的串口引出到排针。可以自行调整0ohm电阻位置,实现不同连接。
左短接:USART2引出至排针
右短接:M5310与stm32 LPUART1连接
可以猜测,这个核心板的串口通信拓扑应该是这样的:
外设 <—USART2—> stm32L0 <—LPUART1—> M5310
即去掉中间的默认短接,再左短接、右短接,使USART2引出到排针,与外设通信。LPUART1连接M5310,收发AT指令。
二、基于HAL库的程序——stm32L0
1. cubeMX中的引脚分配与时钟配置
外接32.768MHz晶体,使用LPUART1和USART2,串行调试方式(SW)。
共7个GPIO,但注意其中PB1已经连接到LED,PB7接0ohm电阻到M5310复位电路。
LSE 32.768MHz作RTC时钟源。
HSI 16MHz作锁相环时钟输入,倍频到32MHz后作系统时钟源。
其余时钟配置如图。
2. keil工程
先看一下工程结构:
-
startup_stm32l011xx.s
启动文件 -
stm32L0xx_it.c
中断向量函数 -
main.c
就是main -
AT_Command_Parser.c
接收到的AT指令解析 -
M5310A.c
5310的一系列操作函数 -
stm32L0xx_hal_msp.c
MSP文件(MSP啥意思) -
system_stm32L0xx.c
systeminit函数 -
stm32L0xx_hal_.....c
HAL库函数
在看main之前,先验证一下前面 串口通信拓扑的猜测。
AT指令是哪个串口发送的?
M5310A.c中的Send_At_Command()函数中有这么一句:
HAL_UART_Transmit_IT(&M5310A_UART, M5310A.TxBuffer, M5310A_TX_SIZE);
可以看出,AT指令是通过M5310A_UART端口发送的,
而M5310A_UART在头文件中的定义为:
#define M5310A_UART huart2
AT指令是通过USART2发送的,与之前的猜测不一致。
再来看看接收:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART2)
{
M5310A_RxCallBack();
}
}
如果接收中断来自于USART2,则M5310A_RxCallBack()
跳转到M5310A_RxCallBack(),代码作者给出的描述是:
//描述:接收串口的回调函数,用来解析接收的数据并将数据交个AT指令处理函数处理
AT指令的响应事件是由USART2产生的。
看完USART2,再看看LPUART1
浏览代码后发现,printf()重定向为LPUART1发送:
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&hlpuart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
此外没有发现有关LPUART1的代码
那么说,之前观察硬件的猜测是错误的。
度云公司给出的例程中,AT指令通过USART2收发。相应地,LPUART1与外设通信。这与硬件上理应的接线顺序不一样。要么改程序中的端口设置,要么飞线,算是有点小坑。
(吐槽:这串口选择电路做的就nm离谱,4个Pin加个0ohm电阻的事情,非要用个奇奇怪怪的符号恶心人)
来看main:
在一堆 Init()之后,只剩下这么几句:
/* USER CODE BEGIN 2 */
printf("Init M5310A\n");
if(!M5310A_Api_Init())
{
while(1)
{
printf("Init M5310A fail\n");
HAL_Delay(1000);
}
}
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
Brd_M5310A_AT_MIPLNOTIFY(0,3200,0,5500,5,"1",1);
Brd_M5310A_AT_MIPLNOTIFY(0,3200,0,5750,1,"doiot",1);
M5310A_exit();
while(1);
/* USER CODE END WHILE */
}
- M5310A_Api_Init():M5310与移动Onenet云平台进行连接
- Brd_M5310A_AT_MIPLNOTIFY():更新消息到Onenet云平台
这俩函数定义在M5310A.c
中。此 .C文件封装好了对M5310模组的操作函数。一同使用的还有AT_Command_Paser.c
,这一 .C文件封装好了对串口接收内容解析操作 ,主要是对AT指令回应内容的解析。
这两个两个库由度云公司提供,使M5310-A与OneNET平台的连接变得简单。