NBIOT-BC28模块程序操作接口编写(基于STM32F103ZET6)
扫描二维码
随时随地手机看文章
项目最终效果,大家可以根据API的去实现自己的业务需求。
程序设计结构体,存储获取模组的相关信息
typedef struct NETWORK_INFO{//初始化NB模块的状态u8 Init_NB_Status ;//NB模块的信号强度u8 signalCSQ ;//IMEI卡号char IMEI[16];//IMSI卡号char IMSI[16];//注网标志位bool Register_NetWork_Flag ;//服务器连接标志位bool Connect_Server_Flag ;} NETWORK_DEVICE_INFO;extern NETWORK_DEVICE_INFO NBIOT_MODULE_INFO ;
下面实现操作NB的方法,首先是最核心的NB指令发送函数,有了这样一个函数,后面的应用才能写,这里用的是中断采集的方式,后续可以更改成DMA接收,传输效率会更高一些,等下次更新一个新的版本,附带完整的测试工程。
/** 函数名:NBIOT_Cmd* 描述 :对NBIOT模块发送AT指令* 输入 :cmd,待发送的指令* reply1,reply2,期待的响应,为NULL表不需响应,两者为或逻辑关系* waittime,等待响应的时间* 返回 : 1,指令发送成功* 0,指令发送失败* 调用 :被外部调用*/bool NBIOT_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime ){bool status = false ;USART4_RX_STA = 0; //从新开始接收新的数据包NB_FramLength = 0 ;memset(RXBuffer, 0, RXBUFFER_LEN); //清空接收缓冲u4_printf("%s\r\n", cmd);if ( ( reply1 == 0 ) && ( reply2 == 0 ) ) //不需要接收数据return true;Delay_ms ( waittime ); //延时RXBuffer[NB_FramLength] = '\0';printf("RXBuffer:%s\n", RXBuffer);if(strstr((char *)RXBuffer, reply2) != NULL){printf("ackerror:%s\n", reply2);return false ;}if(strstr((char *)RXBuffer, reply1) != NULL){printf("acksuccess:%s\n", RXBuffer);//如果匹配到断连标志,就重新建立连接if(strstr((char *)RXBuffer, "+NSOCLI: 1") != NULL){status = NB_Create_TCP("120.78.136.134", 9002);if(false == status){printf("重新创建TCP连接失败\n");return -1 ;}else{printf("重新创建TCP连接成功\n");}}return true ;}return false ;}
根据实现的发送函数,下面来实现驱动NB模块的接口以及整套初始化流程,可以减少开发者的负担。
在对NB模块的编程中,其实就是对串口操作,通常我们会有一个与模块的应答指令,寻问模块是否在线,进而来判断模块是否硬件是否已经连接正确或者模块是否损坏。
//检查模组是否在线bool checkNBIOT(void){return NBIOT_Cmd("AT", "OK", NULL, 100);}
当发出AT时,模组应给主机回复OK作为应答,这样主机就和模组建立通信。
根据前面写过的一篇文章,我们还要对BC28做一系列的适配操作,比如,使能自动寻网、设置频段(电信为5,移动为8)、打开优码控制选项第二项、第三项。
//NBIOT基础配置===>band 5 ==> 电信卡 8===>移动卡bool BASE_Config_NBIOT(int band){char buffer[50] = {0};bool status = true ;//设置频段sprintf(buffer, "AT+NBAND=%d", band);status = NBIOT_Cmd(buffer, "OK", NULL, 100);//自动寻网status = NBIOT_Cmd("AT+NCONFIG=AUTOCONNECT,TRUE", "OK", NULL, 100);//打开优码控制2,3项status = NBIOT_Cmd("AT+NCONFIG=CR_0354_0338_SCRAMBLING,TRUE", "OK", NULL, 100);status = NBIOT_Cmd("AT+NCONFIG=CR_0859_SI_AVOID,TRUE", "OK", NULL, 100);return status ;}
3.1 IMSI 设备识别码
NB模块或者其它的一些通信模块,它都会有一个独有的IMEI号,它是模块生产厂家指定的一个设备识别码,通过指令AT+CGSN=1来获取,功能函数如下:
bool Get_IMEI(void){bool status = true ;status = NBIOT_Cmd("AT+CGSN=1", "OK", "ERROR", 100);if(status == true){memcpy((char *)NBIOT_MODULE_INFO.IMEI, RXBuffer + 8, 15);return true ;}return false ;}
3.2 IMSI 国际移动用户识别码
通常该码存储在SIM卡中,我们可以使用AT+CIMI这条指令来获取,这样可以知道卡到底有没有插好或者是否存在,功能编写如下:
//获取IMSIbool Get_IMSI(void){bool status = true ;status = NBIOT_Cmd("AT+CIMI", "OK", "ERROR", 2000);if(status == true){memcpy((char *)NBIOT_MODULE_INFO.IMSI, RXBuffer + 2, 15);return true ;}return false ;}
模块注册相应的运行商成功,就会收到相应的标志,标志已经注册成功,功能编写如下:
//获取入网状态bool Get_Enter_Net_Status(void){int status = 0 ;bool cmd_status = false ;char buffer[30] = {0};cmd_status = NBIOT_Cmd("AT+CGATT?", "OK", "ERROR", 5000);memcpy(buffer, RXBuffer + 9, 1);status = atoi(buffer);if(1 == status)return true;elsereturn false ;}
BC28的模组信号级别是0-31,返回99则可能模块还没有初始化完毕,或者信号异常。低于10可以认为信号为低,一般别的通信模组(比如4G,WIFI等)如果低于这个级别,数据可能出现丢包状态,但NB模块号称只要大于8,即可无丢损数据,实现函数如下:
//获取信号强度int Get_CSQ(void){int signal_value = -1;bool status = true ;char csq_buffer[50] = {0};status = NBIOT_Cmd("AT+CSQ", "+CSQ", NULL, 100);if(status == true){memcpy(csq_buffer, RXBuffer + 7, 2);signal_value = atoi(csq_buffer);return signal_value ;}return 99 ;}
这里一定要注意一点,模组刷写的固件带ONT版本的,是不能把数据传到私有的服务器的,只有不带ONT的才可以,版本可以通过AT指令的ATI查看。
如果版本是带ONT,而你又想传数据到自己的后台,那就请你连接移远的FAE,提供最新的固件和固件烧写工具给你,如图所示,利用软件对NB模组进行固件更新。
//创建TCP Socket===>成功返回1,失败返回0u8 NB_Create_TCP(const char *server_ip, int port){char buffer[50] = {0};bool status = true ;//1.创建一个TCP Socketstatus = NBIOT_Cmd("AT+NSOCR=STREAM,6,56000,1", "OK", NULL, 2000);//如果创建成功,则连接远程服务器和端口号if(true == status){sprintf(buffer, "AT+NSOCO=1,%s,%d", server_ip, port);status = NBIOT_Cmd(buffer, "OK", NULL, 2000);if(true == status)return 1 ;elsereturn 0 ;}return 0 ;}//关闭Socket连接bool Close_Socket(void){bool status = true ;status = NBIOT_Cmd("AT+NSOCL=0", "OK", NULL, 2000);return status ;}
//NBIOT发送数据到后台服务器/*Data_Length:要发送到后台的原始数据的长度hex_data:要发送到后台的,但必须将原始数据转换成十六进制编码的数据*/bool NB_Send_Data_To_Server(int Data_Length, char *hex_data){bool status = true ;char data_buffer[1024] = {0};sprintf(data_buffer, "AT+NSOSD=1,%d,%s", Data_Length, hex_data);printf("数据上传:\n");printf("%s\n", data_buffer);status = NBIOT_Cmd(data_buffer, "OK", "ERROR", 5000);return status ;}
通常给模组复位,一般是设置完参数后,手册要求要进行复位操作,复位大概需要5s的时间,模组才会稳定下来,所以Delay_ms(5000)最好不要丢掉,否则其它的指令可能出现设置失败的情况。
//复位NBIOT模组bool NB_RESET(void){bool status = true ;status = NBIOT_Cmd("AT+NRB", "OK", NULL, 10000);return status ;}
/*** 功能:初始化NBIOT* 参数:None* 返回值:初始化结果,非0为初始化成功,0为失败*/int initNBIOT(void){bool status_return = false ;while(1){switch(NBIOT_MODULE_INFO.Init_NB_Status){//1、检查NBIOT模块是否在线case 0:status_return = checkNBIOT();if(false == checkNBIOT){printf("NB模块硬件故障..\n");return 0 ;}else{printf("NB模块正常连接\n");NBIOT_MODULE_INFO.Init_NB_Status = 1 ;}break ;//2、进行NBIOT的基础配置case 1:status_return = BASE_Config_NBIOT(5);if(false == status_return){NBIOT_MODULE_INFO.Init_NB_Status = 0 ;printf("配置自动寻网与优码控制第2、3项失败\n");}else{NBIOT_MODULE_INFO.Init_NB_Status = 2 ;printf("配置自动寻网与优码控制第2、3项成功\n");}break ;//3、复位模组case 2:status_return = NB_RESET();if(false == status_return){printf("模组复位失败\n");NBIOT_MODULE_INFO.Init_NB_Status = 0 ;}else{printf("模组复位成功\n");Delay_ms(2000);NBIOT_MODULE_INFO.Init_NB_Status = 3 ;}break ;//4、获取NB模组号case 3:status_return = Get_IMEI();if(false == status_return){printf("没有模组卡号,模块故障\n");NBIOT_MODULE_INFO.Init_NB_Status = 0 ;break ;}else{NBIOT_MODULE_INFO.Init_NB_Status = 4 ;printf("模组号:%s\n", NBIOT_MODULE_INFO.IMEI);}break ;//获取SIM卡卡号,确认设备是否已经插卡case 4:status_return = Get_IMSI();if(false == status_return){printf("没有插SIM卡,模块无法连接网络\n");NBIOT_MODULE_INFO.Init_NB_Status = 0 ;break ;}else{printf("SIM卡号:%s\n", NBIOT_MODULE_INFO.IMSI);NBIOT_MODULE_INFO.Init_NB_Status = 5 ;}break ;//查看注网状态case 5:status_return = Get_Enter_Net_Status();if(false == status_return){printf("入网失败,请重新复位模块\n");NBIOT_MODULE_INFO.Init_NB_Status = 5 ;break ;}else{printf("模组入网成功..\n");NBIOT_MODULE_INFO.Init_NB_Status = 6 ;}break ;//获取信号强度case 6:NBIOT_MODULE_INFO.signalCSQ = Get_CSQ();if(99 == NBIOT_MODULE_INFO.signalCSQ){printf("设备无信号....\n");NBIOT_MODULE_INFO.Init_NB_Status = 5 ;}else{printf("信号级别:%d\n", NBIOT_MODULE_INFO.signalCSQ);NBIOT_MODULE_INFO.Init_NB_Status = 7 ;}break ;default:break ;}if(7 == NBIOT_MODULE_INFO.Init_NB_Status){break ;}}return 1;}
免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!





