我會通過本系列文章,詳細介紹如何從零開始用51單片機去實現智能小車的控制,在本系列的上一篇文章中介紹瞭如何通過手機藍牙去控制智能小車,但是存在加減速指令異常的錯誤,本文主要介紹出現錯誤的原因,及改正方法。
本系列文章鏈接:
-----------------------------------------------------------------------------
詳細介紹如何從零開始製作51單片機控制的智能小車(一)———讓小車動起來
詳細介紹如何從零開始製作51單片機控制的智能小車(二)———超聲波模塊、漫反射光電管、4路紅外傳感器的介紹和使用
詳細介紹如何從零開始製作51單片機控制的智能小車(三)———用超聲波模塊和漫反射光電傳感器實現小車的自動避障
詳細介紹如何從零開始製作51單片機控制的智能小車(四)———通過藍牙模塊實現數據傳輸以及通過手機藍牙實現對小車運動狀態的控制
詳細介紹如何從零開始製作51單片機控制的智能小車(五)———對本系列第四篇文章介紹的手機藍牙遙控加減速異常的錯誤的介紹及糾正
-----------------------------------------------------------------------------
1、原因一 :由HC-COM所帶來的錯誤
原因之一是HC-COM這個app的問題,他一下發送的是20個數,初始階段設定爲最大車速的50%,按程序來說是每收到一個5(加速指令),車速增加10%,每收到一個6(減速指令)車速減少10%,但是我們在用HC-COM輸入一個5或者6的時候發送給單片機的時候,它實際上接收到的是20個5或者20個6,相當於執行了20次車速增加10%,或者減少10%,由於加減速在程序中進行了限幅,會加速到車速的最大值,和最小值,最小值車速爲0。
2、對錯誤原因一 的糾正方法
通過修改加減速函數來糾正,原來的加減速函數如下:
void Speed_add() //加速函數
{
if(Left_Speed_Ratio<10) //限幅
{
Left_Speed_Ratio++;
Right_Speed_Ratio++;
}
}
void Speed_reduce() //減速函數
{
if(Left_Speed_Ratio>0) //限幅
{
Left_Speed_Ratio--;
Right_Speed_Ratio--;
}
}
我們通過設定一個累加的靜態變量來糾正,糾正後的加減速函數如下:
void Speed_add() //加速函數
{
static int i=0;
i=i+1;
if(i==20) //因爲每次接收到的是20個加速信號,這樣就是每接收到20個加速信號,也就是每發送一個5,增加最大車速的10%
{ //將20這個常量就可以調節每次 增速的大小,比如把20改爲10,則每發送一個5,增加最大車速的20%
i=0;
if(Left_Speed_Ratio<10)
{
Left_Speed_Ratio++;
Right_Speed_Ratio++;
}
}
}
void Speed_reduce() //減速函數
{
static int j=0;
j=j+1;
if(j==20) //因爲每次接收到的是20個減速信號,這樣就是每接收到20個減速信號,也就是每發送一個5,減小最大車速的10%
{ //將20這個常量就可以調節每次 減速的大小,比如把20改爲10,則每發送一個5,減小最大車速的20%
j=0;
if(Left_Speed_Ratio>0)
{
Left_Speed_Ratio--;
Right_Speed_Ratio--;
}
}
}
3、原因二 :由while(1)循環所帶來的錯誤
在進行了以上的修正後發現,問題還是沒有得到解決,出錯的原因之二是while(1)循環帶來的,當我們通過手機藍牙發送指令之後,在下一次發送之前receive_real_data的值將不再改變,原來主函數中的控制指令如下:
switch(receive_real_data)
{
case '1': run(); break;
case '2': left(); break;
case '3': right(); break;
case '4': back(); break;
case '5': Speed_add(); break;
case '6': Speed_reduce(); break;
case '7': stop(); break;
case '8': Work_Mode=1; break;
}
由於他在while(1)循環中,所以當我們發出加減速指令的時候,在發出下一次指令之前receive_real_data的值不變,從而在while(1)循環的作用下,不斷地加速減速,直至到限幅的最大值和最小值,所以我們不能吧加減速指令的執行放在while(1)循環中。
4、對錯誤原因二的糾正方法
我們直接在主函數中刪去對指令5和6的控制,如下(主函數的其他地方不用修改)
switch(receive_real_data)
{
case '1': run(); break;
case '2': left(); break;
case '3': right(); break;
case '4': back(); break;
case '7': stop(); break;
case '8': Work_Mode=1; break;
}
我們把5和6(加減速的控制指令)放到串口中斷裏面,原來的串口中斷函數如下:
void Com_Int(void) interrupt 4
{
EA = 0;
if(RI == 1) //當硬件接收到一個數據時,RI會置位
{
LED=0;
RI = 0;
receive_data = SBUF;//接收到的數據
if(receive_data!=0)
receive_real_data=receive_data;
SBUF=receive_real_data;//將接收到的數據放入到發送寄存器
while(!TI); //等待發送數據完成
TI=0; //清除發送完成標誌位
}
EA = 1;
}
糾正後的串口中斷函數如下(新增了一個switch語句,其他地方未修改):
void Com_Int(void) interrupt 4
{
EA = 0;
if(RI == 1) //當硬件接收到一個數據時,RI會置位
{
LED=0;
RI = 0;
receive_data = SBUF;//接收到的數據
if(receive_data!=0)
receive_real_data=receive_data;
switch(receive_real_data) //新增的switch函數
{
case '5': Speed_add(); break;
case '6': Speed_reduce(); break;
}
SBUF=receive_real_data;//將接收到的數據放入到發送寄存器
while(!TI); //等待發送數據完成
TI=0; //清除發送完成標誌位
}
EA = 1;
}
5、總結一下修改的地方
(1)修改了motor_control.c文件中的加減速函數
(2)刪去了main.c文件中main函數switch語句內對加減速指令的控制
(3)在main.c文件中Com_Int(void)函數內增加了對加減速控制的switch語句
糾正後的完整代碼的keil文件我會放到附件裏,需要者自取,還是那句話,我放的時候都是免費的,但是它會自己漲,需要的可以評論區留言,我直接發給你
三個修改都很簡單,大家可以直接在本系列第四篇文章的程序的基礎上進行以上的3個簡單修改,也可以直接下載本篇博文的附件(也就是已經修改好了的)
歡迎大家積極交流,本文未經允許謝絕轉載