单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:4930|回复:8
打印上一主题下一主题

太阳能跟踪系统程序

 [复制链接]
跳转到指定楼层
楼主
ID:191473发表于 2017-5-31 03:32|只看该作者回帖奖励
#include< reg52.h>                 //
#include< LCD1602.H>
#include "DS1302.h"
#include<intrins.h>

sfr ADC_CONTR = 0xBC; //ADC control register
sfr ADC_RES = 0xBD; //ADC hight 8-bit result register
sfr ADC_RESL = 0xBE; //ADC low 2-bit result register
sfr P1ASF = 0x9D; //P1 secondary function control register

sbit xiay  = P3^0;   //定义

sbit key1  = P3^2;   //定义 选择键
sbit key2  = P3^3;   //定义 加 按键端口
sbit key3  = P3^4;   //定义 减 按键端口
sbit key4  = P3^5;   //定义  
sbit key5  = P3^6;   //定义
sbit pwm0  = P2^0;                   //纵向舵机驱动端口
sbit pwm1  = P2^1         ;                   //横向舵机驱动端口

#define uchar unsigned char       //宏定义       unsigned char字符为uchar
#define uint unsigned int       //宏定义       unsigned int
#define ulint unsigned long int //宏定义

/*定义相关特殊功能寄存器*/
#define ADC_POWER 0x80 //ADC power control bit
#define ADC_FLAG 0x10 //ADC complete flag
#define ADC_START 0x08 //ADC start control bit
#define ADC_SPEEDLL 0x00 //540 clocks
#define ADC_SPEEDL 0x20 //360 clocks
#define ADC_SPEEDH 0x40 //180 clocks
#define ADC_SPEEDHH 0x60 //90 clocks

uint guangmin_0=0,guangmin_1=0,guangmin_2=0,guangmin_3=0;  //光敏值变量
uchar xdata Temp[16]="13-04-30   :  G ";
uchar xdata Test[16]="19:14:00   :  K ";
uchar xdata Temp1[16]="X:     Y:     ";
uchar xdata Test1[16]="guangzhao:     ";
uchar xdata Temp2[16]=" G0     G1     ";
uchar xdata Test2[16]=" G2     G3     ";

uint nian,yue,ri,shi,fen,miao;
int _shi=18,_fen=30;           //停止时间变量
int shi_=6,fen_=30;             //启动时间变量
uchar set=0,set1=0,set2=0;       //模式控制变量
uchar xian=0;                     //显示模式标志变量
uint GZ;                           //光照变量
uchar X,Y;                         //角度变量

uint js=0;                             //标志位变量
uint b=107,d=107;                           //角度控制变量

void Delay1us()         //@12.000MHz
{
     _nop_();
     _nop_();
     _nop_();
     _nop_();
}
void InitADC()
{
     P1ASF = 0xf0; //Set all P1 as analog input port 0xff=1111 1111B 即P1全部用作AD,使用时根据实际情况赋值
     ADC_RES = 0;  //清零转换结果寄存器高8位
     ADC_RESL= 0;  //清零转换结果寄存器低2位
     ADC_CONTR = 0x00;
     Delay1us();   //等待ADC_CONTR值写入
     _nop_();
     _nop_();
     _nop_();
     _nop_();
}
unsigned int GetADC(unsigned char ch,unsigned char speed)
{
     unsigned int res;
   ADC_CONTR =ADC_CONTR | ADC_POWER | speed | ADC_START | ch;
     Delay1us();//确保ADC_CONTR的值写入nop; nop; nop; nop;
     while(!(ADC_CONTR& ADC_FLAG)); //如果AD转换未结束FLAG位为0,程序在此等待,如果为1,跳出循环
     res=ADC_RES*4+ADC_RESL; //读AD转换结果
     ADC_RES=0;
     ADC_RESL=0;
     ADC_CONTR=0; //寄存器复位
     return res;
}
void readtime()
{
     nian= BCD_Decimal(read_1302(0x8d));
     yue = BCD_Decimal(read_1302(0x89));
     ri  = BCD_Decimal(read_1302(0x87));
     shi = BCD_Decimal(read_1302(0x85));
     fen = BCD_Decimal(read_1302(0x83));
     miao= BCD_Decimal(read_1302(0x81));
}
uchar key_bcd(uchar key_decimal)               //转成ds1302所需的BCD码
{
     uchar temp;
     temp=(((key_decimal/10)&0x0f)<<4)|(key_decimal%10);
     return temp;    
}
void keyscan()
{
//-----------------------------模式键key1----------------------------        
     if(key1==0&&xian==0)  
     {
       //delay(5);
       if(key1==0)
       {
       //delay(10);
         while(!key1);
           set++;
           set1=0;
           set2=0;
           if(set>6)set=0;
       }
     }
//-----------------------------模式键key4----------------------------        
     if(key4==0&&xian==0)  
     {
       //delay(5);
       if(key4==0)
       {
       //delay(10);
         while(!key4);
           set=0;
           set1++;
           set2=0;
           if(set1>2)set1=0;
       }
     }
//-----------------------------模式键key5----------------------------        
     if(key5==0&&xian==0)  
     {
       //delay(5);
       if(key5==0)
       {
       //delay(10);
         while(!key5);
           set=0;
           set1=0;
           set2++;
           if(set2>2)set2=0;
       }
     }      
//-----------------------------key2----------------------------        
     if(key2==0)  
     {
       //delay(2);
       if(key2==0)
       {
       //delay(5);
         while(!key2);
            
             switch(set)
               {
                   case 1: nian++;
                       if(nian>99)nian=0;
                         write_1302(0x8e,0x00);
                         write_1302(0x8c,key_bcd(nian)| 0x80);
                         write_1302(0x8e,0x80);                    
                         break;              
                   case 2: yue++;
                       if(yue>12)yue=1;
                         write_1302(0x8e,0x00);
                         write_1302(0x88,key_bcd(yue));
                         write_1302(0x8e,0x80);                    
                         break;        
                   case 3: ri++;
                       if(ri>31)ri=1;
                         write_1302(0x8e,0x00);
                         write_1302(0x86,key_bcd(ri));
                         write_1302(0x8e,0x80);                    
                         break;    

                   case 4: shi++;
                       if(shi>23)shi=0;
                         write_1302(0x8e,0x00);
                         write_1302(0x84,key_bcd(shi));
                         write_1302(0x8e,0x80);                    
                         break;              
                   case 5: fen++;
                       if(fen>59)fen=0;
                         write_1302(0x8e,0x00);
                         write_1302(0x82,key_bcd(fen));
                         write_1302(0x8e,0x80);                    
                         break;        
                   case 6: miao++;
                       if(miao>59)miao=0;
                         write_1302(0x8e,0x00);
                         write_1302(0x80,key_bcd(miao)&0x7f);
                         write_1302(0x8e,0x80);                    
                         break;        
               }
           switch(set1)
               {
                   case 1: _shi++;
                       if(_shi>23)_shi=23;                    
                         break;              
                   case 2: _fen++;
                       if(_fen>59)_fen=0;
                         break;                
               }
           switch(set2)
               {
                   case 1: shi_++;
                       if(shi_>_shi)shi_=_shi;                    
                         break;              
                   case 2: fen_++;
                       if(fen_>59)fen_=0;
                         break;                
               }

       }
     }
//-----------------------------key3----------------------------        
     if(key3==0)  
     {
       //delay(2);
       if(key3==0)
       {
       //delay(5);
         while(!key3);
           if(set==0&&set1==0&&set2==0)
           {
                 xian++;
             if(xian>2)xian=0;
               b++;d++;
           }          
             switch(set)
               {
                   case 1: nian--;
                       if(nian>99)nian=99;
                         write_1302(0x8e,0x00);
                         write_1302(0x8c,key_bcd(nian)| 0x80);
                         write_1302(0x8e,0x80);                    
                         break;              
                   case 2: yue--;
                       if(yue>12)yue=12;
                         write_1302(0x8e,0x00);
                         write_1302(0x88,key_bcd(yue));
                         write_1302(0x8e,0x80);                    
                         break;        
                   case 3: ri--;
                       if(ri>31)ri=31;
                         write_1302(0x8e,0x00);
                         write_1302(0x86,key_bcd(ri));
                         write_1302(0x8e,0x80);                    
                         break;    

                   case 4: shi--;
                       if(shi>23)shi=23;
                         write_1302(0x8e,0x00);
                         write_1302(0x84,key_bcd(shi));
                         write_1302(0x8e,0x80);                    
                         break;              
                   case 5: fen--;
                       if(fen>59)fen=59;
                         write_1302(0x8e,0x00);
                         write_1302(0x82,key_bcd(fen));
                         write_1302(0x8e,0x80);                    
                         break;        
                   case 6: miao--;
                       if(miao>59)miao=59;
                         write_1302(0x8e,0x00);
                         write_1302(0x80,key_bcd(miao)&0x7f);
                         write_1302(0x8e,0x80);                    
                         break;                
               }
           switch(set1)
               {
                   case 1: _shi--;
                       if(_shi<shi_)_shi=shi_;                    
                         break;              
                   case 2: _fen--;
                       if(_fen<0)_fen=59;
                         break;                
               }
           switch(set2)
               {
                   case 1: shi_--;
                       if(shi_<0)shi_=0;                    
                         break;              
                   case 2: fen_--;
                       if(fen_<0)fen_=59;
                         break;                
               }
       }
     }
}
uchar ttt;
void display()
{
   if(xian==0)                   //显示模式0
     {
         ttt++;
         if(ttt>5)ttt=0;
         if(set==1)
         {
             if(ttt>2)
             {
               Temp[0]=nian/10+'0';
               Temp[1]=nian%10+'0';
             }
             else
             {
               Temp[0]=' ';
               Temp[1]=' ';        
             }
         }
         else
         {
               Temp[0]=nian/10+'0';
               Temp[1]=nian%10+'0';    
         }
    
         if(set==2)
         {
             if(ttt>2)
             {
               Temp[3]=yue/10+'0';
               Temp[4]=yue%10+'0';
             }
             else
             {
               Temp[3]=' ';
               Temp[4]=' ';        
             }
         }
         else
         {
               Temp[3]=yue/10+'0';
               Temp[4]=yue%10+'0';    
         }
    
         if(set==3)
         {
             if(ttt>2)
             {
               Temp[6]=ri/10+'0';
               Temp[7]=ri%10+'0';
             }
             else
             {
               Temp[6]=' ';
               Temp[7]=' ';        
             }
         }
         else
         {
               Temp[6]=ri/10+'0';
               Temp[7]=ri%10+'0';    
         }
         if(set1==1)
         {
             if(ttt>2)
             {
               Temp[9]=_shi/10+'0';
               Temp[10]=_shi%10+'0';
             }
             else
             {
               Temp[9]=' ';
               Temp[10]=' ';        
             }
         }
         else
         {
               Temp[9]=_shi/10+'0';
               Temp[10]=_shi%10+'0';    
         }
         if(set1==2)
         {
             if(ttt>2)
             {
               Temp[12]=_fen/10+'0';
               Temp[13]=_fen%10+'0';
             }
             else
             {
               Temp[12]=' ';
               Temp[13]=' ';        
             }
         }
         else
         {
               Temp[12]=_fen/10+'0';
               Temp[13]=_fen%10+'0';    
         }
         ShowString(0,Temp);
    
         if(set==4)
         {
             if(ttt>2)
             {
               Test[0]=shi/10+'0';
               Test[1]=shi%10+'0';
             }
             else
             {
               Test[0]=' ';
               Test[1]=' ';        
             }
         }
         else
         {
               Test[0]=shi/10+'0';
               Test[1]=shi%10+'0';    
         }
    
         if(set==5)
         {
             if(ttt>2)
             {
               Test[3]=fen/10+'0';
               Test[4]=fen%10+'0';
             }
             else
             {
               Test[3]=' ';
               Test[4]=' ';        
             }
         }
         else
         {
               Test[3]=fen/10+'0';
               Test[4]=fen%10+'0';    
         }
    
         if(set==6)
         {
             if(ttt>2)
             {
               Test[6]=miao/10+'0';
               Test[7]=miao%10+'0';
             }
             else
             {
               Test[6]=' ';
               Test[7]=' ';        
             }
         }
         else
         {
               Test[6]=miao/10+'0';
               Test[7]=miao%10+'0';    
         }
         if(set2==1)
         {
             if(ttt>2)
             {
               Test[9]=shi_/10+'0';
               Test[10]=shi_%10+'0';
             }
             else
             {
               Test[9]=' ';
               Test[10]=' ';        
             }
         }
         else
         {
               Test[9]=shi_/10+'0';
               Test[10]=shi_%10+'0';    
         }
         if(set2==2)
         {
             if(ttt>2)
             {
               Test[12]=fen_/10+'0';
               Test[13]=fen_%10+'0';
             }
             else
             {
               Test[12]=' ';
               Test[13]=' ';        
             }
         }
         else
         {
               Test[12]=fen_/10+'0';
               Test[13]=fen_%10+'0';    
         }
         ShowString(1,Test);
     }
     if(xian==1)                       //显示模式1
     {
       Y=b;
       X=d;
       GZ=(guangmin_0+guangmin_1+guangmin_2+guangmin_3)/4;
       if(X<=107)
       {
             X=107-X;
           Temp1[3]='-';           //角度数值转换显示
           Temp1[4]=X/100%10+'0';
           Temp1[5]=X/10%10+'0';
           Temp1[6]=X%10+'0';
       }
       if(X>=107)
       {
             X=X-107;
           Temp1[3]='+';           //角度数值转换显示
           Temp1[4]=X/100%10+'0';
           Temp1[5]=X/10%10+'0';
           Temp1[6]=X%10+'0';
       }
      
       if(Y<=107)
       {
             Y=107-Y;
           Temp1[11]='-';           //角度数值转换显示
           Temp1[12]=Y/100%10+'0';
           Temp1[13]=Y/10%10+'0';
           Temp1[14]=Y%10+'0';
       }
       if(Y>=107)
       {
             Y=Y-107;
           Temp1[11]='+';           //角度数值转换显示
           Temp1[12]=Y/100%10+'0';
           Temp1[13]=Y/10%10+'0';
           Temp1[14]=Y%10+'0';
       }

       Test1[10]=GZ/1000+'0';           //光敏数值转换显示
       Test1[11]=GZ/100%10+'0';
       Test1[12]=GZ/10%10+'0';
       Test1[13]=GZ%10+'0';
       ShowString(0,Temp1);
       ShowString(1,Test1);
     }
     if(xian==2)                           //显示模式2
     {
      
       Temp2[4]=guangmin_0/1000+'0';           //光敏数值转换显示
       Temp2[5]=guangmin_0/100%10+'0';
       Temp2[6]=guangmin_0/10%10+'0';
       Temp2[7]=guangmin_0%10+'0';
      
       Temp2[11]=guangmin_1/1000+'0';           //光敏数值转换显示
       Temp2[12]=guangmin_1/100%10+'0';
       Temp2[13]=guangmin_1/10%10+'0';
       Temp2[14]=guangmin_1%10+'0';
      
       Test2[4]=guangmin_2/1000+'0';           //光敏数值转换显示
       Test2[5]=guangmin_2/100%10+'0';
       Test2[6]=guangmin_2/10%10+'0';
       Test2[7]=guangmin_2%10+'0';
      
       Test2[11]=guangmin_3/1000+'0';           //光敏数值转换显示
       Test2[12]=guangmin_3/100%10+'0';
       Test2[13]=guangmin_3/10%10+'0';
       Test2[14]=guangmin_3%10+'0';
      
       ShowString(0,Temp2);
       ShowString(1,Test2);          
     }
}
void timer0_irpt()interrupt 1       //中断1服务程序
{
       TH0 = (65536-10)/256;       //重装计数值          
   TL0 = (65536-10)%256;           //重装计数值
       js++;                           //a自加1
       if(js==2000)                   //如果a等于2000
       {
         pwm0=1;
           pwm1=1;                   //纵向舵机驱动端口取反
         js=0;                       //把a置0
       }
       else                           //否则判断a是否等于b
       {
       if(js==b){pwm0=0;}             //如果等于就把纵向舵机驱动端口取反
       if(js==d){pwm1=0;}
       }
}
void chushihua()           //内部中断初始化函数
{
       TMOD = 0x01;           //将计数器设置为工作方式1
     TH0 = (65536-10)/256;     //给计数器高八位赋值              
     TL0 = (65536-10)%256;       //给计数器低八位赋值
     EA = 1;                     //开总中断
     ET0 = 1;               //开中断1  
     TR0 = 1;  
}
void pianzhuankongzhi(void)
{
                                                  

          
           if(((guangmin_0+guangmin_1)-10)<(guangmin_2+guangmin_3))
           {
                 b--;
               if(b<45){b=45;}
           }
           if(((guangmin_2+guangmin_3)-10)<(guangmin_0+guangmin_1))
           {
                 b++;
               if(b>140){b=140;}
           }
           Delay1us();
           if(((guangmin_3+guangmin_0)-10)<(guangmin_1+guangmin_2))
           {
                 d--;
               if(d<45){d=45;}
           }
           if(((guangmin_1+guangmin_2)-10)<(guangmin_3+guangmin_0))
           {
                 d++;
               if(d>170){d=170;}
           }
      

}
void main(void)
{    
     InitADC();                       //ADC初始化
   InitLcd_LCD1602();               //液晶初始化
     ds1302_init();                 //DS1302初始化
     chushihua();                 //PWM中断初始化
     while(1)
     {
             readtime();     //读取时间
           display();                   //显示控制
           keyscan();                 //按键控制

             if(((shi*60+fen)>=(shi_*60+fen_))&&((shi*60+fen)<=(_shi*60+_fen-1)))         //判断时间段开跟踪
           {      
                       guangmin_0=GetADC(0,ADC_SPEEDLL);
                       guangmin_1=GetADC(1,ADC_SPEEDLL);
                
                       guangmin_2=GetADC(2,ADC_SPEEDLL);
                       guangmin_3=GetADC(3,ADC_SPEEDLL);
                
                       pianzhuankongzhi();           //舵机控制
                       EA=1;                    
           }
           else
           {
               EA=0;
           }                                                  
                                          
     }
}


沙发
ID:184237发表于 2017-7-7 17:59|只看该作者
ad 用的是哪款芯片啊,追踪机理 是判断光敏然后控制舵机吗?直接看程序有些费力,能发实物图吗     之前我接触过的太阳能追踪是机制是   四个光敏以‘+’姿态放在一个板子上,假如左光敏光照强度大于右光敏,用2803控制电机左右转向,  上下部分也是如此,总共利用两个电机
板凳
ID:284437发表于 2018-2-19 02:37|只看该作者
有仿真图吗?
地板
ID:499744发表于 2019-3-28 11:05|只看该作者
感谢分享
5#
ID:350104发表于 2019-3-29 13:45|只看该作者
希望能补全资料
6#
ID:725830发表于 2020-4-9 22:50|只看该作者
大佬,有仿真图吗?
7#
ID:697141发表于 2020-4-23 23:21来自手机|只看该作者
非常好,要是有原理图就更好了,谢谢
8#
ID:621943发表于 2020-5-20 16:59|只看该作者
如果是位置跟随或者说角度跟随的话 比如天线的 需要把光明传感器换成什么呢 请指教谢谢
9#
ID:149799发表于 2020-6-7 19:52|只看该作者
这个不错,谢谢分享。

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

Powered by 单片机教程网