MCU向CH9141发送AT指令

目录

沁恒的BLE模块CH914x系列中,CH9141和CH9343支持通过UART串口识别AT指令。注意CH9140不支持AT指令。使用电脑作为上位机时,各类串口助手可以提供保存和发送自定义字符串的功能,不过很多应用场景下都是通过板子上另一片MCU来为BLE透传模块配置AT指令。以下提供帮助MCU快速使用9141和9143。

本文以CH9141手册中的AT命令为准,整理一份二维数组,可按需增补删改。

const uint8_t ATCMD_STD[4][4] = {           //标准指令前后缀
"AT+",
"?\r\n",
"=",
"\r\n",
};


const uint8_t ATCMD_9141[52][10] = {        //51条指令
"",
"AT...",    //序号1      //进AT配置模式
"RESET",
"VER",                  //获取芯片版本号
"HELLO",
"RELOAD",   //序号5
"SHOW",
"SAVE",
"EXIT",                 //退出AT配置模式
"GPIO",
"INITIO",   //序号10
"UART",
"MAC",
"TPL",
"BLESTA",
"DISCONN",         //序号15
"BLEMODE",
"CCADD",
"NAME",
"PNAME",
"PASEN",         //序号20
"PASS",
"SYSID",
"MODNAME",
"SERINUM",
"FIRMREV",         //序号25
"HARDREV",
"SOFTREV",
"MANUNAME",
"PNPID",
"ADVEN",         //序号30
"ADVDAT",
"LINK",
"CONN",
"SCAN",
"CONADD",       //序号35
"CLRCONADD",
"RSSI",
"ADC",
"SLEEP",
"BAT",          //序号40
"BDSP",
"BLECFGEN",
"BCCH",
"ADVINTER",
"CONNINTER",    //序号45
"LSICALI",
"RFCALI",
"TNOW",
"BSTA",
"AFEC",             //序号50
"IOEN",
};

当然也可以把“AT+”放在ATCMD_9141[]数组中,不过数组的大小就要配置为52x13,多占用一百多个字节。

在发出指令前,可以利用sprintf库函数,将多个字符串按顺序拼接到一起。调用strcat或其他函数做拼接均可,不过考虑到sprintf可以将十进制数据添加到字符串中,还是使用sprintf好了。

将三串字符串拼接到TxBuff中,再通过打印函数或者串口输出,可以得到期望的字符串,最后清空一下TxBuff以便下次使用:

        sprintf(TxBuff, "%s%s%s", ATCMD_STD[0], ATCMD_9141[8], ATCMD_STD[3]);  
        PRINT("%s", TxBuff);                                
        memset(TxBuff, 0, sizeof(TxBuff));                  

为了方便使用,可以再封装一层宏定义,调用起来更方便。

//PRINT()即printf()
#define ENTER_AT_CFG  \
{    \
        sprintf(TxBuff, "%s%s", ATCMD_9141[1], ATCMD_STD[3]);  \
        PRINT("%s", TxBuff);                                \
        memset(TxBuff, 0, sizeof(TxBuff));                  \
}   //进入AT配置模式

#define EXIT_AT_CFG  \
{    \
        sprintf(TxBuff, "%s%s%s", ATCMD_STD[0], ATCMD_9141[8], ATCMD_STD[3]);  \
        PRINT("%s", TxBuff);                                \
        memset(TxBuff, 0, sizeof(TxBuff));                  \
}   //退出AT配置模式

#define COMMAND_AT(MACRO_X)  \
{    \
        sprintf(TxBuff, "%s%s%s", ATCMD_STD[0], (MACRO_X), ATCMD_STD[3]);  \
        PRINT("%s", TxBuff);                                \
        memset(TxBuff, 0, sizeof(TxBuff));                  \
}   //不带问号(即AT+X?格式),不带配置参数(即AT+X=n格式)的指令

#define QUERY_AT(MACRO_X)  \
{    \
        sprintf(TxBuff, "%s%s%s", ATCMD_STD[0], (MACRO_X), ATCMD_STD[1]);  \
        PRINT("%s", TxBuff);                                \
        memset(TxBuff, 0, sizeof(TxBuff));                  \
}   //带问号的查询指令

#define SET_STR_AT(MACRO_X1, MACRO_X2)  \
{    \
        sprintf(TxBuff, "%s%s%s%s%s", ATCMD_STD[0], (MACRO_X1), ATCMD_STD[2], (MACRO_X2), ATCMD_STD[3]);  \
        PRINT("%s", TxBuff);                                \
        memset(TxBuff, 0, sizeof(TxBuff));                  \
}   //需要配置字符串的命令,比如开/关广播、设置厂商名称等指令

#define SET_NUM_AT(MACRO_X1, MACRO_X2)  \
{    \
        sprintf(TxBuff, "%s%s%s%d%s", ATCMD_STD[0], (MACRO_X1), ATCMD_STD[2], (MACRO_X2), ATCMD_STD[3]);  \
        PRINT("%s", TxBuff);                                \
        memset(TxBuff, 0, sizeof(TxBuff));                  \
}   //需要配置十进制数字的命令,比如设置发射功率等指令


/*以下为函数中的调用代码*/
    ENTER_AT_CFG;
    DelayMs(500);

    COMMAND_AT(ATCMD_9141[3]);
    DelayMs(500);

    QUERY_AT(ATCMD_9141[4]);
    DelayMs(500);

    SET_STR_AT(ATCMD_9141[30], "OFF");
    DelayMs(500);

    SET_NUM_AT(ATCMD_9141[13], 3);
    DelayMs(500);

    EXIT_AT_CFG;
    DelayMs(500);

以上宏只涵盖了部分指令。有个别指令比较长,比如配置波特率、奇偶校验位等参数的一串指令;还有部分指令格式比较特殊,比如配置GPIO的指令,这些需要再自行封装,或者写变参数的函数/宏去封装,调用起来更方便。

代码中没有判断CH9141是否回复了“OK\r\n”,实际使用中需要确认CH9141收到指令后再发下一条指令。

posted @ 2023-05-12 14:27  JayWell  阅读(509)  评论(0编辑  收藏  举报