找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3413|回复: 5
收起左侧

51单片机四相双轴光源追踪装置源程序

  [复制链接]
ID:314935 发表于 2019-5-3 17:42 | 显示全部楼层 |阅读模式
实现功能;
光源追踪
装置图: 微信图片_20190404210146.jpg

单片机源代码如下:
  1. //*************************************************
  2. //模块类型:包含外部文件
  3. //功能描述:
  4. //说        明:
  5. //*************************************************
  6. #include "stc15f2kxx.h"
  7. #include "intrins.h"
  8. #include "string.h"
  9. #include "math.h"
  10. //*************************************************
  11. //模块类型:自定义
  12. //功能描述:
  13. //说        明:
  14. //************************************************
  15. typedef unsigned char u8;
  16. typedef unsigned int u16;
  17. typedef unsigned long int u32;

  18. #define CCP_S0                         0x10                         //P_SW1.4
  19. #define CCP_S1                         0x20                         //P_SW1.5
  20. #define ADC_POWER                 0x80                         //ADC电源控制位
  21. #define ADC_FLAG                 0x10                         //ADC完成标志
  22. #define ADC_START                 0x08                         //ADC起始控制位
  23. #define ADC_SPEEDLL         0x00                         //540个时钟
  24. #define ADC_SPEEDL                 0x20                         //360个时钟
  25. #define ADC_SPEEDH                 0x40                         //180个时钟
  26. #define ADC_SPEEDHH         0x60                         //90个时钟

  27. //光敏电阻AD比较灵敏度
  28. #define                                SunValue                                1200   //更改数值,可调节灵敏度,以适应强弱光

  29. #define                                Step                                        1           //调节步数 舵机转动的精度

  30. #define                                DelayTime                                8           //等待时间 舵机转动的速度


  31. u32 data Result_ADC[5] = {0};
  32. u8 PWM_DATA_X = 240;                                
  33. u8 PWM_DATA_Y = 240;
  34. u8 CheckStep = 0;

  35. //*************************************************
  36. //模块类型:内部函数声明
  37. //功能描述:
  38. //说        明:
  39. //************************************************
  40. void UartInit();
  41. void InitADC();
  42. void SendData(u8 dat);
  43. u32 GetADCResult(u8 ch);
  44. void Delay(u16 n);
  45. void ShowResult(u8 ch);

  46. //*************************************************
  47. //函 数 名:u32 GetADCResult(u8 ch)
  48. //输        入:AD通道号
  49. //输    出:无
  50. //功能描述: 读取光敏电阻阻值
  51. //*************************************************
  52. u32 GetADCResult(u8 ch)
  53. {
  54.         u16 buf;
  55.         float ADC_Voltage;
  56.         u32 ResValue;
  57.         ADC_CONTR = ADC_POWER | ADC_SPEEDL | ch | ADC_START;
  58.         _nop_();                                                                                                 //等待4个NOP
  59.         _nop_();
  60.         _nop_();
  61.         _nop_();
  62.         while (!(ADC_CONTR & ADC_FLAG));                                                 //等待ADC转换完成
  63.         ADC_CONTR &= ~ADC_FLAG;                                                                 //Close ADC
  64.         buf = ADC_RES;
  65.         buf = (buf << 8) | ADC_RESL;
  66.         

  67.         ADC_Voltage = (buf * 5.0) / 1024.0;                                                //ADC转换结果计算
  68.         if((5.0 - ADC_Voltage) > 0)
  69.         {
  70.                 ResValue = (ADC_Voltage * 10000) / (5.0 - ADC_Voltage);        //计算光敏电阻阻值
  71.         }
  72.         return ResValue;                                                                                 //返回光敏电阻阻值
  73. }

  74. //*************************************************
  75. //函 数 名:void InitADC(void)
  76. //输        入:无
  77. //输    出:无
  78. //功能描述: ADC初始化
  79. //*************************************************
  80. void InitADC(void)
  81. {
  82.         P1ASF = 0xf0;                                                                 //设置P1口为AD口
  83.         CLK_DIV |= 0x20;
  84.         ADC_RES = 0;                                                                 //清除结果寄存器
  85.         ADC_CONTR = ADC_POWER | ADC_SPEEDHH;
  86.         Delay(2);                                                                        //ADC上电并延时
  87. }
  88. //*************************************************

  89. //*************************************************
  90. //函 数 名:void Write_ADC_Buf(void)
  91. //输        入:无
  92. //输    出:无
  93. //功能描述: ADC结果存储
  94. //*************************************************
  95. void Write_ADC_Buf(void)
  96. {
  97.         Result_ADC[1] = GetADCResult(4);                                                 //读取四个光敏电阻阻值
  98.         Result_ADC[2] = GetADCResult(5);
  99.         Result_ADC[3] = GetADCResult(6);
  100.         Result_ADC[4] = GetADCResult(7);               
  101. }

  102. //*************************************************
  103. //*************************************************
  104. void UartInit(void)                //9600bps@11.0592MHz
  105. {
  106.         SCON = 0x50;                //8位数据,可变波特率
  107.         AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
  108.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  109.         TMOD &= 0x0F;                //设定定时器1为16位自动重装方式
  110.         TL1 = 0xE0;                        //设定定时初值
  111.         TH1 = 0xFE;                        //设定定时初值
  112.         ET1 = 0;                        //禁止定时器1中断
  113.         TR1 = 1;                        //启动定时器1
  114. }

  115. //*************************************************
  116. //*************************************************
  117. //函 数 名:void Delay(u16 n)
  118. //输        入:延时值
  119. //输    出:无
  120. //功能描述: 延时函数
  121. //*************************************************
  122. void Delay(u16 n)
  123. {
  124.         u16 x;
  125.         while (n--)
  126.         {
  127.                 x = 5000;
  128.                 while (x--);
  129.         }
  130. }

  131. //*************************************************
  132. //函 数 名:void TIM0_Init(void)
  133. //输        入:无
  134. //输    出:无
  135. //功能描述: 定时器0初始化 作为PWM基准
  136. //*************************************************
  137. void TIM0_Init(void)                //78微秒的周期隌11.0592MHz
  138. {
  139.         AUXR |= 0x80;                        //定时器时钟1T模式,传统8051的12倍,1T就是指不分频,传统8051的始终是1T/12
  140.         TMOD &= 0xF0;                        //设置定时器模式,16位重载模式
  141.         TL0 = 0xA1;                                //设置定时初值
  142.         TH0 = 0xFC;                                //设置定时初值  差值64673
  143.         TF0 = 0;                                //清除TF0标志
  144.         TR0 = 1;                                //定时器0开始计时
  145. }
  146. //*************************************************
  147. //函 数 名:void PWM_Init(void)
  148. //输        入:无
  149. //输    出:无
  150. //功能描述: PWM初始化
  151. //*************************************************
  152. void PWM_Init(void)
  153. {        
  154.         ACC = P_SW1;//即AUXR1
  155.         ACC &= ~(CCP_S0 | CCP_S1);                 //CCP_S0=0 CCP_S1=0//设置输出引脚
  156.         P_SW1 = ACC;
  157.         CCON = 0;                                                 //初始化PCA控制寄存器
  158.         CL = 0;                                                 //复位PCA16位寄存器
  159.         CH = 0;//高8位
  160.         CMOD = 0x04;                                         //设置PCA时钟源为定时器0的溢出脉冲并且禁止PCA定时器cf位溢出中断
  161.                                                                         
  162.         PCA_PWM0 = 0x00;                                 //PCA模块0工作于8位PWM,PCA_PWM0是一个pwm寄存器
  163.         CCAP0H = CCAP0L = 245;                         //PWM0的占空比,0模块的比较的计数值
  164.         CCAPM0 = 0x42;                                         //PCA模块0为8位PWM模式,允许比较并允许输出p1.1
  165.         
  166.         PCA_PWM1 = 0x00;                                 //PCA模块1工作于8位PWM
  167.         CCAP1H = CCAP1L = 245;                         //PWM1的占空比
  168.         CCAPM1 = 0x42;                                         //PCA模块1为8位PWM模式        ,允许比较,允许输出p1.0
  169.         CR = 1;                                                        //PCA定时器开始工作,位于CCON寄存器,控制pca工作与否
  170. }

  171. //*************************************************
  172. //函 数 名:void SG90_Control(void)
  173. //输        入:无
  174. //输    出:无
  175. //功能描述: SG90舵机控制
  176. //*************************************************

  177. void SG90_Control(void)
  178. {                                                         
  179.         Write_ADC_Buf();                                                                                                //读光敏电阻并做相应计算
  180.         switch(CheckStep)
  181.         {
  182.                 //上下右旋转
  183.                 case 0:
  184.                         if((Result_ADC[1] > Result_ADC[3])&&PWM_DATA_Y !=249)
  185.                         {
  186.                                 if((Result_ADC[1] - Result_ADC[3]) > SunValue)
  187.                                 {
  188.                                         CheckStep = 7;//上 左右转动
  189.                                 }
  190.                                 else
  191.                                 {
  192.                                        
  193.                                         CheckStep = 1;//
  194.                                 }
  195.                         }
  196.                         else
  197.                         {
  198.                                 CheckStep = 1;
  199.                         }
  200.                         break;
  201.                 case 1:
  202.                         if((Result_ADC[3] > Result_ADC[1])&&PWM_DATA_Y !=224)
  203.                         {
  204.                                 if((Result_ADC[3] - Result_ADC[1]) > SunValue)
  205.                                 {
  206.                                         CheckStep = 6;//Y--
  207.                                 }
  208.                                 else
  209.                                 {
  210.                                         CheckStep = 2;
  211.                                 }
  212.                         }
  213.                         else
  214.                         {
  215.                                 CheckStep = 2;
  216.                         }
  217.                         break;
  218.                 case 2://左右旋转
  219.                         if((Result_ADC[2] > Result_ADC[4])&&PWM_DATA_X !=224)
  220.                         {
  221.                                 if((Result_ADC[2] - Result_ADC[4]) > SunValue)
  222.                                 {
  223.                                         CheckStep = 4;//X--
  224.                                 }
  225.                                 else
  226.                                 {
  227.                                         CheckStep = 3;
  228.                                 }
  229.                         }
  230.                         else
  231.                         {
  232.                                 CheckStep = 3;
  233.                         }
  234.                         break;
  235.                 case 3:
  236.                         if((Result_ADC[4] > Result_ADC[2])&&PWM_DATA_X !=249)
  237.                         {
  238.                                 if((Result_ADC[4] - Result_ADC[2]) > SunValue)
  239.                                 {
  240.                                         CheckStep = 5;//X++
  241.                                 }
  242.                                 else
  243.                                 {
  244.                                         CheckStep = 0;
  245.                                 }
  246.                         }
  247.                         else
  248.                         {
  249.                                 CheckStep = 0;
  250.                         }
  251.                         break;
  252.                 case 4:
  253.                         if(Result_ADC[1]-Result_ADC[3]>SunValue)
  254.                         {
  255.                         Delay(DelayTime);
  256.                         PWM_DATA_Y += Step;
  257.                         PWM_DATA_X -= Step;
  258.                         if(PWM_DATA_X < 224)
  259.                         {
  260.                                 PWM_DATA_X = 224;
  261.                         }
  262.                         if(PWM_DATA_Y > 249)
  263.                         {
  264.                                 PWM_DATA_Y = 249;
  265.                         }
  266.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  267.                         CCAP0H = CCAP0L = PWM_DATA_X;

  268.                         }
  269.                         //**************
  270.                         if(Result_ADC[3]-Result_ADC[1]>SunValue)
  271.                         {
  272.                         Delay(DelayTime);
  273.                         PWM_DATA_Y -= Step;
  274.                         PWM_DATA_X -= Step;
  275.                         if(PWM_DATA_X < 224)
  276.                         {
  277.                                 PWM_DATA_X = 224;
  278.                         }
  279.                         
  280.                         if(PWM_DATA_Y < 224)
  281.                         {
  282.                                 PWM_DATA_Y = 224;
  283.                         }
  284.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  285.                         CCAP0H = CCAP0L = PWM_DATA_X;
  286.                         }
  287.                         if((labs(Result_ADC[1]-Result_ADC[3]))<=SunValue)
  288.                         {
  289.                         Delay(DelayTime);
  290.                         PWM_DATA_X -= Step;
  291.                         if(PWM_DATA_X < 224)
  292.                         {
  293.                                 PWM_DATA_X = 224;
  294.                         }
  295.                         CCAP0H = CCAP0L = PWM_DATA_X;
  296.                 }
  297.                         CheckStep = 2;
  298.                         break;
  299.                 case 5:
  300.                         if(Result_ADC[1]-Result_ADC[3]>SunValue)
  301.                         {
  302.                         Delay(DelayTime);
  303.                         PWM_DATA_Y += Step;
  304.                         PWM_DATA_X += Step;
  305.                         if(PWM_DATA_X > 249)
  306.                         {
  307.                                 PWM_DATA_X = 249;
  308.                         }
  309.                         if(PWM_DATA_Y > 249)
  310.                         {
  311.                                 PWM_DATA_Y = 249;
  312.                         }
  313.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  314.                         CCAP0H = CCAP0L = PWM_DATA_X;

  315.                         }
  316.                         //**************
  317.                         if(Result_ADC[3]-Result_ADC[1]>SunValue)
  318.                         {
  319.                         Delay(DelayTime);
  320.                         PWM_DATA_Y -= Step;
  321.                         PWM_DATA_X += Step;
  322.                         if(PWM_DATA_X > 249)
  323.                         {
  324.                                 PWM_DATA_X = 249;
  325.                         }
  326.                         
  327.                         if(PWM_DATA_Y < 224)
  328.                         {
  329.                                 PWM_DATA_Y = 224;
  330.                         }
  331.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  332.                         CCAP0H = CCAP0L = PWM_DATA_X;
  333.                         }//******************
  334.                         if((labs(Result_ADC[1]-Result_ADC[3]))<=SunValue)
  335.                         {
  336.                         Delay(DelayTime);
  337.                         PWM_DATA_X += Step;
  338.                         if(PWM_DATA_X > 249)
  339.                         {
  340.                                 PWM_DATA_X = 249;
  341.                         }
  342.                         CCAP0H = CCAP0L = PWM_DATA_X;
  343.                 }
  344.                         CheckStep = 3;
  345.                         break;
  346.                 case 6:
  347.                         if(Result_ADC[2]>Result_ADC[4]>SunValue)
  348.                         {
  349.                         Delay(DelayTime);
  350.                         PWM_DATA_Y -= Step;
  351.                         PWM_DATA_X -= Step;
  352.                         if(PWM_DATA_Y < 224)
  353.                         {
  354.                                 PWM_DATA_Y = 224;
  355.                         }
  356.                         if(PWM_DATA_X < 224)
  357.                         {
  358.                                 PWM_DATA_X = 224;
  359.                         }
  360.                         CCAP0H = CCAP0L = PWM_DATA_X;
  361.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  362.                   }
  363.                         //*************************
  364.                         if(Result_ADC[4]-Result_ADC[2]>SunValue)
  365.                         {
  366.                         Delay(DelayTime);
  367.                         PWM_DATA_Y -= Step;
  368.                         PWM_DATA_X += Step;
  369.                         if(PWM_DATA_X > 249)
  370.                         {
  371.                                 PWM_DATA_X = 249;
  372.                         }
  373.                         
  374.                         if(PWM_DATA_Y < 224)
  375.                         {
  376.                                 PWM_DATA_Y = 224;
  377.                         }
  378.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  379.                         CCAP0H = CCAP0L = PWM_DATA_X;
  380.                         }
  381.                         //******************
  382.                         if((labs(Result_ADC[2]-Result_ADC[4]))<=SunValue)
  383.                         {
  384.                         Delay(DelayTime);
  385.                         PWM_DATA_Y -= Step;
  386.                         if(PWM_DATA_Y < 224)
  387.                         {
  388.                                 PWM_DATA_Y = 224;
  389.                         }
  390.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  391.                 }
  392.                 //*****************************
  393.                         CheckStep = 1;
  394.                         break;
  395.                 case 7:
  396.                         if(Result_ADC[2]-Result_ADC[4]>SunValue)
  397.                         {
  398.                         Delay(DelayTime);
  399.                         PWM_DATA_Y += Step;
  400.                         PWM_DATA_X -= Step;
  401.                         if(PWM_DATA_Y >= 249)
  402.                         {
  403.                                 PWM_DATA_Y = 249;
  404.                         }
  405.                         if(PWM_DATA_X <= 224)
  406.                         {
  407.                                 PWM_DATA_X = 224;
  408.                         }
  409.                         
  410.                         
  411.                         CCAP0H = CCAP0L = PWM_DATA_X;
  412.                         CCAP1H = CCAP1L = PWM_DATA_Y;

  413.                         }
  414.                         //**************
  415.                         if(Result_ADC[4]-Result_ADC[2]>SunValue)
  416.                         {
  417.                         Delay(DelayTime);
  418.                         PWM_DATA_Y += Step;
  419.                         PWM_DATA_X += Step;
  420.                         if(PWM_DATA_X > 249)
  421.                         {
  422.                                 PWM_DATA_X = 249;
  423.                         }
  424.                         
  425.                         if(PWM_DATA_Y > 249)
  426.                         {
  427.                                 PWM_DATA_Y = 249;
  428.                         }
  429.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  430.                         CCAP0H = CCAP0L = PWM_DATA_X;
  431.                         }
  432.                         
  433.                         //$
  434.                         if((labs(Result_ADC[2]-Result_ADC[4]))<=SunValue)
  435.                         {
  436.                         Delay(DelayTime);
  437.                         PWM_DATA_Y += Step;
  438.                         if(PWM_DATA_Y > 249)
  439.                         {
  440.                                 PWM_DATA_Y = 249;
  441.                         }
  442.                         CCAP1H = CCAP1L = PWM_DATA_Y;
  443.                 }
  444.                 //***************
  445.                         CheckStep = 0;
  446.                         break;
  447.                 default:
  448.                         break;               
  449.         }
  450. }


  451. //*************************************************
  452. //函 数 名:void main(void)
  453. //输        入:无
  454. //输    出:无
  455. //功能描述: 主函数
  456. //*************************************************
  457. void main(void)
  458. {
  459.         UartInit();                                                 //初始化串口  用于测试,可删除
  460.         InitADC();                                                         //初始化ADC
  461.         TIM0_Init();                                                //初始化定时器0
  462.         PWM_Init();                                                        //初始化PWM
  463.         while(1)
  464.         {        
  465.                 SG90_Control();                                        //舵机控制
  466.         }
  467. }
  468. ***************************************************************************************
复制代码

评分

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

查看全部评分

回复

使用道具 举报

ID:505153 发表于 2019-5-6 01:23 | 显示全部楼层
有视频吗,看一下效果
回复

使用道具 举报

ID:646835 发表于 2020-5-13 19:16 | 显示全部楼层
有没有仿真图
回复

使用道具 举报

ID:65237 发表于 2020-5-13 20:40 | 显示全部楼层
谢谢分享 很好的创意
回复

使用道具 举报

ID:616559 发表于 2021-2-22 10:14 | 显示全部楼层
请问下,这个有没有原理图啊
回复

使用道具 举报

ID:706290 发表于 2022-9-21 15:33 | 显示全部楼层
提供一个原理图吧
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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