原文地址:?mod=viewthread&tid=544143
此帖子現在有一個后續版本,實現了手機端的藍牙程序控制小車運動以及接收小車狀態并展示,鏈接地址:
... d&tid=544299&page=1
最初的想法是做一個紅外遙控的裝置,鏈接地址:
... d&tid=540165&extra=
我只需要前進和停止,二路遙控,想使用模擬電路搭建,但最后也沒能完成,這個想法依然在,現在只能留帶以后是否有想法再做了。
第二個想法是想做一個小車,小車的功能如下: 前進,后退,轉彎,遙控控制,自主智能運轉。 上某寶買了一個小車的底座(4驅動的,帶電機), 買了兩個L298N驅動模塊用來驅動小車,買了藍牙模塊(HC05)用來充當遙控。
實踐篇:
1,首先根據51單片機的最小系統的電路圖,焊接了一個最小系統板,使用的STC89c52的單片機(晶振6Mhz,帶復位電路,復位指示燈顯示),為了便于測試,又焊接了一個發光二極管連接一個I/O口,用于測試最小系統。
2,然后開始測試最小系統,不過我很多年沒有用過keil和下載器了,就上網尋找了一下關于這方面的帖子,過程總結如下:
最小系統測試篇:
要測試最小系統,首先需要編譯代碼的工具(我用的keil),下載代碼到單片機的工具(stc-isp),usb轉ttl硬件設備(某寶上2塊多錢買的),串口調試助手(使用的是單片機多功能調試助手PortHelper.exe),于是從網上下載了keil4破解版本,stc-isp下載軟件,單片機多功能調試助手三個軟件。
第一步:測試usb轉ttl是否可用(就4個引腳,5v,GND, TX, RX)
打開串口調試助手,設置波特率,打開,發現打開失敗,比較郁悶,為何呢? 極有可能是串口號不對,于是打開我的電腦-》管理-》設備管理器,找到串口的條目,查看它的串口號,我的竟然是串口號12.于是設置串口號,重新打開,OK。 如何測試usb轉ttl呢? 我的想法是如果發送數據的話,對應的tx引腳應該有信號,如果將TX和RX連接到一起,那么發送出去的應該自己可以接收到。我沒有示波器,就簡單的使用萬用表量它的TX引腳的電壓,點擊發送按鈕,發現TX引腳的電壓有波動即可。
第二步: 將usb轉ttl的四個引腳接入到單片機的對應引腳即可(其實就是VCC接VCC,GND接GND,TX接RX,RX接TX)。沒有采用外部供電,直接利用usb轉ttl進行的5v供電
第三步:在keil中寫代碼,對單片機的某一個I/O進行翻轉電平的操作,代碼如下
sbit LED=P0^0;
while(1){
LED = !LED
Delay10ms(100);
}
第四步:編譯程序,生成HEX文件
第五步:打開stc-isp下載工具,選擇單片機型號,hex程序位置,點擊下載即可,如果識別了單片機的話,會出現給MCU重新上電的字樣,這個時候只需要關閉再打開MCU的電源開關即可,就會出現燒寫程序的過程。
最小系統測試篇遇到的問題,回憶篇:
51單片機的電源供電問題,忘了接單片機的VCC引腳了(如果是這方面的問題,就檢查幾個關鍵地方,vcc和地接好了嗎,tx和rx接好了嗎,晶振接好了嗎,復位電路先不用管,我是使用的萬用表一個個的量的)
晶振的電路沒焊好(萬用表搞定)
usb轉ttl找不到串口(軟件問題的話,容易解決,也有可能是usb轉ttl硬件有問題,驅動沒有安裝成功,導致識別不了硬件)
第六步: 用萬用表量P0^0口,查看電壓是否1秒一次變化即可。
3,藍牙模塊工作篇
從某寶上花了17大洋買了一個HC05藍牙主從模塊,有6個引腳(VCC,GND,TX,RX,AT,STATUS),前4個引腳與usb轉ttl的接法相同(注意RX,TX交叉接線接入到單片機),AT和STatus引腳是我自己命的名字。 AT引腳高電平有效,用于藍牙模塊進入AT狀態(所謂AT狀態,即是其他程序可以通過它的引腳向藍牙模塊發送AT控制命令,例如設置波特率,查看版本號,設置主從模式),AT引腳懸空默認為低電平。Status引腳用于顯示配對的狀態(配對成功輸出高電平,未配對輸出低電平)
藍牙模塊測試篇:
第一步:藍牙模塊既然包含串口,那么它應該可以跟usb轉ttl直接連接,使用電腦向藍牙模塊發送命令。于是連接藍牙模塊與usb轉ttl的對應引腳。
第二步:將AT引腳懸空,使用手機搜索周圍的藍牙設備,發現有HC05的藍牙(因為這個藍牙模塊默認是從模塊,可以被收到)
第三步:將AT引腳拉高電平,使其進入AT狀態(按照文檔描述,如果上電之后再置位AT,指示燈無變化,依舊是,如果上電之前拉高AT,指示燈轉為1秒一次),然后通過電腦串口發送AT+VERSION?(注意需要換行)查看版本號,使用AT+UART?查看波特率(默認9600,不帶校驗)
此文檔有用: ATK-HC05-V11用戶手冊_V1.0.pdf
第四步:實驗了一下,我的模塊有問題,就是上電之前拉高AT,模塊不接受AT命令,只有上電后拉高AT才有用,不過不影響使用。
第五步:將藍牙模塊和usb轉ttl連接后,AT保持懸空,即藍牙模塊為從模塊,手機安裝藍牙串口助手,打開手機藍牙,然后搜索HC05,配對,然后打開手機端的藍牙串口助手軟件,向HC05發送消息,如果藍牙模塊工作正常,那么電腦端的串口調試助手應該收到手機發送的消息。同樣的也可以通過電腦端發送消息,到手機端。
消息傳遞流程如下: 手機端藍牙串口助手 -> 手機藍牙 ->空氣 -> HC05藍牙模塊 -> USB轉ttl模塊 -> 電腦的串口調試助手,反過來也是可行的(注意線路連接方式都是RX與TX交叉連接)
藍牙模塊與單片機集成調試篇:
上面的測試已經證明了藍牙模塊是可以發送接收手機端消息的,現在開始將藍牙模塊與單片機的TX,RX接口連接起來,通過程序控制藍牙模塊與手機藍牙進行溝通,從而達到利用手機藍牙進行遙控的目的。
main函數如下,主要設置串口波特率,以及開啟串口中斷
//PCON:SMOD位默認為0,串行口波特率加倍位
PCON = 0x80; //SMOD=1;
TMOD=0x20; //8位自動加載計數器
//TH1=0xfd; TL1=0xfd; for 11.0592MHZ and SMOD=0,
TH1 = 0xf3;//2400bps
TL1 = 0xf3;
TR1=1; // T1
//SCON: 0x50=SM0=0, SM1=1,REN=1
REN=1;
SM0=0;
SM1=1; //串口
EA=1; //中斷
ES=1;
串口中斷函數
void serial() interrupt 4
{
char sbuf;
sbuf=SBUF;
switch (sbuf)
{
case 'f': direc=4; break;
case 'b': direc=5; break;
case 'l': direc=6; break;
case 'r': direc=7; break;
case 's': direc=-1; break;
default : LED = !LED; //LED為一個I/O引腳,控制發光二極管
}
RI=0;
}
遇到的問題:
利用手機給藍牙HC05發送消息,如果不是switch中的幾個case的話,那么LED燈會明暗變化,但是剛開始的測試卻始終不如意。而后仔細查看了代碼,并沒有發現什么錯誤,后來懷疑是波特率的問題,因為我的晶振是6Mhz的,藍牙模塊的波特率是9600. 我手動計算了一下:
采用波特率倍頻,那么計算如下 6*1000000*2 / 12 / 32 / 9600 = 3.255, 取整為3. 然后使用3反代入到此式子中
6*1000000*2 / 12 / 32 /3 = 10416.7 與9600相差1000多,這個似乎差距太大了。我又嘗試了其他幾個參數,像4800,19200,38400都相差挺大的,估計就是這個原因。于是繼續嘗試,發現2400的話,相差不多。6*1000000*2/12/32/2400
= 13.02 ,然后使用13代入進去結果為2403.8,與2400的波特率相差很小,估計是可以用的。但是看藍牙模塊的文檔,發現它說不支持2400的,我不甘心,就使用usb轉ttl模塊設置了一下2400,沒想到AT命令還真的返回OK了,單片機程序也可以正常工作了。
4,小車驅動篇:
將兩個L298N模塊與單片機的P2口直接相連(小車4輪驅動,每個電機需要兩個輸入引腳,以及一個使能引腳,那就是12個引腳,我剛開始并不想支持調速的功能,因此使能引腳直接高電平了,就連接了8個I/O口)。注意L298N的GND引腳一定要和單片機的GND共地。
關于L298N: 它的EN引腳用于使能,EN為高電平,才使能。另外兩個輸入引腳IN1,IN2根據電平的組合變化會有4種情況(00,10,01,11),電機相應的在00和11停止(這個停止是帶電的,類似于鎖死的感覺),在10正轉,01反轉。可以直接使用單片機的VCC和GND連接L298N的IN1和IN2,同時將EN端接VCC,看電機轉不轉就可以測試L298N模塊了。
編寫程序,控制輪子的正轉,翻轉,停止等。基本上就是以下的這種代碼
void wheelForward(uchar which)
{
switch(which)
{
case 1:
{
wheel_1_1 = 0;
wheel_1_2 = 1;
break;
}
case 2:
{
wheel_2_1 = 0;
wheel_2_2 = 1;
break;
}
case 3:
{
wheel_3_1 = 0;
wheel_3_2 = 1;
break;
}
case 4:
{
wheel_4_1 = 0;
wheel_4_2 = 1;
break;
}
}
}
遇到的問題:
問題1: 剛開始L298N直接連接P0口,死活不轉,而直接引出高低電平到某一個電機的IN1,IN2口,電機正常運轉。于是猜測是I/O有問題,使用萬用表測量,發現P0的I/O在輸出高電平的時候,根本不是高電平,而后發了帖子,詢問了一下才知道P0口在高電平是呈現高阻態的,需要外部焊接電路加上拉電阻才可工作。我不想焊接過多的電路,就將其I/O換到P2口,可以正常工作
帖子鏈接地址:
... 8&page=1#pid4108114
問題2: 我使用的是路由器的9v直流電源,使用其帶動兩個L298N,同時將L298N的輸出的一個5V高電平接到單片機上給單片機供電,啟動4輪驅動,電機只會翁的一聲,然后啥也沒有,二輪驅動也不轉。 上網查看了不少資料,基本上都是電源功率過低,需要將單片機與L298N分別供電才可以。
于是使用筆記本的usb口給單片機供電,使用9v直流電源給電機供電,比剛才好了一些,兩輪可以轉,但是4個輪子還是轉不了。沒辦法,想到自己有一個小的卡片相機,有鎳氫電池8節,然后上網買了一個電池盒,裝上去,電機轉的吼吼叫,同時L298N給單片機供電也沒問題。
問題3:
關于L298N同時給單片機供電的問題,大家可以在啟動輪子轉動的時候量一量單片機的電源電壓,會發現在電機啟動的一剎那,單片機的電壓有一個瞬時的拉低,這樣單片機就會復位了。
5,藍牙遙控小車匯總篇
第一步:部署小車,L298N,鎳氫電池盒,藍牙模塊組裝到一起
第二步:編寫代碼,本來可以使用EN口進行調速控制的,但是考慮到還需要使用額外的I/O口,就先不打算做了。
代碼完成的功能:
小車前進,后退,停止,左轉,右轉
小車單個輪子的轉動(用于測試)
小車當前狀態的獲取(用于后期給小車增加其他模塊的時候,例如溫度模塊,就可以讀取溫度了)
小車命令幫助
代碼思路:
首先完成單個輪子的控制
再完成小車的控制
再加入串口接收中斷,收到不同命令,設置方向變量
main程序讀取方向變量控制不同的方向
6,思路篇
一些比較有特點的思路:
思路1:一個棘手的問題想實現這樣的功能:
用戶按鍵,小車才走,用戶松開按鍵,小車停止。
我的想法如下: 小車使用一個定時器T0,控制定時器的延時時間為100ms,用戶每發送一個前進信號,小車會前進100ms,但是這100ms內小車還需要能夠響應外部的命令。例如如果用戶在t=0ms發送前進命令,然后在t=50ms發送左轉命令,小車能夠立刻左轉,而不是繼續前進100ms,然后才執行左轉的命令?;镜拇a思路是用戶的每一個命令,都會重置timer0,timer0的超時中斷函數會將小車停止。這樣用戶只要以連續的小于100ms間隔發送前進命令,小車就會一直前進,也就是說timer0的中斷沒有執行,如果用戶間隔100ms還沒有發送命令,那么小車停止。
當前我使用的藍牙串口助手它的按鍵不支持連續發送,只能按下松開手,才會發送消息,這樣我現在就把時間間隔設置為1000ms,用戶只要以小于1000ms的間隔連續按鍵,小車就會一直前進,如果不按鍵,小車會繼續前進1000ms才會停止。 后期打算找到藍牙串口調試助手的源代碼,修改它的源代碼,設置成如果用戶按下不丟,小車前進命令能夠一直發送。
思路2: 既然有了手機藍牙,那么小車再想展示一些狀態信息,就沒必要使用像1602,12864之類的東東了,直接定時發給手機藍牙模塊就OK了。我現在并沒有實現定時發送,不過支持了命令獲取的功能。
當用戶發送命令h到單片機,單片機會返回一個幫助界面,告知如何控制小車,例如"f"控制小車前進,"b"控制小車后退,當用戶發送命令i到單片機,單片機會返回小車的一些狀態信息,我當前只返回了一些簡單的變量狀態(后面想加入距離,溫度,光敏都是可行的)。
思路3:有了藍牙,這個小車就可以被我們隨心所欲的控制了。你既可以推命令到單片機,控制它,你又可以把單片機內部的當前狀態拉出來。單片機本身又可以定期將它的狀態向你的手機進行推送。這個我感覺還是很好玩的,有了這個代碼的基本框架,后面有可能的話像實現一個小車的擴展功能,加上紅外對管讓它不撞墻,加上超聲波讓它測距,加上麥克風讓它向著聲音跑,加上人體感應讓它做一個跟屁蟲,甚至于加上一個智能化點的程序,讓它能夠在一個屋子里隨便的轉悠,然后記錄屋里的情況。還想做的是加入一個wifi模塊,能將它的狀態信息上傳到路由器里面(手里有一個壞的路由器華為hg255d,正在修理中,還沒有摸清楚如何修),這樣遠在千里之外都可以訪問小車上面傳感器的情況了。還想加的是一個攝像頭模塊,不過單片機的處理能力有限,攝像頭的解碼對它是個大問題,估計很難辦到(手頭有優龍fs2401開發板,剛修好它的電源模塊,正在研究中,不過前天它突然bios引導不起來了,也不知道是什么問題,關于這種arm的東西,還沒有接觸過,完全不懂刷bios,uboot等等的東西,看情況是要重新刷bios了)。
評論
查看更多