找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6326|回复: 9
收起左侧

51单片机光敏电阻+步进电机双轴自动追光系统程序原理图设计

  [复制链接]
ID:975909 发表于 2022-5-16 08:31 | 显示全部楼层 |阅读模式
制作出来的单片机双轴自动追光系统实物图如下:
51hei.png

51单片机双轴自动追光系统主要由STC89C52RC + 5516光敏电阻 + ADC0832+ ULN2803 + 步进电机 + LCD1602显示屏组成。
1.通过子电路板的上、下、左、右四个光敏电阻来感受四个方向的光强,自动寻找光强最强的方向。四个光敏电阻的分压电路将测得的光强转换为电信号,再通过两个ADC0832 转换为数字量,单片机对数据进行比较处理之后进行显示并输出控制信号通过ULN2803芯片驱动步进电机转动。
2.系统共设置有两个模式,自动模式与手动模式,可通过按键切换。
3.自动模式下分为寻光与避光模式,寻光模式下系统会自动寻找光照最强的地方,避光模式下系统会避开光照强烈的地方,可通过按键切换。
4.手动模式下可通过上下左右四个按键(只在手动模式有效)来控制电机的转动。
5.LCD1602 液晶屏实时显示ADC芯片转换的光敏数值
注意:由于系统功率有限,无法同时有效驱动显示屏和两个电机的运转,当所有器件均由电源线一个口供电时电机运转缓慢, 同时电机运转时会拉低整个系统的电压,显示屏会变暗,所以需要外接电池盒对两个步进电机进行单独供电,经过测试,接四节5 号南孚电池电机能正常运转,接三节5号南孚电池电机虽能运转但力矩过小(电机转动的力太小) ,稍微有障碍物或者控制线的阻挡就转不动了。 (电池盒电源线的夹子夹在左下角的P6 上,红夹子夹 + 号一端,黑夹子夹 - 号端)

电路原理图如下:
51hei.png 51hei.png

还有原理图及实物图和Altium Designer-原理图及PCB工程因为文件太大没法上传

  • 将上下两部分连接的排线接好,两个电路板插口处上有文字标识,要对应插好,不要接反了
上 - 上
下  - 下
左  - 左
右  - 右
GND  - GND
VCC  - VCC
  •            将上下用螺丝连接起来
这根长螺丝插到底座上,如右图



3.
将小螺丝刀插入底座上的黑色小螺丝,拧紧,上下主体连接完毕
            
4.连接电机排线
上面这个电机的线插到最左边带有‘Y方向’标识的接口,红线朝右
下面这个电机的线插到中间带有‘X方向’标识的接口,红线朝右

5.检查线,屏幕是否插好,检查无误后接上电源线,打开电池盒背部的开关,打开板子上的电源开关,屏幕点亮,自动显示A/D转换的值,开机默认自动寻光模式。(用安卓线供电无需电池盒)


单片机源程序如下:
  1. #include <reg52.h>
  2. #include "Delay.h"
  3. #include "ADC0832.h"
  4. #include "LCD1602.h"
  5. #include "StepMotor.h"

  6. #define uchar unsigned char        //宏定义
  7. #define uint  unsigned int        //宏定义

  8. #define Light_Sensty  3                 //感光灵敏度

  9. sbit Key_Pattern = P3^4;        //模式切换
  10. sbit Key_Blk_or_Lgt = P3^5;        //自动寻/避光
  11. sbit Key_Up           =        P3^0;         //上按键
  12. sbit Key_Down         =         P3^1;         //下按键
  13. sbit Key_Left         =         P3^2;         //左按键
  14. sbit Key_Right        =         P3^3;         //右按键

  15. uchar Up_data,Down_data,Right_data,Left_data;//X,Y方向的光照数值
  16. bit flag_Blk_or_Lgt;        //用于切换寻黑、寻光
  17. bit flag_Auto_or_Hand;        //用于切换自动、手动


  18. uchar code *DIS1=" Welcome to use ";
  19. uchar code *DIS2=" Wait a jiff    ";
  20. uchar code *DIS3="                ";
  21. uchar code table[]={0,1,2,3,4,5,6,7,8,9};//显示数字码表

  22. /********************************************************************
  23. * 名称 : void DataDisplay(void)
  24. * 功能 : 获取光照数值的个、十、百位的数
  25. * 输入 : 无
  26. * 输出 : 无
  27. ***********************************************************************/
  28. typedef struct LIGHT         
  29. {
  30.         uchar bai1,shi1,ge1; //上下
  31.         uchar bai2,shi2,ge2; //左右
  32. }LIGHT1;
  33. LIGHT1 AD1,AD2;

  34. void DisplayInit(void)
  35. {
  36.         L1602_string(1,1,DIS1);//开机显示
  37.            L1602_string(2,1,DIS2);   
  38.            DelayMs(200);
  39.            L1602_char(2,13,'.');
  40.            DelayMs(200);
  41.            L1602_char(2,14,'.');
  42.            DelayMs(200);
  43.            L1602_char(2,15,'.');
  44.            DelayMs(300);  
  45.            L1602_string(1,1,"U:000 D:000 Auto");        //开机显示
  46.            L1602_string(2,1,"L:000 R:000 Sun ");
  47. }

  48. /********************************************************************
  49. * 名称 : void DataDisplay(void)
  50. * 功能 : 光照数值显示
  51. * 输入 : 无
  52. * 输出 : 无
  53. ***********************************************************************/
  54. void DataDisplay(void)
  55. {
  56.         uchar i;
  57.         for(i=0;i<5;i++)
  58.         {Up_data = Adc0832_Read_1(0);}Delayus(100);         //获取上方电压值                           

  59.         for(i=0;i<5;i++)
  60.         {Down_data = Adc0832_Read_1(1);}Delayus(100);         //获取下方电压值                           

  61.         for(i=0;i<5;i++)
  62.         {Right_data = Adc0832_Read_2(0);}Delayus(100);        //获取右方电压值                 

  63.         for(i=0;i<5;i++)
  64.         {Left_data = Adc0832_Read_2(1);}Delayus(100);        //获取左方电压值
  65.         
  66.         

  67.         AD1.bai1 = Up_data/100%10;                  //分离百位
  68.         AD1.shi1 = Up_data/10%10;                  //分离十位
  69.         AD1.ge1  = Up_data%10;                          //分离个位

  70.         AD1.bai2 = Down_data/100%10;
  71.         AD1.shi2 = Down_data/10%10;
  72.         AD1.ge2  = Down_data%10;

  73.         AD2.bai1 = Right_data/100%10;
  74.         AD2.shi1 = Right_data/10%10;
  75.         AD2.ge1  = Right_data%10;

  76.         AD2.bai2 = Left_data/100%10;
  77.         AD2.shi2 = Left_data/10%10;
  78.         AD2.ge2  = Left_data%10;

  79.         L1602_char(1,3,table[AD1.bai1]+0X30); //显示百位
  80.         L1602_char(1,4,table[AD1.shi1]+0X30); //显示十位
  81.         L1602_char(1,5,table[AD1.ge1]+0X30);  //显示个位
  82.         DelayMs(5);                                                          //延时5毫秒
  83.         L1602_char(1,9,table[AD1.bai2]+0X30);
  84.         L1602_char(1,10,table[AD1.shi2]+0X30);
  85.         L1602_char(1,11,table[AD1.ge2]+0X30);
  86.         DelayMs(5);
  87.         L1602_char(2,3,table[AD2.bai1]+0X30);
  88.         L1602_char(2,4,table[AD2.shi1]+0X30);
  89.         L1602_char(2,5,table[AD2.ge1]+0X30);
  90.         DelayMs(5);
  91.         L1602_char(2,9,table[AD2.bai2]+0X30);
  92.         L1602_char(2,10,table[AD2.shi2]+0X30);
  93.         L1602_char(2,11,table[AD2.ge2]+0X30);
  94.         DelayMs(5);

  95.         if(flag_Auto_or_Hand)         //自动模式时显示
  96.         {
  97.                 L1602_string(1,13,"Auto");
  98.                 if(flag_Blk_or_Lgt)
  99.                 {
  100.                         L1602_string(2,13,"Sun ");
  101.                 }
  102.                 else
  103.                 {
  104.                         L1602_string(2,13,"Dark");
  105.                 }
  106.         }
  107.         else                                    //手动模式时显示
  108.         {
  109.                 L1602_string(1,13,"Hand");
  110.                 L1602_string(2,13,"    ");
  111.         }


  112. }

  113. /********************************************************************
  114. * 名称 : void Auto_Mode(void)
  115. * 功能 : 自动模式
  116. * 输入 : 无
  117. * 输出 : 无
  118. ***********************************************************************/
  119. void Auto_Mode(void)
  120. {
  121.         int Value_Y,Value_X;
  122.         Value_Y=(int)Up_data-(int)Down_data;   //上下光照值差值
  123.         Value_X=(int)Right_data-(int)Left_data;//左右光照值差值
  124.         
  125.         if(flag_Blk_or_Lgt)//寻光
  126.         {
  127.                 if(Value_Y<(-Light_Sensty))        //上方光照值小于下方光照值
  128.                 {Motor_Down();}                //下转
  129.                 else if(Value_Y>Light_Sensty)        //上方光照值大于下方光照值
  130.                 {Motor_Up();}                 //上转
  131.                 else if((Value_Y>(-Light_Sensty))&&(Value_Y<Light_Sensty))//上  下光照值相差不大
  132.                 {Motor1_Stop();}        //停止

  133.                 if(Value_X<(-Light_Sensty))        //右方光照值小于左方光照值
  134.                 {Motor_Left();}                //左转
  135.                 else if(Value_X>Light_Sensty)        //右方光照值大于左方光照值
  136.                 {Motor_Right();}        //右转
  137.                 else if((Value_Y>(-Light_Sensty))&&(Value_Y<Light_Sensty))//左右光照值相差不大
  138.                 {Motor2_Stop();}        //停止
  139.         }
  140.         else                           //避光
  141.         {

  142.                 if(Value_Y<(-Light_Sensty))
  143.                 {Motor_Up();}                   //上转
  144.                 else if(Value_Y>Light_Sensty)
  145.                 {Motor_Down();}                   //下转
  146.                 else if((Value_Y>(-Light_Sensty))&&(Value_Y<Light_Sensty))
  147.                 {Motor1_Stop();}

  148.                 if(Value_X<(-Light_Sensty))
  149.                 {Motor_Right();}           //右转
  150.                 else if(Value_X>Light_Sensty)
  151.                 {Motor_Left();}                //左转
  152.                 else if((Value_Y>(-Light_Sensty))&&(Value_Y<Light_Sensty))
  153.                 {Motor2_Stop();}        //停止
  154.         }
  155. }

  156. /********************************************************************
  157. * 名称 : void Hand_Mode(void)
  158. * 功能 : 手动模式
  159. * 输入 : 无
  160. * 输出 : 无
  161. ***********************************************************************/
  162. void Hand_Mode(void)
  163. {
  164.         if(Key_Up==0)
  165.         {
  166.                 DelayMs(10);
  167.                 if(Key_Up==0)
  168.                 {
  169.                         while(!Key_Up)
  170.                          Motor_Up();
  171.                 }
  172.                 while(!Key_Up);
  173.         }

  174.         if(Key_Down==0)
  175.         {
  176.                 DelayMs(10);
  177.                 if(Key_Down==0)
  178.                 {
  179.                         while(!Key_Down)
  180.                          Motor_Down();        
  181.                 }
  182.                 while(!Key_Down);
  183.         }

  184.         if(Key_Left==0)
  185.         {
  186.                 DelayMs(10);
  187.                 if(Key_Left==0)
  188.                 {
  189.                         while(!Key_Left)
  190.                          Motor_Left();
  191.                 }
  192.                 while(!Key_Left);
  193.         }

  194.         if(Key_Right==0)
  195.         {
  196.                 DelayMs(10);
  197.                 if(Key_Right==0)
  198.                 {                        
  199.                         while(!Key_Right)                        
  200.                          Motor_Right();                                
  201.                 }
  202.                 while(!Key_Right);
  203.         }

  204.         Motor1_Stop();
  205.         Motor2_Stop();        
  206. }

  207. /********************************************************************
  208. * 名称 : void Mode_Switch(void)
  209. * 功能 : 模式切换        切换自/手动        、寻/避光
  210. * 输入 : 无
  211. * 输出 : 无
  212. ***********************************************************************/
  213. void Mode_Switch(void)
  214. {
  215.         if(Key_Pattern==0)                 //模式切换按键按下
  216.         {
  217.                 DelayMs(10);                //延时消抖
  218.                 if(Key_Pattern==0)        //确实按下
  219.                 {
  220.                         flag_Auto_or_Hand=!flag_Auto_or_Hand;//自动/手动切换标志位反转        
  221.                 }
  222.                 while(!Key_Pattern);//松手检测
  223.         }

  224.         if(flag_Auto_or_Hand)         //如果工作在自动模式
  225.         {
  226.                 if(Key_Blk_or_Lgt==0)//寻/避光按键按下        
  227.                 {
  228.                         DelayMs(10);         //延时消抖
  229.                         if(Key_Blk_or_Lgt==0)//确实按下
  230.                         {
  231.                                 flag_Blk_or_Lgt=!flag_Blk_or_Lgt;// 寻光/避光标志位反转               
  232.                         }
  233.                         while(!Key_Blk_or_Lgt);//松手检测
  234.                 }
  235.         }
  236. }


  237. void main(void)
  238. {
  239.    L1602_init();//LCD1602初始化
  240.      
  241.    flag_Auto_or_Hand = 1;//自动模式
  242.    flag_Blk_or_Lgt   = 1;//寻光模式
  243.    DisplayInit();
  244.    while(1)
  245.    {
  246.             DataDisplay();//数值显示
  247.          Mode_Switch();//模式切换

  248.          if(flag_Auto_or_Hand)//控制位为1时
  249.          {
  250.                  Auto_Mode();//自动模式
  251.          }                                          //控制位为0时
  252.          else
  253.          {
  254.                   Hand_Mode();//手动模式
  255.          }
  256.          
  257.    }
  258. }
复制代码

元件清单
元件 值 数量/个
电容
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, 下载次数: 139)
手动模式.bmp
主程序.jpg
自动模式.bmp

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:962396 发表于 2022-7-12 23:52 | 显示全部楼层
感谢,学习中
回复

使用道具 举报

ID:566128 发表于 2023-2-14 16:01 | 显示全部楼层
请问一下,有仿真图吗
回复

使用道具 举报

ID:505058 发表于 2023-3-25 00:33 来自手机 | 显示全部楼层
小白鹭 发表于 2023-2-14 16:01
请问一下,有仿真图吗

这是我B站的资源
回复

使用道具 举报

ID:505058 发表于 2023-3-25 00:33 来自手机 | 显示全部楼层
我B站的东西都放这来了
回复

使用道具 举报

ID:47634 发表于 2023-3-25 08:55 | 显示全部楼层
不错不错,很好的制作资料
回复

使用道具 举报

ID:1068108 发表于 2023-4-13 19:44 来自手机 | 显示全部楼层
我想问一下,用stc15内部adc测光强,protues仿真数值可以随光源距离改变 ,但是下载到板子一直没有变化是什么原因
回复

使用道具 举报

ID:1107443 发表于 2024-1-1 20:21 | 显示全部楼层
158751hei0141 发表于 2023-3-25 00:33
我B站的东西都放这来了

你B站是啥啊,我去看看你的,我现在正学这个了
回复

使用道具 举报

ID:289826 发表于 2024-3-6 22:38 | 显示全部楼层
下载学习一下,谢谢分响
回复

使用道具 举报

ID:505058 发表于 2024-3-17 07:36 来自手机 | 显示全部楼层
此项目是本人于B站发布的项目,B站视频地址:BV1qQ4y1r7MQ,望各位知悉!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表