上一篇帖子我们通过阅读代码分析了原厂对于NodeMCU-BU01的初始化配置过程,通过USART中断入口函数定位到了AT指令解析运行及相对应的功能调用函数的具体实现;这篇帖子我们来看一下,这份功能代码是怎么一个测距流程的……
首先我们还是先看一下对应的AT指令功能调用函数的实现部分(仅与测距相关的部分):
1、AT+anchor_tag指令:这个AT指令的功能,是将当前的NodeMCU-BU01设置为基站还是标签模式,将设置数据写入到FLASH的USER_FLASH_BASE地址进行存储;
int AT_CmdFunc_ANCHOR_TAG(int opt,int argc, char *argv[])
{
//phy_printf("aliGenie set opt:%d\r\n",opt);
if(opt==EXECUTE_CMD)
{
uint16_t write=66;
FLASH_WriteMoreData(USER_FLASH_BASE,&write,1);
}
else if(opt==SET_CMD)
{
char *get=NULL;
get=strtok(argv[0],",");
uint16_t Set=atoi(get);
uint16_t write[3]={0};
if(Set==1)
{
//uint16_t write=1;
write[0]=1;
//FLASH_WriteMoreData(USER_FLASH_BASE,&write,1);
}
else if(Set==0)
{
write[0]=0;
//uint16_t write=0;
//FLASH_WriteMoreData(USER_FLASH_BASE,&write,1);
}
else
{
return -1;
}
get=NULL;
get=strtok(NULL,",");
Set=atoi(get);
if(Set>=0 && Set<=255)
{
write[1]=Set;
}
else
{
return -1;
}
FLASH_WriteMoreData(USER_FLASH_BASE,write,2);
}
else if(opt==QUERY_CMD)
{
uint16_t buff[3]={0};
FLASH_ReadMoreData(USER_FLASH_BASE,buff,3);
printf("buff0:%d\r\n",buff[0]);
printf("buff1:%d\r\n",buff[1]);
printf("buff2:%d\r\n",buff[2]);
}
return 1;
}
2、AT+interval指令:这个AT指令的功能是设定测距的间隔时间,单位是毫秒,设置值范围在5~50之间,而AT指令的参数,被赋值到ANCHOR_REFRESH_COUNT_set这个全局变量中进行存储;
int AT_CmdFunc_interval(int opt,int argc, char *argv[])
{
//phy_printf("aliGenie set opt:%d\r\n",opt);
if(opt==EXECUTE_CMD)
{
}
else if(opt==SET_CMD)
{
char *get=NULL;
get=strtok(argv[0],",");
uint16_t Set=atoi(get);
if(Set>=5&& Set<=50)
{
ANCHOR_REFRESH_COUNT_set=Set;
}
else
{
return -1;
}
}
else if(opt==QUERY_CMD)
{
}
return 1;
}
3、AT+switchdis指令:这个AT指令的功能就是控制测距的使能,控制开始进行测距和停止测距,而AT指令的设置参数被保存在SWITCH_DIS这个全局变量中;
int AT_CmdFunc_ondis(int opt,int argc, char *argv[])
{
//phy_printf("aliGenie set opt:%d\r\n",opt);
if(opt==EXECUTE_CMD)
{
}
else if(opt==SET_CMD)
{
char *get=NULL;
get=strtok(argv[0],",");
uint16_t Set=atoi(get);
if(Set==1)
{
SWITCH_DIS=1;
}
else if(Set==0)
{
SWITCH_DIS=0;
}
else
{
return -1;
}
}
else if(opt==QUERY_CMD)
{
}
return 1;
}
那测距过程,是如何通过这些AT指令来相互配合实现的呢?
首先,我们还是看MAIN函数的实现:在进行外设初始化完成后,接着对DW1000进行复位操作,在低SPI速率的情况下,对DWT进行初始化操作,等初始化完成后再提升SPI的通讯速率;然后就是配置DWT的设置参数;接着从FLASH中读取AT配置的工作模式,如果在没有配置的情况下,默认为基站模式;接下来就是根据工作模式来进行不同的函数调用;
int main(void)
{
uint8 anthor_index = 0;
uint8 tag_index = 0;
uint8 Semaphore_Enable = 0 ;
uint8 Waiting_TAG_Release_Semaphore = 0;
int8 frame_len = 0;
//lable1:
/* Start with board specific hardware init. */
peripherals_init();
printf("hello dwm1000!\r\n");
/* Reset and initialise DW1000.
* For initialisation, DW1000 clocks must be temporarily set to crystal speed. After initialisation SPI rate can be increased for optimum
* performance. */
reset_DW1000(); /* Target specific drive of RSTn line into DW1000 low for a period. */
spi_set_rate_low();
if(dwt_initialise(DWT_LOADUCODE) == -1)
{
printf("dwm1000 init fail!\r\n");
OLED_ShowString(0,0,"INIT FAIL");
while (1)
{
//STM_EVAL_LEDOn(LED1);
GPIO_SetBits(GPIOC,GPIO_Pin_13);
deca_sleep(1000);
//STM_EVAL_LEDOff(LED1);
GPIO_ResetBits(GPIOC,GPIO_Pin_13);
deca_sleep(1000);
}
}
spi_set_rate_high();
/* Configure DW1000. See NOTE 6 below. */
dwt_configure(&config);
dwt_setleds(1);
/* Apply default antenna delay value. See NOTE 1 below. */
dwt_setrxantennadelay(RX_ANT_DLY);
dwt_settxantennadelay(TX_ANT_DLY);
OLED_ShowString(0,0,"INIT PASS");
printf("init pass!\r\n");
printf("AIT-BU01-DB V100 T2020-5-17\r\n");
AnchorList[0].x =0.12;
AnchorList[0].y =0.34;
AnchorList[0].z =0;
AnchorList[1].x =0.25;
AnchorList[1].y =0;
AnchorList[1].z =0;
AnchorList[2].x =0;
AnchorList[2].y =0;
AnchorList[2].z =0;
int rx_ant_delay =32880;
int index = 0 ;
extern UserSet UserSetNow;
uint16_t buff[3]={1,0,0xff};//ĬèÏÖμ
FLASH_ReadMoreData(USER_FLASH_BASE,buff,3);
if(buff[0]==1)
{
UserSetNow.ANCHOR_TAG=1;
}
else if(buff[0]==0)
{
UserSetNow.ANCHOR_TAG=0;
}
else
{
UserSetNow.ANCHOR_TAG=1;
}
//#ifdef ANTHOR
if(UserSetNow.ANCHOR_TAG==1)
{
if(buff[1]>=0 && buff[1]<=255)
{
UserSetNow.ID=buff[1];
ANCHOR_IND=UserSetNow.ID;
}
printf("device:anchor ID:%d\r\n",ANCHOR_IND);
Anchor_Array_Init();
/* Loop forever initiating ranging exchanges. */
OLED_ShowString(0,0,"DS TWR ANTHOR");
//OLED_ShowString(0,2,"Distance:");
//KalMan_PramInit();
ANTHOR_MEASURE();
}
//#endif
//#ifdef TAG
if(UserSetNow.ANCHOR_TAG==0)
{
if(buff[1]>=0 && buff[1]<=255)
{
UserSetNow.ID=buff[1];
TAG_ID=UserSetNow.ID;
MASTER_TAG=TAG_ID;
}
printf("device:TAG ID:%d\r\n",UserSetNow.ID);
if(TAG_ID == MASTER_TAG)
{
OLED_ShowString(0,0,"DS MASTER TAG:");
}
else
{
OLED_ShowString(0,0,"DS SLAVE TAG:");
}
/* Set expected response's delay and timeout. See NOTE 4 and 5 below.
* As this example only handles one incoming frame with always the same delay and timeout, those values can be set here once for all. */
dwt_setrxaftertxdelay(POLL_TX_TO_RESP_RX_DLY_UUS);
dwt_setrxtimeout(RESP_RX_TIMEOUT_UUS);
//OLED_ShowString(0,2,"Distance:"); chnage by johhn
if(TAG_ID == MASTER_TAG)
{
Semaphore_Enable = 1 ;
Semaphore_Init();
Waiting_TAG_Release_Semaphore = 0;
}
else
{
Semaphore_Enable = 0 ;
}
//Master TAG0
TAG_MEASURE();
}
//#endif
}
在基站模式下,程序中通过OLED在其显示“DS TWR ANTHOR”信息,通过调用ANTHOR_MEASURE函数来完成具体的功能;
在标签模式下,程序中根据当前TAG_ID的主从通过OLED在其显示“DS MASTER TAG”或者“DS SLAVE TAG”信息,通过调用TAG_MEASURE函数来写成具体的功能;
而TAG_MEASURE和ANTHOR_MEASURE这两个函数在整个工程文件中,只在lib.h中进行了声明,也没有具体的实现……所以这函数具体实现的代码是被封装了STM3210E-EVAL.lib这个库文件里了吗?那么我想把这个UWB功能移植到其它的MCU平台,该怎么来实现或者操作呢?感觉又被卡住了……