硬件:正点原子战舰V3
蓝牙模块BT04(HC-05也一样的,不过指令不一样)
USB转TTL模块
软件:XCOM串口调试助手(PC)
蓝牙调试宝(安卓平台)
昨晚调试蓝牙模块,这个蓝牙模块因为只需要连接串口就可以正常工作,应该来说比较简单。但是还是遇到一个小问题,找了很久的原因,调试了很长时间。
我想要测试的功能是利用手机APP发送命令控制LED灯,下面是主函数:
int main(void)
{
u16 t;
u16 len;
u16 times=0;
delay_init();
LED_Init();
KEY_Init();
USART_Config();
while(1)
{
if(USART_RX_STA&0x8000)
{
switch(USART_RX_BUF[0])
{
case('A'):
Send_data(DEBUG_USARTx,"首位为A,LED1亮\r\n");
LED0=1;
LED1=0;
break;
case('B'):
Send_data(DEBUG_USARTx,"首位为B,LED0亮\r\n");
LED0=0;
LED1=1;
break;
}
USART_RX_STA=0;
}
}
}
我的想法是,命令中第一位字符为“A”则LED1亮,LED0灭,第一位字符为B则相反。
这里我用的是中断接收函数,我最开始使用的是正点原子一样的函数直接搬过来,使用PC端的串口调试助手使用USB转TTL模块调试可以正常工作,但是当我利用蓝牙模块连接到手机发送命令无法正常工作,下面是正点原子的中断服务函数:
void DEBUG_USART_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
if(USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
{
Res =USART_ReceiveData(DEBUG_USARTx); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(USART_RX_STA&0x4000)//接收到了0x0d
{
if(Res!='D')USART_RX_STA=0;//接收错误,重新开始
else {USART_RX_STA|=0x8000;//接收完成了
Send_data(DEBUG_USARTx,"完成一次传输\r\n");
}
}
else //还没收到0X0D
{
if(Res=='+')USART_RX_STA|=0x8000;
else
{
Send_data(DEBUG_USARTx,"写入缓冲\r\n");
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收
}
}
}
}
}
后来找了很多原因也找不到,最后发现是因为这个中断函数接受的数据要求0x0a 0x0d结束,电脑串口助手发送新行会发送这两个字符,但是按说换行符只有一个0x0a,没有0x0d,所以无法接收到正确的命令。感谢这位大哥。
后面改了程序,把示意命令结束的符号设置为“+”,这样在PC和安卓端都能正常发出命令。
void DEBUG_USART_IRQHandler(void) //串口1中断服务程序
{
u8 Res;
if(USART_GetITStatus(DEBUG_USARTx, USART_IT_RXNE) != RESET)
{
Res =USART_ReceiveData(DEBUG_USARTx); //读取接收到的数据
if((USART_RX_STA&0x8000)==0)//接收未完成
{
if(Res=='+')USART_RX_STA|=0x8000;
else
{
// Send_data(DEBUG_USARTx,"写入缓冲\r\n");
USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
}
}
}
}
后记
在调试蓝牙时,发现有些app不能搜到我这个蓝牙模块,试了好几个才找到这个蓝牙调试宝可以,虽然有广告,但至少能用TAT.