Моделирование шагового двигателя Sun tracker с помощью pic16f877a
Я написал код для двухосного отслеживания солнца, основанный на времени. Я взаимодействую с ЖКИ с рис. 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
цикл Просто посмотри в чем проблема. Я кое-что заметил: если я уберу 2й while
петля, т.е. while(count2<13)
Программа, кажется, работает правильно, и наоборот. Если 1-й while
петля удалена и 2-ая сохранена, она работает правильно. Теперь я не знаю, что вызвало предыдущую проблему.
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 ответ
am1
а также am2
имеют тип int
, Эти переменные содержат целочисленные значения. Таким образом, присваивая значения с плавающей точкой, они будут преобразованы в целые числа. Так что если вы, например, используете
am1 = 1.8;
фактическая стоимость am1
будет 1.