概述
1、A08版本软件域名解析很慢的情况
用A07版本做域名解析的时候发现很快,但是升级到A08版本,发现变得很慢,咨询原厂说是域名解析配置不对,A08默认是3gpp的epco,国内运营商的IE类型 是pco
通过这个指令配置
AT+NCONFIG=PCO_IE_TYPE,PCO
2、BC28模块会每隔1小时自己启动
通过长时间测试发现,模块会每隔1小时启动一次,导致让费电量。咨询原厂才发现是模块里面因为集成的华为平台连接功能,默认是打开的,需要关闭才行
指令
AT+QREGSWT=2
3、BC28 进入休眠的问题
BC28进入休眠的时候,通信串口的TX存在一个 0.03V的虚电压,这里会导致休眠后,电流为100多ua,并且还会漂移,所以在主控那里休眠后需要将这个口拉低就不存在电流漏电
4、BC28 连不上基站降低功耗的办法
由于板子上没有设计模块断电的电路,当模块连接不上基站的时候,模块还会一直去连接,导致功耗大的情况,这时可以在联网超时的时候发送如下指令,关闭模块搜索基站
"AT+COPS=2rn"
5、NB读卡问题
在调试的时候出现,有些卡能读的到的有些卡不能读到的情况,最好发现是卡槽的问,有些卡偏薄一点,导致卡槽关闭后还是接触不良。所以卡槽这块也需要注意
6、BC28驱动代码
/*********************************************
* @文件: driverBC28.c
* @作者: cjx
* @版本: v1.0.1
* @时间: 2020-02-21
* @概要: BC28 连接驱动
*********************************************/
#include "libraryAll.h"
#include "ioctrl.h"
#include "public.h"
/********************************************
基本宏定义区
*********************************************/
//IO宏定义
#define BC28_TX_PORT GPIO_PORT_1
#define BC28_TX_PIN GPIO_PIN_2
#define BC28_RX_PORT GPIO_PORT_1
#define BC28_RX_PIN GPIO_PIN_3
#define BC28_RST_PORT GPIO_PORT_2
#define BC28_RST_PIN GPIO_PIN_4
#define BC28_RST_EN() GPIO_SetActive(BC28_RST_PORT, BC28_RST_PIN)
#define BC28_RST_DI() GPIO_SetInactive(BC28_RST_PORT, BC28_RST_PIN)
//AT命令定义
#define AT "ATrn"
#define ATI "ATIrn"
#define AT_RST "AT+RSTrn"
#define AT_GMR "AT+CGMSrn" //获取软件版本
#define AT_CGSN "AT+CGSN=1rn" //获取IMEI
#define AT_CIMI "AT+CIMIrn" //获取IMSI
#define AT_ICCID "AT+NCCIDrn" //获取ICCID
#define AT_CGATT "AT+CGATT?rn" //查询网络附着
#define AT_CSQ "AT+CSQrn" //查询信号强度
#define AT_CGDCONT "AT+CGDCONT?rn" //查询APN
#define AT_CSCON "AT+CSCON=1rn" //开启nb连接状态打印
#define AT_CPSMS "AT+CPSMS=1,,,01001010,00000101rn" //修改PSM模式参数 TAU:100H act:10s
#define AT_QREGSWT "AT+QREGSWT=2rn" //关闭自启动
#define AT_NRB "AT+NRBrn" //模块复位
#define AT_COPS "AT+COPS=1,2,"46000"rn" //手动入网
#define AT_NPSMR "AT+NPSMR=1rn" //提示休眠状态
#define AT_PSM_GET "AT+CPSMS?rn"
#define AT_COPS_CLOSE "AT+COPS=2rn" //关闭网络
//其他定义
#define SOCKET_TYPE 'U'
//BC28 工作步骤
enum
{
E_BC28_STEP_INIT = 0, // 初始化步骤
E_BC28_STEP_SETUP, //基础设置
E_BC28_STEP_GET_INFO, //获取信息
E_BC28_STEP_CGATT, //查询网络附着
E_BC28_STEP_GET_NET_INFO, //查询网络信息
E_BC28_STEP_DNS, //域名解析
E_BC28_STEP_DNS_STATUS, //域名解析状态
E_BC28_STEP_FD, //创建套接字
E_BC28_STEP_FD_STATUS, //套接字状态
E_BC28_STEP_CONNECT, //连接服务器
E_BC28_STEP_CONNECT_STATUS, //连接状态
E_BC28_STEP_END,
};
/********************************************
基本数据区
*********************************************/
static struct{
T_U32 u32Step; //工作步骤
T_U32 u32Status; //工作状态
T_U32 u32BC28SleepFlg; //模块休眠状态 0:未休眠 1:休眠
T_U32 u32UartEn; //串口是否使能用的时候串口才使能,不用的时候设置成输入 0:非使能 1:使能
T_U8 u8RxCache[1];
}g_stThisCtl; //相应芯片的控制数据
static S_NBInfo g_stNBInfo ; //存储NB信息
static struct{
T_S8 s8Domain1[50]; //域名1
T_S8 s8Port1[10]; //端口1
T_S8 s8Domain2[50]; //域名2
T_S8 s8Port2[10]; //端口2
}g_stServerInfo; //存储服务器信息
static struct{
T_S8 s8IP1[20]; //IP1
T_S8 s8Fd1;
T_S8 s8IP2[20]; //IP2
T_S8 s8Fd2;
}g_stSocketInfo ; //socket信息
static T_U8 g_u8ServerData[NET_READ_CACHE_SIZE]; //接收缓冲
static T_S8 g_s8AtCache[300]; //AT指令缓存
static T_S8 g_s8SeverDataHead[30]; //服务器数据头
//应用层访问数据定义
static S_DriverDatas g_DriverDatas; //应用层读取数据
static T_U8 g_u8ReadDataCache[sizeof(S_DriverReadNet)]; //数据缓冲,根据实际需要定制大小
//static T_U8 g_u8NetStatus __attribute__((section("retention_mem_area0"), zero_init)); //这个变量要在休眠后保持
/********************************************
内部函数声明区
*********************************************/
static T_VOID _Pop(
T_U8 u8Type,
T_U8 *pu8Data,
T_U32 u32Len);
static T_VOID BC28_RxHandler(T_S8 *ps8Data, T_U32 u32Len);
static T_VOID BC28_Rst(T_VOID);
static void BC28_RxCb(uint8_t status);
//static void BC28_TxCb(uint8_t status);
static T_VOID BC28_StartRevData(T_S8 s8Fd);
/********************************************
自定义函数区
*********************************************/
/********************************************
串口操作函数
*********************************************/
//串口数据定义
static S_UartRx g_stUartRx; //串口接收数据,主要这个数据初始化后不要把数据地址清除了
static T_U8 g_u8RxCache[NET_READ_CACHE_SIZE]; //接收缓冲
/********************************************
*功能:串口接收数据
*输入:u8RxData: 接收的数据
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID UART_Rx(T_U8 u8RxData)
{
g_stUartRx.u8RxFlag = 1;
g_stUartRx.u32RxChkFullTime = 0;
//数据入缓冲,不要越界
if(g_stUartRx.u32RxLen < sizeof(g_u8RxCache))
{
g_stUartRx.pu8RxData[g_stUartRx.u32RxLen++] = u8RxData;
}
}
/********************************************
*功能:串口发生数据
*输入:pu8TxData: 发送的数据
u32Len: 发送的长度
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID UART_Tx(T_U8 *pu8TxData, T_U32 u32Len)
{
//uart2_write((uint8_t *)pu8TxData, u32Len, BC28_TxCb);
T_U32 u32i = 0;
for(u32i = 0; u32i < u32Len; u32i++)
{
uart2_txdata_setf(pu8TxData[u32i]);
while(0 == uart2_txfifo_full_getf());
uart2_thr_empty_setf(0);
}
}
/********************************************
*功能:串口接收数据清除
*输入:无
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID UART_RxClear(T_VOID)
{
g_stUartRx.u8RxFlag = 0;
g_stUartRx.u32RxLen = 0;
g_stUartRx.u32RxChkFullTime = 0;
}
/********************************************
*功能:串口接收任务
*输入:pvData: 任务数据
*输出:无
*条件:无
*返回:成功:RET_SUCCESS
失败:RET_FAILED
注意:
*********************************************/
static T_VOID UART_RxTaskHandler(T_VOID *pvData)
{
//接收数据处理部分
if(1 == g_stUartRx.u8RxFlag)
{
g_stUartRx.u32RxChkFullTime += UART_RX_TASK_PEOD;
if(g_stUartRx.u32RxChkFullTime >= UART_RX_FULL_TIME)
{
BC28_RxHandler((T_S8 *)g_stUartRx.pu8RxData, g_stUartRx.u32RxLen);
//接收完一条后清除数据
UART_RxClear();
}
}
MDL_DRVTIMER_Add(UART_RxTaskHandler, T_NULL, UART_RX_TASK_PEOD, 0);
}
/********************************************
*功能:串口初始化
*输入:无
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID UART_Init(T_VOID)
{
//引脚任务初始化
GPIO_ConfigurePin(BC28_TX_PORT, BC28_TX_PIN, OUTPUT, PID_UART2_TX, false);
GPIO_ConfigurePin(BC28_RX_PORT, BC28_RX_PIN, INPUT, PID_UART2_RX, false);
SetBits16(CLK_PER_REG, UART2_ENABLE, 1);
uart2_init(UART_BAUDRATE_9K6, UART_FRAC_BAUDRATE_9K6, UART_CHARFORMAT_8);
uart2_read((uint8_t *)g_stThisCtl.u8RxCache, 1, BC28_RxCb);
//数据清零并初始化
memset(&g_stUartRx, 0, sizeof(g_stUartRx));
memset(&g_u8RxCache, 0, sizeof(g_u8RxCache));
g_stUartRx.pu8RxData = g_u8RxCache; //指向缓存地址,其他地方不要再动这个变量
//接收任务启动
MDL_DRVTIMER_Add(UART_RxTaskHandler, T_NULL, UART_RX_TASK_PEOD, 0);
}
/********************************************
BC28 操作函数
*********************************************/
static void BC28_RxCb(uint8_t status)
{
UART_Rx(g_stThisCtl.u8RxCache[0]);
uart2_read((uint8_t *)g_stThisCtl.u8RxCache, 1, BC28_RxCb);
}
#if 0
static void BC28_TxCb(uint8_t status)
{
}
#endif
static T_VOID BC28_UARTConfInput(T_VOID)
{
GPIO_ConfigurePin(BC28_TX_PORT, BC28_TX_PIN, INPUT, PID_GPIO, false);
GPIO_ConfigurePin(BC28_RX_PORT, BC28_RX_PIN, INPUT, PID_GPIO, false);
g_stThisCtl.u32UartEn = 0;
}
static T_VOID BC28_UARTConfUart(T_VOID)
{
if(0 == g_stThisCtl.u32UartEn)
{
UART_Init();
g_stThisCtl.u32UartEn = 1;
}
}
/********************************************
*功能:串口发生数据
*输入:pu8TxData: 发送的数据
u32Len: 发送的长度
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID BC28_Tx(T_U8 *pu8TxData, T_U32 u32Len)
{
BC28_UARTConfUart();
if(g_stThisCtl.u32BC28SleepFlg)
{
//唤醒模块
UART_Tx(AT, sizeof(AT)-1);
g_stThisCtl.u32BC28SleepFlg = 0;
T_U32 u32Delay = 10000;
while(u32Delay--);
}
UART_Tx(pu8TxData, u32Len);
}
/********************************************
*功能:发送数据到服务器
*输入:pu8Buf: 发送的数据
u32Len: 发送的长度
*输出:无
*条件:无
*返回:无
注意:
*********************************************/
static T_VOID BC28_SendToSever(T_U8 *pu8Buf, T_U32 u32Len)
{
T_U32 u32Poi = 0;
if(E_NET_STATUS_SERVER_CONNECTED == g_stThisCtl.u32Status)
{
//发送到服务器1
if('