|
該設計是在單片機小車為基礎開發的循跡系統。小車由L298N電機驅動模塊、紅外循跡模塊,由STC89C52RC控制芯片完成各模塊之間的連接與控制。按鍵能傳送相應命令,對小車移動進行靈活巧妙的控制。當系統啟動后,通過按鍵來選擇紅外循跡的圖形從而改變小車的移動方向。在自動模式下,能沿著紅外循跡到地面黑線運動,能躲避障礙物。具體設計模塊圖如圖1-1所示。
制作出來的實物圖如下:
1.jpg (1.54 MB, 下載次數: 19)
下載附件
2023-12-30 23:49 上傳
2.jpg (1.07 MB, 下載次數: 20)
下載附件
2023-12-30 23:49 上傳
3.jpg (2.93 MB, 下載次數: 19)
下載附件
2023-12-30 23:49 上傳
電路原理圖如下:
1.png (115.87 KB, 下載次數: 28)
下載附件
2023-12-30 23:49 上傳
4.1 主程序設計
在軟件設計中,采用了PWM 調速、信息融合技術等,編寫程序時使用了C/C++語言,實現相同功能時只需要更簡單的語句,循跡模塊主程序為判斷語句,判斷光電開關的狀態,如果其中一個光電傳感器未接收到反射信號(黑線或障礙物吸收了紅外光線),單片機使用PWM 算法調控,通過控制電流在一個周期中的占空比,立刻調整左右輪差速實現方向調控,實現轉彎循跡,如果兩個光電傳感器同時未接收到反射信號,單片機輸出電平停止直流電機的運轉,實現避障停車。通過調用各個子函數實現智能小車的功能,經實踐檢測程序的整體可讀性較好,方便移植。
4.2 電機驅動程序
本設計采用 L298N電機驅動模塊。由L298N模塊各個端口的邏輯關系可知,當 ENA與ENB為 1 時,通過控制 IN1、IN2、IN3、IN4 端口電平的高低來改變電機的轉向。電機方向控制邏輯表如表3-1。同時單片機還可以產生PWM波,通過調節占空比的方式來控制電機的轉速。
4.3 紅外循跡程序
初始化結束后,接收到循跡指令,小車前方有一對紅外對管,分別置于黑線兩側,紅外管相對于黑線有 2mm到 4mm的距離。當兩對紅外管都能探測到黑線時,汽車就會一直向前行駛。當左側傳感器無法檢測到黑線時,左側電機向前旋轉,右側電機向后旋轉,利用差速原理實現車輛的向右轉向,直到檢測到左側的黑線后,小車繼續沿直線行駛。同樣,當無法在右側檢測到黑線時,右電機向左旋轉,左電機向右旋轉,實現車輛的向左轉向,直到在右側檢測到黑線,小車繼續直線行駛。循跡流程如圖3-1所示。
4.4 按鍵掃描程序
只要使用單片機,按鍵檢測基本上是一定要實現的功能。按鍵檢測要好用,最重要的是實時和去抖。初學者往往會在主循環調用按鍵檢測程序(實時)并利用延時去抖(準確)。這種在主循環內延時的做法對整個程序非常不友好,也非常不高效。因此我們將其做成一個按鍵檢測的模塊化程序,方便調用和調試
單片機源程序如下:- #include <REGX52.H>
- #include "LCD1602.h"
- #include "Delay.h"
- #include "Timer0.h"
- #include "CCDR.h"
- #include "Key.h"
- sbit MotorA=P1^4;
- sbit MotorB=P1^5;
- sbit A01=P1^0;
- sbit A02=P1^1;
- sbit B01=P1^2;
- sbit B02=P1^3;
- unsigned char Sr=1;////半徑(無限制)
- unsigned char Rr=10;////半徑(1~80)
- unsigned char Counter,CompareA,CompareB; //計數值和比較值,用于輸出PWM
- unsigned char KeyNum,m,
- SpeedA=13,
- SpeedB=10;
- void cwA(int a)///正
- {
- A01=0;
- A02=1;
- CompareA=a;
- }
- void ccwA(int a)///反
- {
- A01=1;
- A02=0;
- CompareA=a;
- }
-
- void cwB(int b)///反
- {
- B01=1;
- B02=0;
- CompareB=b;
- }
- void ccwB(int b)///正
- {
- B01=0;
- B02=1;
- CompareB=b;
- }
- void qian(void)
- {
- cwA(SpeedA);
- cwB(SpeedB);
- }
- void hou (void)
- {
- ccwA(SpeedA);
- ccwB(SpeedB);
- }
- void you(void)
- {
- cwA(SpeedA);
- ccwB(SpeedB);
- }
- void zuo(void)
- {
- ccwA(SpeedA);
- cwB(SpeedB);
- }
- void square()
- {
- qian();
- time(Sr);
- zuo();
- Delay(600);
- }
- void round()
- {
- cwA(SpeedA);
- cwB(SpeedB+Rr);
- }
- void main()
- {
- Timer0_Init();
- // LCD_Init(); //LCD初始化
- // LCD_ShowChar(1,1,'A'); //在1行1列顯示字符A
- // LCD_ShowString(1,3,"Hello"); //在1行3列顯示字符串Hello
- // LCD_ShowNum(1,9,66,2); //在1行9列顯示數字66,長度為2
- // LCD_ShowSignedNum(1,12,-88,2); //在1行12列顯示有符號數字-88,長度為2
- // LCD_ShowHexNum(2,1,0xA5,2); //在2行1列顯示十六進制數字0xA5,長度為2
- // LCD_ShowBinNum(2,4,0xA5,8); //在2行4列顯示二進制數字0xA5,長度為8
- // LCD_ShowChar(2,13,0xDF); //在2行13列顯示編碼為0xDF的字符
- // LCD_ShowChar(2,14,'C'); //在2行14列顯示字符C
- while(1)
- {
- KeyNum=Key();
- if(KeyNum==1)
- {
- m=0;
- }
- if(KeyNum==2)
- {
- m=1;
- }
- if(m==1)
- {
- // LCD_ShowString(1,3,"square"); //在1行1列顯示字符A
- square();
- }
- if(m==0)
- {
- // LCD_ShowString(1,3,"round"); //在1行1列顯示字符A
- round();
- }
- }
- }
- void Timer0_Routine() interrupt 1
- {
- TL0 = 0x9C; //設置定時初值
- TH0 = 0xFF; //設置定時初值
- Counter++;
- Counter%=100; //計數值變化范圍限制在0~99
- if(Counter<CompareA) //計數值小于比較值
- {
- MotorA=1; //輸出1
- }
- else //計數值大于比較值
- {
- MotorA=0; //輸出0
- }
- if(Counter<CompareB) //計數值小于比較值
- {
- MotorB=1; //輸出1
- }
- else //計數值大于比較值
- {
- MotorB=0; //輸出0
- }
- }
復制代碼 原理圖PCB: 無
仿真: 無
代碼:
51單片機電子繪圖小車.7z
(1.57 MB, 下載次數: 23)
2023-12-30 23:51 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
-
-
視頻.7z
2023-12-30 23:51 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
5.85 MB, 下載次數: 6, 下載積分: 黑幣 -5
評分
-
查看全部評分
|