CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

VID29 stepper motor control problem

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
moksan



Joined: 19 Oct 2015
Posts: 1

View user's profile Send private message

VID29 stepper motor control problem
PostPosted: Mon Oct 19, 2015 3:38 am     Reply with quote

Hi, I'm trying to VID29 stepper motor control with 16F1937. But I have a problem. Motor does not turn as I wanted. Frequency enter the RB0 and internal ext. Motor based on the value of the frequency I want to convert back and forth. Motor pins(coil) connected to port c.

Code:
#include <main.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=20M)
#use fast_io(b)
#use fast_io(c)

unsigned long long int t,new=0;
float f;
const int back[]={0x06,0x02,0x0B,0x09,0x0D,0x04};
const int forth[]={0x04,0x0D,0x09,0x0B,0x02,0x06};
int old=0

void main()


   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

   set_timer1(0);
   set_tris_c(0x00);
   set_tris_b(0x03);
   
   output_c(0);
   output_b(0);

   while(1)
   {

   f=t*0.0000016;
   f=1/f;
   f=f/5;
   new=f;

   if(new>old)
     {
     while(old<new)
       {

      for(i=0;i<=6;i++)
      {
         output_c(forth[i]);
         delay_ms(30);
      }
      old++;
      }
   }

if(old>new)
   {
  while(old>new)
     {

      for(i=0;i<=6;i++)
      {
         output_c(back[i]);
         delay_ms(30);
      }
      old--;
     }   
   }
 }
}

#int_ext
void timer1_kesme()
{
disable_interrupts(GLOBAL);
t=get_timer1();
set_timer1(0);
enable_interrupts(GLOBAL);
}

#int_timer1
void ext_kesmesi()
{
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Oct 19, 2015 4:41 am     Reply with quote

Your code has several bugs:

Quote:
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=20M)

This indicates you are probably running this in Proteus. That's because
Proteus doesn't care about oscillator fuses. In real hardware, you need
the HS fuse to run the oscillator at 20 MHz.


Quote:

const int back[]={0x06,0x02,0x0B,0x09,0x0D,0x04};
const int forth[]={0x04,0x0D,0x09,0x0B,0x02,0x06};

for(i=0;i<=6;i++)
{
output_c(forth[i]);
delay_ms(30);
}

for(i=0;i<=6;i++)
{
output_c(back[i]);
delay_ms(30);
}

Your arrays have 6 elements, which are numbered from 0 to 5 in the C
language. But your for() loops are using "less than or equal to 6" as
the test. This means your loop will run for indexes (i) from 0 to 6, which
is 7 array elements. You are running past the ends of your arrays.

If you want a loop counter that does 6 iterations and starts at 0, use
"less than" as the test. This will count from 0 to 5 and will do 6 passes
through the loop. Example:
Quote:

for(i=0;i<6;i++)
{

}

This is true in the whole of C programming. Always remember this one.
If you ever have any doubts about how a for() loop works, run a simple
test program in MPLAB simulator, or run it in hardware. The program
below has the following output. You can see that the "i <= 6" test makes
the loop have 7 passes, from 0 to 6. That's bad if your arrays have
only 6 elements.
Quote:
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6

Test program:
Code:
#include <18F4620.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)

//=============================
void main()
{
int8 i;
   
for(i=0;i<=6;i++)
  {
   printf("i = %u \r", i);
  }

while(TRUE);
}




Quote:
#int_ext
void timer1_kesme()
{
disable_interrupts(GLOBAL);
t=get_timer1();
set_timer1(0);
enable_interrupts(GLOBAL);
}

This is probably copied from some other compiler. Don't do this (in bold)
in CCS. Delete those two lines. These two lines are handled by the PIC
hardware and by the compiler. If you put in those lines, your program
will eventually crash when the timer1 interrupt occurs while your program
is in the exit code of the CCS interrupt handler.
Ttelmah



Joined: 11 Mar 2010
Posts: 19504

View user's profile Send private message

PostPosted: Mon Oct 19, 2015 8:09 am     Reply with quote

I'd have to actually say it might well be for a different chip, rather than just a different compiler!... Twisted Evil

It is _vital_ that an interrupt can't occur inside itself.
Different chips handle "how not to enable interrupts till you are actually 'out of' the handler" in different ways.

On some chips, the 'enable interrupt' instruction does not enable interrupts till the _next_ instruction. So you can code the last two instructions of the interrupt handler, as:

enable_interrupt
return

(in the particular syntax for the chip obviously), and the actual interrupt does not get enabled till after the return.

I'd suspect the code has been copied from a chip where this is the case.

The PIC instead has a special 'return from interrupt' instruction, that automatically enables the interrupts after it executes.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group