制作出來的單片機雙軸自動追光系統實物圖如下:
51單片機雙軸自動追光系統主要由STC89C52RC + 5516光敏電阻 + ADC0832+ ULN2803 + 步進電機 + LCD1602顯示屏組成。
1.通過子電路板的上、下、左、右四個光敏電阻來感受四個方向的光強,自動尋找光強最強的方向。四個光敏電阻的分壓電路將測得的光強轉換為電信號,再通過兩個ADC0832 轉換為數字量,單片機對數據進行比較處理之后進行顯示并輸出控制信號通過ULN2803芯片驅動步進電機轉動。
2.系統共設置有兩個模式,自動模式與手動模式,可通過按鍵切換。
3.自動模式下分為尋光與避光模式,尋光模式下系統會自動尋找光照最強的地方,避光模式下系統會避開光照強烈的地方,可通過按鍵切換。
4.手動模式下可通過上下左右四個按鍵(只在手動模式有效)來控制電機的轉動。
5.LCD1602 液晶屏實時顯示ADC芯片轉換的光敏數值
注意:由于系統功率有限,無法同時有效驅動顯示屏和兩個電機的運轉,當所有器件均由電源線一個口供電時電機運轉緩慢, 同時電機運轉時會拉低整個系統的電壓,顯示屏會變暗,所以需要外接電池盒對兩個步進電機進行單獨供電,經過測試,接四節5 號南孚電池電機能正常運轉,接三節5號南孚電池電機雖能運轉但力矩過小(電機轉動的力太小) ,稍微有障礙物或者控制線的阻擋就轉不動了。 (電池盒電源線的夾子夾在左下角的P6 上,紅夾子夾 + 號一端,黑夾子夾 - 號端)
電路原理圖如下:
還有原理圖及實物圖和Altium Designer-原理圖及PCB工程因為文件太大沒法上傳
- 將上下兩部分連接的排線接好,兩個電路板插口處上有文字標識,要對應插好,不要接反了
上 - 上下 - 下 左 - 左 右 - 右 GND - GND VCC - VCC -
將上下用螺絲連接起來
這根長螺絲插到底座上,如右圖
 
3.將小螺絲刀插入底座上的黑色小螺絲,擰緊,上下主體連接完畢 4.連接電機的排線 上面這個電機的線插到最左邊帶有‘Y方向’標識的接口,紅線朝右 下面這個電機的線插到中間帶有‘X方向’標識的接口,紅線朝右
5.檢查線,屏幕是否插好,檢查無誤后接上電源線,打開電池盒背部的開關,打開板子上的電源開關,屏幕點亮,自動顯示A/D轉換的值,開機默認自動尋光模式。(用安卓線供電無需電池盒)
單片機源程序如下:
- #include <reg52.h>
- #include "Delay.h"
- #include "ADC0832.h"
- #include "LCD1602.h"
- #include "StepMotor.h"
- #define uchar unsigned char //宏定義
- #define uint unsigned int //宏定義
- #define Light_Sensty 3 //感光靈敏度
- sbit Key_Pattern = P3^4; //模式切換
- sbit Key_Blk_or_Lgt = P3^5; //自動尋/避光
- sbit Key_Up = P3^0; //上按鍵
- sbit Key_Down = P3^1; //下按鍵
- sbit Key_Left = P3^2; //左按鍵
- sbit Key_Right = P3^3; //右按鍵
- uchar Up_data,Down_data,Right_data,Left_data;//X,Y方向的光照數值
- bit flag_Blk_or_Lgt; //用于切換尋黑、尋光
- bit flag_Auto_or_Hand; //用于切換自動、手動
- uchar code *DIS1=" Welcome to use ";
- uchar code *DIS2=" Wait a jiff ";
- uchar code *DIS3=" ";
- uchar code table[]={0,1,2,3,4,5,6,7,8,9};//顯示數字碼表
- /********************************************************************
- * 名稱 : void DataDisplay(void)
- * 功能 : 獲取光照數值的個、十、百位的數
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- typedef struct LIGHT
- {
- uchar bai1,shi1,ge1; //上下
- uchar bai2,shi2,ge2; //左右
- }LIGHT1;
- LIGHT1 AD1,AD2;
- void DisplayInit(void)
- {
- L1602_string(1,1,DIS1);//開機顯示
- L1602_string(2,1,DIS2);
- DelayMs(200);
- L1602_char(2,13,'.');
- DelayMs(200);
- L1602_char(2,14,'.');
- DelayMs(200);
- L1602_char(2,15,'.');
- DelayMs(300);
- L1602_string(1,1,"U:000 D:000 Auto"); //開機顯示
- L1602_string(2,1,"L:000 R:000 Sun ");
- }
- /********************************************************************
- * 名稱 : void DataDisplay(void)
- * 功能 : 光照數值顯示
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void DataDisplay(void)
- {
- uchar i;
- for(i=0;i<5;i++)
- {Up_data = Adc0832_Read_1(0);}Delayus(100); //獲取上方電壓值
- for(i=0;i<5;i++)
- {Down_data = Adc0832_Read_1(1);}Delayus(100); //獲取下方電壓值
- for(i=0;i<5;i++)
- {Right_data = Adc0832_Read_2(0);}Delayus(100); //獲取右方電壓值
- for(i=0;i<5;i++)
- {Left_data = Adc0832_Read_2(1);}Delayus(100); //獲取左方電壓值
-
-
- AD1.bai1 = Up_data/100%10; //分離百位
- AD1.shi1 = Up_data/10%10; //分離十位
- AD1.ge1 = Up_data%10; //分離個位
- AD1.bai2 = Down_data/100%10;
- AD1.shi2 = Down_data/10%10;
- AD1.ge2 = Down_data%10;
- AD2.bai1 = Right_data/100%10;
- AD2.shi1 = Right_data/10%10;
- AD2.ge1 = Right_data%10;
- AD2.bai2 = Left_data/100%10;
- AD2.shi2 = Left_data/10%10;
- AD2.ge2 = Left_data%10;
- L1602_char(1,3,table[AD1.bai1]+0X30); //顯示百位
- L1602_char(1,4,table[AD1.shi1]+0X30); //顯示十位
- L1602_char(1,5,table[AD1.ge1]+0X30); //顯示個位
- DelayMs(5); //延時5毫秒
- L1602_char(1,9,table[AD1.bai2]+0X30);
- L1602_char(1,10,table[AD1.shi2]+0X30);
- L1602_char(1,11,table[AD1.ge2]+0X30);
- DelayMs(5);
- L1602_char(2,3,table[AD2.bai1]+0X30);
- L1602_char(2,4,table[AD2.shi1]+0X30);
- L1602_char(2,5,table[AD2.ge1]+0X30);
- DelayMs(5);
- L1602_char(2,9,table[AD2.bai2]+0X30);
- L1602_char(2,10,table[AD2.shi2]+0X30);
- L1602_char(2,11,table[AD2.ge2]+0X30);
- DelayMs(5);
- if(flag_Auto_or_Hand) //自動模式時顯示
- {
- L1602_string(1,13,"Auto");
- if(flag_Blk_or_Lgt)
- {
- L1602_string(2,13,"Sun ");
- }
- else
- {
- L1602_string(2,13,"Dark");
- }
- }
- else //手動模式時顯示
- {
- L1602_string(1,13,"Hand");
- L1602_string(2,13," ");
- }
- }
- /********************************************************************
- * 名稱 : void Auto_Mode(void)
- * 功能 : 自動模式
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Auto_Mode(void)
- {
- int Value_Y,Value_X;
- Value_Y=(int)Up_data-(int)Down_data; //上下光照值差值
- Value_X=(int)Right_data-(int)Left_data;//左右光照值差值
-
- if(flag_Blk_or_Lgt)//尋光
- {
- if(Value_Y<(-Light_Sensty)) //上方光照值小于下方光照值
- {Motor_Down();} //下轉
- else if(Value_Y>Light_Sensty) //上方光照值大于下方光照值
- {Motor_Up();} //上轉
- else if((Value_Y>(-Light_Sensty))&&(Value_Y<Light_Sensty))//上 下光照值相差不大
- {Motor1_Stop();} //停止
- if(Value_X<(-Light_Sensty)) //右方光照值小于左方光照值
- {Motor_Left();} //左轉
- else if(Value_X>Light_Sensty) //右方光照值大于左方光照值
- {Motor_Right();} //右轉
- else if((Value_Y>(-Light_Sensty))&&(Value_Y<Light_Sensty))//左右光照值相差不大
- {Motor2_Stop();} //停止
- }
- else //避光
- {
- if(Value_Y<(-Light_Sensty))
- {Motor_Up();} //上轉
- else if(Value_Y>Light_Sensty)
- {Motor_Down();} //下轉
- else if((Value_Y>(-Light_Sensty))&&(Value_Y<Light_Sensty))
- {Motor1_Stop();}
- if(Value_X<(-Light_Sensty))
- {Motor_Right();} //右轉
- else if(Value_X>Light_Sensty)
- {Motor_Left();} //左轉
- else if((Value_Y>(-Light_Sensty))&&(Value_Y<Light_Sensty))
- {Motor2_Stop();} //停止
- }
- }
- /********************************************************************
- * 名稱 : void Hand_Mode(void)
- * 功能 : 手動模式
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Hand_Mode(void)
- {
- if(Key_Up==0)
- {
- DelayMs(10);
- if(Key_Up==0)
- {
- while(!Key_Up)
- Motor_Up();
- }
- while(!Key_Up);
- }
- if(Key_Down==0)
- {
- DelayMs(10);
- if(Key_Down==0)
- {
- while(!Key_Down)
- Motor_Down();
- }
- while(!Key_Down);
- }
- if(Key_Left==0)
- {
- DelayMs(10);
- if(Key_Left==0)
- {
- while(!Key_Left)
- Motor_Left();
- }
- while(!Key_Left);
- }
- if(Key_Right==0)
- {
- DelayMs(10);
- if(Key_Right==0)
- {
- while(!Key_Right)
- Motor_Right();
- }
- while(!Key_Right);
- }
- Motor1_Stop();
- Motor2_Stop();
- }
- /********************************************************************
- * 名稱 : void Mode_Switch(void)
- * 功能 : 模式切換 切換自/手動 、尋/避光
- * 輸入 : 無
- * 輸出 : 無
- ***********************************************************************/
- void Mode_Switch(void)
- {
- if(Key_Pattern==0) //模式切換按鍵按下
- {
- DelayMs(10); //延時消抖
- if(Key_Pattern==0) //確實按下
- {
- flag_Auto_or_Hand=!flag_Auto_or_Hand;//自動/手動切換標志位反轉
- }
- while(!Key_Pattern);//松手檢測
- }
- if(flag_Auto_or_Hand) //如果工作在自動模式
- {
- if(Key_Blk_or_Lgt==0)//尋/避光按鍵按下
- {
- DelayMs(10); //延時消抖
- if(Key_Blk_or_Lgt==0)//確實按下
- {
- flag_Blk_or_Lgt=!flag_Blk_or_Lgt;// 尋光/避光標志位反轉
- }
- while(!Key_Blk_or_Lgt);//松手檢測
- }
- }
- }
- void main(void)
- {
- L1602_init();//LCD1602初始化
-
- flag_Auto_or_Hand = 1;//自動模式
- flag_Blk_or_Lgt = 1;//尋光模式
- DisplayInit();
- while(1)
- {
- DataDisplay();//數值顯示
- Mode_Switch();//模式切換
- if(flag_Auto_or_Hand)//控制位為1時
- {
- Auto_Mode();//自動模式
- } //控制位為0時
- else
- {
- Hand_Mode();//手動模式
- }
-
- }
- }
復制代碼
元件清單
元件 值 數量/個
電容
104電容(0.01uf) 4
30pf瓷片電容 2
10uf電解電容 1
電阻
500Ω 1
10k 5
10k電位器 1
10k排阻 1
5516光敏電阻 4
晶振 11.0592Mhz 1
51單片機 STC89C52 1
IC芯片座
40p 1
18p 1
8p 2
排針
5p 2
6p 2
3p 2
4p 1
3p*2 1
輕觸按鍵 4腳 7
電源插座 DC005 1
電源開關 SS-12D07 3腳2擋 直插 1
LED燈 紅色 1
短接帽 兩腳 2
M3螺絲
圓頭3*5mm 4
圓頭3*25mm 2
聯軸器固定螺絲 6
M4螺絲 圓頭4*60mm 1
螺帽 M3 6
M4 1
聯軸器 內徑 4mm-5mm 2
XH2.54排線 6p 1
LCD顯示屏 LCD1602 1
電源線 DC005 1
步進電機 28byj-48 2
ADC0832 直插 2
ULN2803 直插 1
Keil代碼附件下載:
程序.7z
(4.68 MB, 下載次數: 151)
2022-5-16 21:01 上傳
點擊文件名下載附件
|