Run a motor, urgent help needed plz

Status
Not open for further replies.

zesla

New Member
Hi guys,

Sorry but I need urgent help.

I want to run a stepper motor clockwise and anticlockwise by an ATMEGA16.
Can you guys please tell me what's the problem of the below instructions to do so?:


while (1)
{
if(PINB.0==0)
{
for(y=1;(PINB.0==0)&&(y<=x);y=y+1)
{
z=z+1;
if(z==1) PORTD=8;
if(z==2) PORTD=4;
if(z==3) PORTD=2;
if(z==4)
{
PORTD=1;
z=0;
}}}
delay_ms(10);
if (PINB.1==0)
{
for(y=1;(PINB.1==0)&&(y<=x);y=y+1)
{
z=z+1;
if(z==1) PORTD=1;
if(z==2) PORTD=2;
if(z==3) PORTD=4;
if(z==4)
{
PORTD=8;
z=1;
}} }
delay_ms(10);

}
}
 
Here's the whole instruction if needed.

Chip type : ATmega16
Program type : Application
Clock frequency : 4.000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega16.h>
#include <delay.h>


// Declare your global variables here

void main(void)
{char x,y,z=0;
x=PINA;

// Declare your local variables here

// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;

// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=P State0=P
PORTB=0x03;
DDRB=0x00;

// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0x0F;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

while (1)
{
if(PINB.0==0)
{
for(y=1;(PINB.0==0)&&(y<=x);y=y+1)
{
z=z+1;
if(z==1) PORTD=8;
if(z==2) PORTD=4;
if(z==3) PORTD=2;
if(z==4)
{
PORTD=1;
z=0;
}}}
delay_ms(10);
if (PINB.1==0)
{
for(y=1;(PINB.1==0)&&(y<=x);y=y+1)
{
z=z+1;
if(z==1) PORTD=1;
if(z==2) PORTD=2;
if(z==3) PORTD=4;
if(z==4)
{
PORTD=8;
z=1;
}} }
delay_ms(10);

}
}
 
First, try writing code so that it can actually be read and understood if you plan to show it others for review. Here is your code in more readable form:

Code:
while(1){

    if(PINB.0==0){
        for(y=1;(PINB.0==0)&&(y<=x);y=y+1){
    
            z=z+1;
            if(z==1) PORTD=8;
            if(z==2) PORTD=4;
            if(z==3) PORTD=2;
            
            if(z==4){
                PORTD=1;
                z=0;
            }
        }
    }
    
    delay_ms(10);
    
    if (PINB.1==0){ 
        for(y=1;(PINB.1==0)&&(y<=x);y=y+1){
            z=z+1;
            if(z==1) PORTD=1;
            if(z==2) PORTD=2;
            if(z==3) PORTD=4;
            
            if(z==4){
                PORTD=8;
                z=1;
            }
        }
    }
    
    delay_ms(10);
}



Now, what is this FOR-loop supposed to do?

Code:
for(y=1; (PINB.0==0)&&(y<=x); y=y+1){

        z=z+1;
        if(z==1) PORTD=8;
        if(z==2) PORTD=4;
        if(z==3) PORTD=2;
        
        if(z==4){
            PORTD=1;
            z=0;
        }
 }

That runs quite fast on a 4 Mhz processor. Should you have some delays in it? How many times it should loop? What are x, y and z variables?
 
Last edited:
Yes, please use the (CODE) and (/CODE) tags around your code! (use SQUARE brackets)

Your code seems badly designed.

The typical way to drive a stepper motor is to debounce the input "step" pin (very important!) and then sequence the 4 steps based on the state of the direction pin.

something like this;
Code:
// PORBT.0 = STEP pin input
// PORTB.1 = DIRECTION pin input
// PORTD = stepper motor 4 outputs (3-0) 

while(1)
{
  while(PINB.0 == 1) continue;  // wait here for STEP pin to go lo \
  delay_ms(10);   // debounce delay
  while(PINB.0 == 0) continue;  // now wait here for STEP pin to go hi /
  delay_ms(10);   // debounce delay

  // now step forward or backward 1 step
  if(PINB.1 == 0)   // DIR input pin is forward
  {
    mask = (mask >> 1);
    if(mask == 0) mask = 0b00001000;
  }
  else     // else DIR pin is backward
  {
    mask = (mask << 1);
    if(mask == 0b00010000) mask = 0b00000001;
  }

  // finally put the mask to PORTD for stepper motor pins
  PORTD = mask;
}

Is easier to read and to understand.
 

Thanks sir,

Can you please do me a favor and give me the whole instruction so that I could simulate it in Porous? Port A has to have several keys to determine the rate of turns of the 4 phase stepper motor.
 
I think he means the micro is actually generating the step pulse itself, and that the PORTA pins will be a binary code to set the motor speed.

Zesla, no I won't give you the whole instruction you will have to do some things for yourself!

However here is an idea for PORTA setting the motor speed and motor running continuously;

Code:
// PORTA = motor speed control inputs (pins 2-0)
// PORTB.1 = DIRECTION pin input
// PORTD = stepper motor 4 outputs (pins 3-0) 

while(1)
{
  // this delay set the motor speed! Delay is 5mS to 40mS (in 8 speeds)
  delay_ms(5);
  if(PORTA.0) delay_ms(5); 
  if(PORTA.1) delay_ms(10); 
  if(PORTA.2) delay_ms(20); 

  // now step forward or backward 1 step
  if(PINB.1 == 0)   // DIR input pin is forward
  {
    mask = (mask >> 1);
    if(mask == 0) mask = 0b00001000;
  }
  else     // else DIR pin is backward
  {
    mask = (mask << 1);
    if(mask == 0b00010000) mask = 0b00000001;
  }

  // finally put the mask to PORTD for stepper motor pins
  PORTD = mask;
}

Good luck.
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…