NB-IoT(7)---开发环境搭建及模组驱动开发

NB-IoT(7)---开发环境搭建及模组驱动开发

 

STM32CubeMX安装及使用

1、STM32CubeMX介绍

2、STM32CubeMX安装

3、STM32CubeMX使用

STM32CubeMX介绍

STM32CubeMX简介

微控制器图形化配置

– 自动处理引脚冲突

– 动态设置确定的时钟树

– 可以动态确定参数设置的外围和中间件模式和初始化

– 功耗预测

C代码工程生成器覆盖了STM32微控制器初始化编译软件,如IAR,KEIL,GCC可以独立使用,作为Eclipse插件使用

HAL库与STD库

STD库-标准外设库

– 寄存器操作,将一些基本的寄存器操作封装成函数

HAL库-硬件抽象库

– 将这些抽象成了一个抽象层,从使用的角度来看,是与硬件无关的

HAL库优势

– HAL库是ST未来主推的库,从2015开始ST新出的芯片已经没有STD库

– HAL库的处理机制比STD库好很多,HAL库支持STM32全线产品

– HAL库跨芯片的可移植性非常好

STM32CubeMX安装

STM32CubeMX安装

安装JAVA运行环境,JavaSetup8u151.exe

安装SetupSTM32CubeMX-4.22.0.exe,最好不要有中文路径

加载 “stm32cube_fw_f0_v180.zip”HAL库到STM32CubeMX中

STM32CubeMX加载固件库

Keil安装及使用

1、Keil介绍

2、Keil安装

3、Keil使用

Keil介绍

行业领先的ARM C/C++编译工具链

μVision5 IDE集成开发环境,调试器和仿真环境

符合CMSIS (Cortex微控制器软件接口标准)

MDK-ARM软件为基于Cortex-M、Cortex-R4、ARM7、ARM9处理器设备提供了一个完整的开发环境。 MDK-ARM专为微控制器应用而设计,不仅易学易用,而且功能强大,能够满足大多数苛刻的嵌入式应用。

Keil安装

安装“MDK-523.exe”嵌入式开发环境

双击软件图标打开软件安装界面:

一直点击Next,License选项框打钩

输入用户、城市、电子邮件信息

选择安装目录为默认即可

点击Next,开始安装,安装完成后,桌面显示

Keil破解

以管理员身份运行Keil5,在File菜单下,选择License Management,复制CID

以管理员身份运行KEIL_Lic.exe,粘贴CID,选择Target为ARM,点击Generate成注册码

注册码复制到New License ID Code下,点击Add LIC,完成破解

设备包安装

选择Pack Installer 安装设备支持包

选择File菜单,点击Import

导入Keil.STM32F0xx_DFP.1.4.0

STLink驱动安装

右击此电脑,选择管理

选择设备管理器,发现其他设备STM32 STLink

右击STM32 STLink,选择更新驱动程序

选择浏览我的计算机…….

点击浏览选择驱动目录,win10系统选择Window8

完成驱动安装

NB-IoT基础工程建立

1、原理图分析

2、IO口、时钟及外设配置

3、LCD驱动移植

4、Printf函数重定向

原理图分析

分析NB-IoT核心板原理

分析一键还原底板原理

建立IO功能映射表

IO口、时钟及外设配置

IO口配置

选择IO标签,根据IO功能映射表配置为相对应的功能

时钟配置

选择时钟源为HSE(外部高频时钟)

配置倍频系数为6

使能锁相环配置系统主时钟为48M

外设树配置

SPI选择全双工主机模式

USART1选择异步收发模式

USART2选择异步收发模式

USART配置

USART1& USART2设置波特率为9600、开启全局中断

SPI配置

设置数据位为8位

设置波特率为1.5MBit/s

时钟极性为低电平驱动

时钟相位为第一个边沿

LCD驱动移植

LCD主要用于人机交互,动态显示设备信息

相关LCD的驱动开发已在LoRa中讲解,现只做移植

将下图所示文件添加到工程中,修改SPI初始化代码即可(LCD的 MISO用于数据和指令切换)

将PB4的复用功能模式更改为推挽输出模式 

 
  1. GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_5;

  2. GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;//功能复用模式

  3. GPIO_InitStruct.Pull = GPIO_NOPULL;

  4. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  5. GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;

  6. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  7.  
  8. /* USER CODE BEGIN SPI1_MspInit 1 */

  9. //LCD驱动使能PB4为输出模式

  10. GPIO_InitStruct.Pin = GPIO_PIN_4;

  11. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//推挽输出模式

  12. GPIO_InitStruct.Pull = GPIO_NOPULL;

  13. GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  14. HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

添加头文件和LCD初始化函数

 
  1. #include "lcd.h"

  2. #include <stdio.h>

 
  1. Lcd_Init();

  2. Lcd_Clear(YELLOW);

Printf函数重定向

 
  1. #include <stdio.h>

  2. int fputc(int ch, FILE *f)

  3. {     

  4.    while((USART1->ISR & 0X40)==0);

  5.    USART1->TDR = (uint8_t)ch;      

  6.    return ch;

  7. }

AT指令集开发原理

1、什么是AT指令集

2、NB-IoT关键AT指令介绍

3、串口透传开发

4、AT指令测试

什么是AT指令集

串口模块

AT指令集

在90年代,诺基亚、爱立信、摩托罗拉和HP共同为GSM研制了一整套AT指令

    -->GSM模块与计算机之间的通信协议是一些AT指令集

    -->AT指令是以AT为首,字符结束的字符串,AT指令的响应数据包也是一个字符串

AT指令格式

DTE:AT< CR>< LF>(发送:AT+回车+换行)

DCE:< LF> OK < LF>(返回:换行+OK+换行)

DTE:ATTEST< CR>< LF>(发送:ATTEST+回车+换行)

DCE:< CR> ERROR < LF>(返回:回车+ERROR+换行)

如果AT指令执行成功,“OK”字符串返回;

如果AT 指令语法错误或AT 指令执行失败,“ERROR”字符串返回。

NB-IoT关键AT指令介绍

NB-IoT初始化AT指令

AT+CFUN=0关闭射频功能(不进行无线通讯)

AT+CFUN=1开启射频功能

AT+NBAND?查询(读取)模组配置频段

AT+NBAND=5配置模组为电信频段

AT+CGSN=1 查询IMEI号(一般出厂已经设置好)

AT+CGSN=1,201612091450303 设置IMEI号

AT+NCDP=XX.XX.XX.XX 设置 IoT 平台 IP 地址(非 COAP 协议可以不配置)

AT+NRB 软重启

AT+CIMI 查询SIM卡信息

AT+CMEE=1 开启错误提示

AT+CGDCONT=1,”IP”,”ctnet”设置APN

AT+CSQ 获取信号质量

NB-IoT连接网络AT指令

AT+CSCON=1 设置基站连接通知

AT+CEREG=2 设置连接核心网通知

AT+NNMI=1 开启下行数据通知

AT+CGATT=1 自动搜网

AT+NUESTATS 查询 UE 状态

AT+CGPADDR 查询核心网分配的 ip 地址

NB-IoT数据收发AT指令

UDP数据收发

在发送数据前先建立 socket:AT+NSOCR=DGRAM,17,XXXX,1 XXXX 为 SOCKET 监听的端口号, 回复 OK 创建成功

AT+NSOST=0,192.158.5.1,1024,2,AB30 向 192.158.5.1:1024 发送两字节数据: 0xAB 0x30

+NSONMI:0,4 模组提示收到了四字节数据

AT+NSORF=0,256 读取接收到的数据, 最多读取 256 个

0, 192.158.5.1,1024,4,A1A2A3A4,0 收到 192.158.5.1:1024 返回的四字节数据 0xA1 0xA2 0xA3 0xA4

COAP数据收发

CoAP 数据发送无需事先建立 socket(模组内部处理) , 直接发送数据:

    -->AT+NMGS=2,A1A2 发送 2 字节数据, 发送成功回复 OK, 否则 ERROR

读取 CoAP 数据:

    -->+NNMI:2,A1A2 收到 2 字节 CoAP 数据

串口透传开发

为了便于我们快速掌握AT指令原理:MCU充当透明传输,PC机直接与NB-IoT模组直接通讯(通过串口中断实时收发数据)

串口接收中断使能:

 

 
  1. uint8_t Usart1Rx = 0;

  2. uint8_t Usart2Rx = 0;

  3.  
  4.  
  5. __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);//打开UART1接收中断(接收寄存器不为空则产生中断)

  6.  
  7. HAL_UART_Receive_IT(&huart1, &Usart1Rx, 1);//UART1接收使能,Usart1Rx:接收数据的缓存区

  8.  
  9. __HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);//打开UART2接收中断(接收寄存器不为空则产生中断)

  10.  
  11. HAL_UART_Receive_IT(&huart2, &Usart2Rx, 1);//UART2接收使能,Usart2Rx:接收数据的缓存区

重写串口中断函数:

 
  1. void USART1_IRQHandler(void)

  2. {

  3. //uint8_t data;

  4.  
  5. if(__HAL_UART_GET_FLAG(&huart1,UART_FLAG_RXNE) == SET)//判断是否为串口接收中断(是否产生UART_FLAG_RXNE标志)

  6. {

  7. while((USART2->ISR&0x40) == 0);//判断UART2是否发送完成

  8.  
  9. //data = USART1->RDR;

  10.  
  11. USART2->TDR = USART1->RDR;//将UART1接收的数据赋值给UART2的发送寄存器,由UART2将数据自动发送给NB-IOT

  12. //USART1->TDR = data;

  13. }

  14. HAL_UART_IRQHandler(&huart1);

  15. }

  16.  
  17. void USART2_IRQHandler(void)

  18. {

  19.  
  20. if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_RXNE) == SET)

  21. {

  22. while((USART1->ISR&0x40) == 0);

  23.  
  24. USART1->TDR = USART2->RDR;//将UART2接收的数据赋值给UART1的发送寄存器,由UART1将数据自动发送给PC

  25. }

  26.  
  27. HAL_UART_IRQHandler(&huart2);

  28. }

AT指令测试

操作步骤:

 

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NB-IoT硬件驱动开发代码的实现过程与具体的硬件平台和NB-IoT模组有关,下面是一份基于 STM32 平台和SIMCom SIM7020E模组NB-IoT硬件驱动开发代码,供参考: 1. 硬件接口定义: ```c /* 串口接口定义 */ #define NB_UART USART1 #define NB_UART_CLK RCC_APB2Periph_USART1 #define NB_UART_CLK_CMD RCC_APB2PeriphClockCmd #define NB_UART_IRQn USART1_IRQn #define NB_UART_IRQHandler USART1_IRQHandler #define NB_UART_TX_PIN GPIO_Pin_9 #define NB_UART_RX_PIN GPIO_Pin_10 #define NB_UART_GPIO GPIOA #define NB_UART_GPIO_CLK RCC_APB2Periph_GPIOA /* GPIO接口定义 */ #define NB_PWRKEY_PIN GPIO_Pin_1 #define NB_PWRKEY_GPIO GPIOB #define NB_PWRKEY_GPIO_CLK RCC_APB2Periph_GPIOB #define NB_PWRKEY_HIGH() GPIO_SetBits(NB_PWRKEY_GPIO, NB_PWRKEY_PIN) #define NB_PWRKEY_LOW() GPIO_ResetBits(NB_PWRKEY_GPIO, NB_PWRKEY_PIN) #define NB_STATUS_PIN GPIO_Pin_0 #define NB_STATUS_GPIO GPIOB #define NB_STATUS_GPIO_CLK RCC_APB2Periph_GPIOB #define NB_STATUS_READ() GPIO_ReadInputDataBit(NB_STATUS_GPIO, NB_STATUS_PIN) ``` 2. 驱动程序编写: (1)初始化NB-IOT模组 ```c void nb_init(void) { /* 使能UART和GPIO时钟 */ RCC_APB2PeriphClockCmd(NB_UART_CLK | NB_UART_GPIO_CLK | NB_PWRKEY_GPIO_CLK | NB_STATUS_GPIO_CLK, ENABLE); /* 配置UART引脚 */ GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = NB_UART_TX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(NB_UART_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = NB_UART_RX_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(NB_UART_GPIO, &GPIO_InitStructure); /* 配置GPIO引脚 */ GPIO_InitStructure.GPIO_Pin = NB_PWRKEY_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(NB_PWRKEY_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = NB_STATUS_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(NB_STATUS_GPIO, &GPIO_InitStructure); /* 复位NB-IOT模组 */ NB_PWRKEY_LOW(); delay_ms(100); NB_PWRKEY_HIGH(); delay_ms(5000); } ``` (2)发送AT指令 ```c uint8_t nb_send_at_cmd(char *cmd, char *resp, uint16_t timeout) { uint8_t i = 0, j = 0; uint8_t ret = 0; char rx_buf[256] = {0}; uint32_t t1 = 0, t2 = 0; /* 发送AT指令 */ USART_ITConfig(NB_UART, USART_IT_RXNE, DISABLE); USART_ITConfig(NB_UART, USART_IT_TC, ENABLE); while (cmd[i] != '\0') { USART_SendData(NB_UART, (uint16_t)cmd[i++]); while (USART_GetFlagStatus(NB_UART, USART_FLAG_TC) == RESET); } /* 等待模组应答 */ USART_ITConfig(NB_UART, USART_IT_TC, DISABLE); USART_ITConfig(NB_UART, USART_IT_RXNE, ENABLE); t1 = millis(); while ((millis() - t1) < timeout) { if (USART_GetFlagStatus(NB_UART, USART_FLAG_RXNE) == SET) { rx_buf[j++] = (char)USART_ReceiveData(NB_UART); } if (strstr(rx_buf, resp) != NULL) { ret = 1; break; } } return ret; } ``` (3)数据收发 ```c void nb_send_data(uint8_t *data, uint16_t len) { /* 发送数据 */ char cmd[64] = {0}; sprintf(cmd, "AT+NMGS=%d,%02X", len, data[0]); nb_send_at_cmd(cmd, "OK", 2000); memset(cmd, 0, sizeof(cmd)); for (uint16_t i = 0; i < len; i++) { sprintf(cmd + strlen(cmd), "%02X", data[i]); } nb_send_at_cmd(cmd, "OK", 2000); } uint16_t nb_recv_data(uint8_t *data) { /* 接收数据 */ char cmd[64] = {0}; nb_send_at_cmd("AT+NMGR=1", "+NMGR:", 2000); char *ptr = strstr((char *)nb_rx_buf, ","); ptr++; uint16_t len = 0; sscanf(ptr, "%02X", &len); ptr += 2; for (uint16_t i = 0; i < len; i++) { sscanf(ptr + i * 2, "%02X", (unsigned int *)(data + i)); } return len; } ``` 3. 应用程序开发 (1)连接网络 ```c uint8_t nb_connect_network(void) { nb_send_at_cmd("AT+CFUN=0", "OK", 2000); nb_send_at_cmd("AT+CFUN=1", "OK", 2000); nb_send_at_cmd("AT+COPS=1,2,\"46001\"", "OK", 2000); nb_send_at_cmd("AT+CGDCONT=1,\"IP\",\"ctnet\"", "OK", 2000); nb_send_at_cmd("AT+CFUN=0", "OK", 2000); nb_send_at_cmd("AT+CFUN=1", "OK", 2000); nb_send_at_cmd("AT+CSQ", "OK", 2000); uint8_t i = 0; while (i < 10) { if (NB_STATUS_READ() == 0) { return 1; } delay_ms(1000); i++; } return 0; } ``` (2)发送数据 ```c uint8_t nb_send(uint8_t *data, uint16_t len) { uint8_t retry = 3; while (retry > 0) { nb_send_data(data, len); if (nb_send_at_cmd("AT+NMGS?", "+NMGS:", 2000) == 1) { return 1; } retry--; } return 0; } ``` (3)接收数据 ```c uint16_t nb_recv(uint8_t *data) { uint16_t len = 0; if (nb_send_at_cmd("AT+NMGR?", "+NMGR:", 2000) == 1) { len = nb_recv_data(data); } return len; } ``` 以上代码仅供参考,实际使用时需要根据具体的硬件平台和NB-IoT模组进行相应的修改和调试。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值