c - 使用 pic16f877a 进行太阳跟踪器步进电机仿真

标签 c pic mikroc

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

我还有另一个问题。 我已经放了2 while在开头循环,while(count2>13)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);
      }
    }
  }
}

最佳答案

am1am2 的类型为 int。这些变量保存整数值。因此,通过分配浮点值,它们将被转换为整数。因此,如果您使用

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

关于c - 使用 pic16f877a 进行太阳跟踪器步进电机仿真,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20812160/

相关文章:

c - 如何创建一个计时器/时钟,它可以将其值发回,存储在一个变量中,仅在 C 和 mikroC 上延迟

c - VS 2013错误C1853尝试构建DLL(但不使用预编译头集)

c - 如何将数字 PIC 端口读入单个变量?

c - 通用 MPLAB X、XC8 和 C。跨函数和源文件使用变量

c - MikroC 中的嵌套调用限制是什么?

compiler-construction - PIC16 C 编译器

c++ - 如何在 C/C++ 中以编程方式查找 "Saved Games"文件夹?

c - 有人用 ANSI C 写过字典( HashMap )吗?

c++ - 从有符号字符转换为无符号字符然后再转换回来?

pic - 从 MPLAB 8.92 到 MPLAB X 5.25 : how do I programmatically halt the simulator now?