制作出来的单片机双轴自动追光系统实物图如下:
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)
|