單片機實現AT調試命令分享


單片機實現AT調試命令

實現目的

對於日常開發過程,我們經常需要借助串口調試設備,所以增加調試指令並且易於擴展是有必要的

思路

1、串口使用中斷接收用戶參數到接收緩沖區,定義0x0d作為結束標志
2、調用命令類型解析回調函數AT_DeviceHandle,對命令消息進行分流,然后進入指令類型解析函數
3、再指令解析函數里面對指令進行分流,分別處理對應的指令以及使用相關參數

關鍵實現代碼

// 指令類型處理函數
static int OnCfgDebug(uint32_t vp_Type, uint32_t vp_P1, uint32_t vp_P2, uint32_t vp_P3)
{
	p_info("info:OnCfgDebug:Type=%d,P1=%d,P2=%d,P3=%d.", vp_Type, vp_P1, vp_P2, vp_P3);
	
	switch(vp_Type)
	{
		case 1:
		{
			gTickS = 0;
 			gTickMs = 0;
			StopTimer(1);
			gOpenTime = vp_P1;
			gCloseTime = vp_P2;
			StartTimer(1);
			SaveParamToFlash();
			p_dbg("OK");
			break;
		}
		default:
			p_info("warn:PARAM INVALID!");
			break;
	}
	
	return 0;
}

// 格式:AT+cmdCfg=vl_CmdId,vl_Type,vl_P1,vl_P2,vl_P3
// vl_CmdId:命令ID
// vl_Type:指令類型
// vl_P1,vl_P2,vl_P3:指令參數
// 例如:AT+cmdCfg=103,1,1,2,3
static int AT_DeviceHandle(const unsigned char *data_buf)
{
	count = 0;
	
	uint32_t i, vl_CmdId, vl_Type, vl_P1, vl_P2, vl_P3;
	uint32_t nlen = strlen((const char *)data_buf);
	char vl_FormateStr[64]; // 格式化緩沖區
	
	vl_CmdId = 0;
	vl_Type = 0;
	vl_P1 = 0;
	vl_P2 = 0;
	vl_P3 = 0;
	
        // 至少有一個'='
	if(!strstr((const char *)data_buf, "="))
		goto RETURN;

	memset(vl_FormateStr, 0, sizeof(vl_FormateStr)/sizeof(vl_FormateStr[0]));
	memcpy(vl_FormateStr, "AT+cmdCfg=%d", strlen("AT+cmdCfg=%d"));
	
	for (i = 0; i < nlen; i++)
	{
		if ((',' == data_buf[i]) && (i < nlen - 1))
			memcpy(vl_FormateStr + strlen(vl_FormateStr), ",%d", strlen(",%d"));
	}
	sscanf((const char *)data_buf, vl_FormateStr, &vl_CmdId, 
		&vl_Type, &vl_P1, &vl_P2, vl_P3);
	
	memset((char *)data_buf, 0, nlen);
	
	p_dbg("vl_CmdId=%d, vl_Type=%d, vl_P1=%d, vl_P2=%d, vl_P3=%d", vl_CmdId, vl_Type, vl_P1, vl_P2, vl_P3);
	if (TIME_CFG_CMD == vl_CmdId)
		return OnCfgDebug(vl_Type, vl_P1, vl_P2, vl_P3);
RETURN:
	return -1;
}

擴展時,只需要增加消息類型以及對應的指令即可,參數目前默認支持3個,可自行擴展,以及定義數據結構來管理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM