
首先是非常幸运的得到了这款毫米波雷达模块,之前也断断续续研究了一下,今天才弄完发出了。本来想着使用一个蓝牙模块对雷达模块进行参数的设置等,并在手机端显示出模块当前的一个输出参数等。但毫米波雷达模块输出的信息蓝牙串口只能接收很短的时间然后系统就死机了,也不清楚是因为什么,懂的朋友可以在评论区交流。最后就稍稍的缩减了一下功能。
这款毫米波雷达模块采用的是串口通信方式,具体的通信方式如下:
配置模块参数的时候和蓝牙于WIFI的AT指令模式差不多。这款雷达模块有两种工作模式一是测试模式二是正常的工作模式。在测试模式下,模块不仅会输出当前目标的运动幅度还会输出信号强度str的值。
通过串口助手向模块发送“test_mode=1”模块进入测试模式,模块默认“test_mode=0”正常模式,如AT测试指令相同,发送时选择发送新行,并在指令的结尾带一个回车。
模块的其他指令如下:
在设置完参数之后要发送“save”保存命令,否则设置的参数不会生效。
最为重要和关键的一个参数就是这个灵敏度的阈值,阈值的设置可以根据不同状态下测试模式模块输出的信号强度str值来设置。即无人状态、静止或者小幅运动状态、大幅运动状态。
当str的值小于最小灵敏度阈值时模块就会输出无人状态,
当str的值大于最小灵敏度阈值小于最大灵敏度阈值时模块就会输出静止或者小幅运动状态,
当str的值大于最大灵敏度阈值时模块就会输出大幅运动状态,
自己在设置测试的时候不知是不是宿舍环境太复杂还是模块对的的太准还是其他原因,输出的状态不太稳定,或对于目标状态的检测太过于灵敏。
接下来就是程序部分:
程序还是比较简单的,只使用到了串口,再对串口接收到的数据加以处理再通过另外一个串口输出到上位机就行了。
使用的是串口3资源
串口初始化函数:
/初始化IO 串口3
//pclk1:PCLK1时钟频率(Mhz)
//bound:波特率
void CEM5825F_Init()
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); // GPIOB时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE); //串口3时钟使能
USART_DeInit(USART3); //复位串口3
//USART3_TX PB10
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB10
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB10
//USART3_RX PB11
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOB, &GPIO_InitStructure); //初始化PB11
USART_InitStructure.USART_BaudRate = 115200;//波特率一般设置为115200,使用模块默认的波特率;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART3, &USART_InitStructure); //初始化串口 3
USART_Cmd(USART3, ENABLE); //使能串口
//使能接收中断
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//开启中断
//设置中断优先级
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
TIM7_Int_Init(99,7199); //10ms中断
USART3_RX_STA=0; //清零
TIM_Cmd(TIM7,DISABLE); //关闭定时器7
}
串口3中断服务函数
void USART3_IRQHandler(void)
{
u8 res;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)//接收到数据
{
res =USART_ReceiveData(USART3);
if((USART3_RX_STA&(1<<15))==0)//接收完的一批数据,还没有被处理,则不再接收其他数据
{
if(USART3_RX_STA<USART3_MAX_RECV_LEN) //还可以接收数据
{
TIM_SetCounter(TIM7,0);//计数器清空 //计数器清空
if(USART3_RX_STA==0) //使能定时器7的中断
{
TIM_Cmd(TIM7,ENABLE);//使能定时器7
}
USART3_RX_BUF[USART3_RX_STA++]=res; //记录接收到的值
}else
{
USART3_RX_STA|=1<<15; //强制标记接收完成
}
}
}
}
重定义printf函数,向雷达模块写命令;
//串口3,printf 函数
//确保一次发送数据不超过USART3_MAX_SEND_LEN字节
//发送指令结尾加上结束符
void u3_printf(char* fmt,...)
{
u16 i,j;
va_list ap;
va_start(ap,fmt);
vsprintf((char*)USART3_TX_BUF,fmt,ap);
va_end(ap);
i=strlen((const char*)USART3_TX_BUF); //此次发送数据的长度
for(j=0;j<i;j++) //循环发送数据
{
while(USART_GetFlagStatus(USART3,USART_FLAG_TC)==RESET); //循环发送,直到发送完毕
USART_SendData(USART3,USART3_TX_BUF[j]);
}
}
雷达模块写命令,并且将应答输出至上位机的串口助手。
void CEM5825F_CMD(u8 *str)
{
u8 temp;
u8 t;
delay_ms(10);
u3_printf("%s\r\n",(char*)str); //发送指令
for(t=0;t<50;t++) //最长等待500ms,来接收HC05模块的回应
{
if(USART3_RX_STA&0X8000)break;
delay_ms(10);
}
if(USART3_RX_STA&0X8000) //接收到一次数据了
{
temp=USART3_RX_STA&0X7FFF; //得到数据长度
USART3_RX_STA=0;
USART3_RX_BUF[temp]=0; //加结束符
printf("\r\n%s",USART3_RX_BUF);//发送回应数据到串口1
}
}
主函数
int main()
{
SysTick_Init(72);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中断优先级分组 分2组
LED_Init();
USART1_Init(115200);
CEM5825F_Init();
CEM5825F_CMD("get_all");
while(1)
{
u16 i;
u32 temp;
if(USART3_RX_STA&0X8000) //接收到一次数据了
{
temp=USART3_RX_STA&0X7FFF; //得到数据长度
USART3_RX_STA=0;
USART3_RX_BUF[temp]=0; //加结束符
if(USART3_RX_BUF[0] == 'o')
{
printf("当前状态为静止");
}
else if(USART3_RX_BUF[0] == 'm')
{
printf("当前状态为运动");
}
printf("%s",USART3_RX_BUF);//发送回应数据到串口1
}
if(i%10 == 0)
{
led1=!led1;
}
i++;
delay_ms(10);
}
}
完整的工程放在了附件,还有完整版的雷达模块的数据手册,有需要的自行下载。
ps:工程当中有自己写了一半的蓝牙控制函数,感兴趣有能力的可以试着完成一下,不需要的直接删了就好。
全部评论