使用pic16f877a的太阳跟踪器步进电机仿真

时间:2013-12-28 07:31:48

标签: c pic mikroc

我根据时间编写了双轴太阳跟踪代码。 我正在连接一张液晶显示器和照片16f877a。 我偶然发现了一个问题。 我在这里找到的问题是,如果我将其写为int am1,我输出为1.0(我希望输出显示为1.8)。这里1.8是电机的步进角。 如果我将其写为double am1,我会收到一条错误,指出运算符不适用于此操作数。 如果我把它写成long am1它没有正确旋转,即它转向1.8度然后反向3.6 *(考虑步进角为1.8 *)

我还有另一个问题。 如果不满足某些条件,我会在开头whilewhile(count2>13)放置2 while(count2<13)个循环。 现在在while循环之后它应该进入无限循环但是在无限循环中的前2个for循环之后它似乎从头开始,即while循环 只是看看有什么问题。 我发现了一些事: 如果我删除第二个while循环,即while(count2<13)程序似乎正常工作,反之亦然。如果第一个while循环被移除并且第二个保持它正常工作。 现在,我不知道是什么导致了之前的问题。

int i;
int j;
int k;
int m;
int l;

int ch;
int count=0;          //Keep track of days
int count1=0;         //Reference position of motor
int count2=13+2;      //Equator count value+(days passed since equator/7)
int count3=0;
int count4=0;         //Direction of N-S motor  0=clockwise   1=anticlockwise
int count5=0;
int count6=0;
int count7=0;
int count8=13;       //Count at equator
int am1=0.0;
int am2=0.0;
char txt1[6];
//LCD Module Connection Initialization
sbit LCD_RS at RC2_bit;
sbit LCD_EN at RC3_bit;

sbit LCD_D7 at RC7_bit;
sbit LCD_D6 at RC6_bit;
sbit LCD_D5 at RC5_bit;
sbit LCD_D4 at RC4_bit;
//End of LCD Module Connection

//Intialization of LCD Pin Direction
sbit LCD_RS_Direction at TRISC2_bit;
sbit LCD_EN_Direction at TRISC3_bit;

sbit LCD_D7_Direction at TRISC7_bit;
sbit LCD_D6_Direction at TRISC6_bit;
sbit LCD_D5_Direction at TRISC5_bit;
sbit LCD_D4_Direction at TRISC4_bit;
//End of LCD Pin Direction

void main()
{ 
  //Intialization of Ports
  TRISB=0X00;     //Initialize Port B as output
  PORTB=0X00;     //Assign Value 0 to port B
  TRISD=0X00;     //Initialize Port D as output
  PORTD=0X00;     //Assign Value 0 to port D
  //End of Initialization

  Lcd_Init();                     //Initailize LCD Module
  Lcd_Cmd(_LCD_CLEAR);            //Clear Display
  Lcd_Cmd(_LCD_CURSOR_OFF);       //Cursor Off
  while(count2>13){               //If Earth greater than 0* of the Equator
    PORTD=0X04;                   //Move stepper motor by a step
    delay_ms(500);                //Short delay
    count8++;                     //Increment value to increment motor value by 1
    if(count8==count2){           //Check if motor value = Equinox value
      PORTD=0X00;                   //Pass no current to motor
      count1=1;                     //Reference position value set
      delay_ms(500);                //Short delay
      break;
    }
    PORTD=0X02;                   //Move stepper motor by a step
    delay_ms(500);                //Short delay
    count8++;                     //Increment value to increment motor value by 1
    if(count8==count2){           //Check if motor value = Equinox value
      PORTD=0X00;                 //Pass no current to motor
      count1=2;                   //Reference position value set
      delay_ms(500);              //Short delay
      break;
    }
    PORTD=0X08;                   //Move stepper motor by a step
    delay_ms(500);                //Short delay
    count8++;                     //Increment value to increment motor value by 1
    if(count8==count2){           //Check if motor value = Equinox value
      PORTD=0X00;                 //Pass no current to motor
      count1=3;                   //Reference position value set
      delay_ms(500);              //Short delay
      break;
    }
    PORTD=0X01;                   //Move stepper motor by a step
    delay_ms(500);                //Short delay
    count8++;                     //Increment value to increment motor value by 1
    if(count8==count2){           //Check if motor value = Equinox value
      PORTD=0X00;                 //Pass no current to motor
      count1=0;                   //Reference position value set
      delay_ms(500);              //Short delay
      break;
    }
  }

  while(count2<13){      //If Earth lesser than 0* of the Equator
    PORTD=0X08;
    delay_ms(500);
    count8--;
    if(count8==count2){
      PORTD=0X00;
      count1=1;
      delay_ms(500);
      break;
    }
    PORTD=0X02;
    delay_ms(500);
    count8--;
    if(count8==count2){
      PORTD=0X00;
      count1=2;
      delay_ms(500);
      break;
    }
    PORTD=0X04;
    delay_ms(500);
    count8--;
    if(count8==count2){
      PORTD=0X00;
      count1=3;
      delay_ms(500);
      break;
    }
    PORTD=0X01;
    delay_ms(500);
    count8--;
    if(count8==count2){
      PORTD=0X00;
      count1=0;
      delay_ms(500);
      break;
    }
  }
  for(;;)                           //Infinite Loop
  {
    for(i=0;i<1;i++)                //Rotating from east to west by 1.8 every 7 minutes
    {
      PORTB=0X04;                   //Move stepper motor by a step
      delay_ms(500);                //Delay
      PORTB=0X00;                   //Pass no current to motor
      Lcd_Out(1,1,"Angle M1:");
      am1=am1+1.8;
      Lcd_Chr(1,10,48+am1);         //Output value of am1 on LCD
      Lcd_Chr_CP('.');              //To display value "."
      ch=am1*10;
      ch=ch%10;
      Lcd_Chr(1,10,48+ch);

      PORTB=0X02;                   //Move stepper motor by a step
      delay_ms(500);                //Delay
      PORTB=0X00;                   //Pass no current to motor
      am1=am1+1.8;

      PORTB=0X08;                   //Move stepper motor by a step
      delay_ms(500);                //Delay
      PORTB=0X00;                   //Pass no current to motor
      am1=am1+1.8;

      PORTB=0X01;                   //Move stepper motor by a step
      delay_ms(500);                //Delay
      PORTB=0X00;                   //Pass no current to motor
      am1=am1+1.8;
    }
    for(j=0;j<1;j++)              //Rotating from west to east
    {
      PORTB=0X08;                   //Move stepper motor by a step
      delay_ms(500);                //Delay
      am1=am1-1.8;
      PORTB=0X02;                   //Move stepper motor by a step
      delay_ms(500);                //Delay
      am1=am1-1.8;
      PORTB=0X04;                   //Move stepper motor by a step
      delay_ms(500);                //Delay
      am1=am1-1.8;
      PORTB=0X01;                   //Move stepper motor by a step
      delay_ms(500);                //Delay
      am1=am1-1.8;
      count++;
    }
    if(count==2){                 //For 7 days ((365/94)=3.80) --> (1.8*3.80 = 6.84 = 7 days)
      if(count4==0){                //Reference that motor moving in clockwise  direction
        switch(count1){               //Reference position the motor stopped
          case 0:
            {
              if (count2==26){             //One end of Equinox = 23.5* --> For 47 degrees  ((47/1.8) = 26.11) =26 steps
                count4=1;                     //Reference that motor should move in anti-clockwise direction
                break;
              }
              PORTD=0X04;                   //Move stepper motor by a step
              count=0;                      //Reset 7 day counter to 0
              count1=1;                     //Reference position value set
              delay_ms(500);                //delay
              count2=count2++;              //Increment Equinox Step by 1
            }
            break;
          case 1:
            {
              if (count2==26){             //One end of Equinox = 23.5*
                count4=1;                     //Reference that motor should move in anti-clockwise direction
                break;
              }
              PORTD=0X02;                   //Move stepper motor by a step
              count1=2;                     //Reference position value set
              count=0;                      //Reset 7 day counter to 0
              delay_ms(500);                //delay
              count2=count2++;              //Increment Equinox Step by 1
            }
            break;
          case 2:
            {
              if (count2==26){             //One end of Equinox = 23.5*
                count4=1;                     //Reference that motor should move in anti-clockwise direction
                break;
              }
              PORTD=0X08;                   //Move stepper motor by a step
              count1=3;                     //Reference position value set
              count=0;                      //Reset 7 day counter to 0
              delay_ms(500);                //delay
              count2=count2++;              //Increment Equinox Step by 1
              break;
            }
          case 3:
            {
              if (count2==26){             //One end of Equinox = 23.5*
                count4=1;                     //Reference that motor should move in anti-clockwise direction
                break;
              }
              PORTD=0X01;               //Move stepper motor by a step
              count1=0;                     //Reference position value set
              count=0;                      //Reset 7 day counter to 0
              delay_ms(500);                //delay
              count2=count2++;              //Increment Equinox Step by 1
              break;
            }
        }
      }
      if(count4==1){                        //Reference that motor should move in anti-clockwise direction
        switch(count5){
          case 0:
            {
              if (count2==0){               //One end of Equinox = 23.5*
                count4=0;                     //Reference that motor should move in clockwise direction
                break;
              }
              switch(count1){              //Reference position of the motor
                case 0:
                  {
                    count6=1;
                    break;
                  }
                case 1:
                  {
                    count6=4;
                    break;
                  }
                case 2:
                  {
                    count6=3;
                    break;
                  }
                case 3:
                  {
                    count6=2;
                    break;
                  }
              }
            }
        }
        switch(count6){
          case 1:
            {
              if (count2==0){               //One end of Equinox = 0.0*
                count4=0;                     //Reference that motor should move in clockwise direction
                break;
              }
              PORTD=0X08;                   //Move stepper motor by a step
              count=0;                      //Reset 7 day counter to 0
              count1=3;                     //Reference position value set
              delay_ms(500);                //delay
              count2=count2-1;              //Decrement Equinox Step by 1
              break;
            }
          case 2:
            {
              if (count2==0){              //One end of Equinox = 0.0*
                count4=0;                     //Reference that motor should move in clockwise direction
                break;
              }
              PORTD=0X02;                   //Move stepper motor by a step
              count1=2;                     //Reference position value set
              count=0;                      //Reset 7 day counter to 0
              delay_ms(500);                //delay
              count2=count2-1;              //Decrement Equinox Step by 1
              break;
            }
          case 3:
            {
              if (count2==0){              //One end of Equinox = 0.0*
                count4=0;                     //Reference that motor should move in clockwise direction
                break;
              }
              PORTD=0X04;                   //Move stepper motor by a step
              count1=1;                     //Reference position value set
              count=0;                      //Reset 7 day counter to 0
              delay_ms(500);                //delay
              count2=count2-1;              //Decrement Equinox Step by 1
              break;
            }
          case 4:
            {
              if (count2==0){              //One end of Equinox = 0.0*
                count4=0;                     //Reference that motor should move in clockwise direction
                break;
              }
              PORTD=0X01;               //Move stepper motor by a step
              count1=0;                     //Reference position value set
              count=0;                      //Reset 7 day counter to 0
              delay_ms(500);                //delay
              count2=count2-1;              //Decrement Equinox Step by 1
              break;
            }
        }
      }
      if (count2==0){                       //One end of Equinox = 0.0*
        count4=0;                     //Reference that motor should move in clockwise direction
      }
    }
    else
    {
      for (l=0;l<2;l++){                   //Delay for the rest of the 12 hours
        delay_ms(431);
      }
    }
  }
}

1 个答案:

答案 0 :(得分:1)

am1am2属于int类型。这些变量保持整数值。因此,通过指定浮点值,它们将被转换为整数。所以如果你使用

am1 = 1.8; am1的实际值为1.