#采用stm32f103c8t6芯片
基础的服务函数写完了,接下来开始联合调试了。在整合篇第一章中,我将会进行蓝牙模块更加进一步的编写,其中包括传输红外传感器数据,pid调试部分代码。不过可惜的是,考虑到加入速度传感器会比较大程度的增加代码编写复杂性,且速度传感器为非必要,所以我并不打算在最终的项目中使用速度传感器。算是比较可惜的一点。
先说一下app inventor吧,app inventor是MIT运营的一款图形画app开发程序,可以用来开发安卓app,适合没有安卓开发经验的项目开发者的轻度使用。我使用的是基于app inventor的增强版WxBit,其具有在线调试功能,相对原版会更加方便一些。
我的一些蓝牙模块开发经验来源于:https://blog.csdn.net/qq_40515692/article/details/80894253,这里面比较详细的阐述了蓝牙app如何开发,同时我还推荐以下b站的https://www.bilibili.com/video/BV1Cy4y1h7ma视频,视频篇幅较短,可以让初学者快速地上手蓝牙app开发。
在开发过程中,最需要注意的便是蓝牙的接收了,这一点困扰了我许久。app inventor的蓝牙接收与单片机的蓝牙接收不同,其没有接收到蓝牙信号便触发中断的选项,因此只能由定时器定时,到达给定时间后查询蓝牙信号。
这也是最坑的地方,也就是说,app inventor无法不定时接收蓝牙信号,只能以确定时间接收蓝牙信号。我就是在这里被困扰许久。对于此,比较好的解决办法就是定时器到达确定时间后,由手机主动发出查询信号后进入接收模式,单片机接收到信号进入中断以后,返回查询值,这样子才可以确保app不会出错。
同时还需要注意的一点是,进入定时器后最好先进行蓝牙是否连接的判断,能更好的防止app出错。
前置知识已经说完了,接下来开始写代码。从简单开始。
else if (data_in_flag == infrared1)
{
USART_SendData(BLUETOOTH_Usart, INFRARED1_input);
}
else if (data_in_flag == infrared2)
{
USART_SendData(BLUETOOTH_Usart, INFRARED2_input);
}
else if (data_in_flag == infrared3)
{
USART_SendData(BLUETOOTH_Usart, INFRARED3_input);
}
else if (data_in_flag == infrared4)
{
USART_SendData(BLUETOOTH_Usart, INFRARED4_input);
}
这部分代码是和之前红外进行的联合调试,当app发送信号时,单片机进入中断并返回信号。
经过测试,可以正常使用。
接下来开始尝试调节pid。首先在主函数定义全局变量p、i、d。
接收思路为,首先接收相应标志位,然后接收多位直到接收到停止标志位。这里需要考虑的一个问题是,串口每接收一位就会进入一次中断服务函数,我在中断服务函数写了对于接收到不同标志位的判断。但是,问题是,我在接收数据时接收的是数字,而不是标志位,我怎么在未完成接收前每一次中断都进入到pid接收的条件分支呢?
这里我多使用了一个标志位,即两个标志位同时操控。我们设这两个标志位为p,q。在接收到pid接收的标志p后,将q设置为非零的某一个数。进入下一次中断后,先检测标志位q是否为非零,若为非零,将p设置为进入pid条件分支的相应标志,直至接收到结束接收的标志位,这一过程一直循环。结束接收后,将q设置为零,这样p就可以正常接收到从串口读来的数据,从而进入不同的功能条件分支。
当然,这里面还涉及到了将每一位数按照个十百叠加在一起的算法,但这个在读者初学c语言时肯定写过类似的程序,在这里就不赘述了。接下来上中断服务函数的代码吧。
#串口中断服务函数
void USART2_IRQHandler(void)
{
if (USART_GetITStatus(BLUETOOTH_Usart, USART_IT_RXNE))
{
if (data_in_flag1 != start_transmit)
data_in_flag = USART_ReceiveData(BLUETOOTH_Usart);
if (data_in_flag == move_forward)
{
CarControl(MOTORA, 3000);
CarControl(MOTORB, 3000);
}
else if (data_in_flag == move_left)
{
CarControl(MOTORA, 0);
CarControl(MOTORB, 3000);
}
else if (data_in_flag == move_right)
{
CarControl(MOTORA, 3000);
CarControl(MOTORB, 0);
}
else if (data_in_flag == move_back)
{
CarControl(MOTORA, -2000);
CarControl(MOTORB, -2000);
}
else if (data_in_flag == move_stop)
{
CarControl(MOTORA, 0);
CarControl(MOTORB, 0);
}
else if (data_in_flag == infrared1)
{
USART_SendData(BLUETOOTH_Usart, INFRARED1_input);
}
else if (data_in_flag == infrared2)
{
USART_SendData(BLUETOOTH_Usart, INFRARED2_input);
}
else if (data_in_flag == infrared3)
{
USART_SendData(BLUETOOTH_Usart, INFRARED3_input);
}
else if (data_in_flag == infrared4)
{
USART_SendData(BLUETOOTH_Usart, INFRARED4_input);
}
else if (data_in_flag == change_p)
{
if (data_in_flag1 == start_transmit)temp_data = USART_ReceiveData(BLUETOOTH_Usart);
data_in_flag1 = start_transmit;
if (temp_data != stop_transmit)
{
receive_data[receive_count] = temp_data;
receive_count++;
if (receive_count >= 5)receive_count = 5;
}
else
{
data_in_flag1 = 0;
receive_count--;
temp_data = 0;
for (; receive_count > 0; receive_count--)
{
temp_data = receive_data[receive_count] + temp_data*10;
}
P_control = temp_data;
temp_data = 0;
receive_count = 0;
}
}
else if (data_in_flag == change_I)
{
if (data_in_flag1 == start_transmit)temp_data = USART_ReceiveData(BLUETOOTH_Usart);
data_in_flag1 = start_transmit;
if (temp_data != stop_transmit)
{
receive_data[receive_count] = temp_data;
receive_count++;
if (receive_count >= 5)receive_count = 5;
}
else
{
data_in_flag1 = 0;
receive_count--;
temp_data = 0;
for (; receive_count > 0; receive_count--)
{
temp_data = receive_data[receive_count] + temp_data*10;
}
I_control = temp_data;
temp_data = 0;
receive_count = 0;
}
}
else if (data_in_flag == change_d)
{
if (data_in_flag1 == start_transmit)temp_data = USART_ReceiveData(BLUETOOTH_Usart);
data_in_flag1 = start_transmit;
if (temp_data != stop_transmit)
{
receive_data[receive_count] = temp_data;
receive_count++;
if (receive_count >= 5)receive_count = 5;
}
else
{
data_in_flag1 = 0;
receive_count--;
temp_data = 0;
for (; receive_count > 0; receive_count--)
{
temp_data = receive_data[receive_count] + temp_data*10;
}
D_control = temp_data;
temp_data = 0;
receive_count = 0;
}
}
}
}
好了,蓝牙与小车代码的整合到这里就结束了!下一次就是巡线逻辑的编写了。让我们尽情期待吧!