Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
ar_hoseini
PostPosted: May 15, 2012 - 10:29 AM
Newbie


Joined: Apr 04, 2012
Posts: 3


Hi all
I need to control a DC motor for a RC car using AVR Atmega1281. I used one PWM channel for Forward, one for Backward (because of the H-bridge design). since I didn't have any experience in PWM I read about it then wrote the following code, however when it comes to alter PWM Speed
I get a fixed PWM output result
which is always %10 (checked by oscilloscope)
no matter what value I assigned to ICR3 register since Timer 3 (channel B and C one for CW, one for CCW rotation) have been used.
Output_PWM_Frequency is 200 Hz. (pre-scalar 8, TOP 2500).
using Phase and frequency correct PWM mode I set a TOP value in ICR3.

I’d be thankful if you gave me a hint to solve this issue
(F_CPU is 8 MHz).


Last edited by ar_hoseini on May 15, 2012 - 12:01 PM; edited 6 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
ar_hoseini
PostPosted: May 15, 2012 - 10:31 AM
Newbie


Joined: Apr 04, 2012
Posts: 3


Code:
// headerfile
#include <avr/io.h>
#include <avr/interrupt.h>
#include "delay.h"

#define F_CPU 8000000UL
#define OC3C_PORT E
#define OC3C_PIN PE5
#define OC3B_PORT E
#define OC3B_PIN PE4

#define DDR(a) __CONCAT(DDR,a)
#define PORT(a) __CONCAT(PORT,a)
#define PIN(a) __CONCAT(PIN,a)

#define HALT    0
#define LEFT   1
#define RIGHT   2
#define FORWARD    1
#define BACKWARD 2

void MotorInit();
void Motor_Dir(uint8_t dir);
void Motor_Speed(uint8_t dir,uint8_t speed);

Code:
void MotorInit()
{

   //  DEFINING SPEED OF PWM
      TCCR3A= (1<<COM3B1)|(1<<COM3C1);   // Clear OC3B & OC3C on compare match
      TCCR3B |= (1<<WGM33); // Phase and frequency correct PWM mode
         
   //  CLOCK SPEED = F_CPU/ RESCALAR--------PRESCALAR = 8
       TCCR3B |= (1<<CS31);
      ICR3 = 1250; // 200 Hz
   
   //  SET THE PINS TO OUTPUT
      DDR(OC3C_PORT)|=(1<<OC3C_PIN);
      DDR(OC3B_PORT)|=(1<<OC3B_PIN);

   //  DEFINE OUTPUT FOR CONTROL PINS
      DDRE|=0X0F;   //  PE4 to PE7 as output
      
}

/*----------------------------------------------------
DEFINING SPEED (0 TO 255) & DIRECTION OF THE MOTOR_Speed

DIR = 0 for STOP ROTAION
     = 1 for FORWARD
     = 2 for BACKWARD
----------------------------------------------------*/
void Motor_Speed(uint8_t dir,uint8_t speed)
{
   //  DIRECTION
   if(dir == 0)
   {
      PORTE&=(~(1<<PE4));
      PORTE&=(~(1<<PE5));
   }

   else if(dir == 2)
   {
      PORTE&=(~(1<<PE4));
      PORTE|=(1<<PE5);
      OCR3B=speed;
   }
   else if(dir == 1)
   {
      PORTE&=(~(1<<PE5));
      PORTE|=(1<<PE4);
      OCR3C=speed;
   }

   //  SPEED
   uint8_t sreg=SREG;

   cli();

   SREG=sreg;
}
//---------------------------------------------   

I wrote the following code as well For test
Code:
void Moving(uint8_t AngDir , uint8_t VectDir , uint8_t Speed);

void Moving(uint8_t AngDir , uint8_t VectDir , uint8_t Speed)
{
   if(AngDir!=0)
   {
        Motor_Speed(VectDir,Speed);  // Moves straight with speed of 0.5 m/s
         Motor_Dir(AngDir);
         _delay_us(1);
         }
   else
   {
     Motor_Dir(0);    // assure  steering wheel is straight
     Motor_Speed(VectDir,Speed); // Moves straight with speed of 1 m/s
   }
}
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: May 15, 2012 - 02:36 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25901
Location: Wisconsin USA

Quote:

ICR3 = 1250; // 200 Hz

Quote:

,uint8_t speed

Well, you'll never get more than about 20% with that code--the biggest value is 255/1250.

Quote:

TCCR3B |= (1<<WGM33); // Phase and frequency correct PWM mode

Let's see the rest of the timer setup. (Why are people in love with |= ???)
 
 View user's profile Send private message  
Reply with quote Back to top
ar_hoseini
PostPosted: May 17, 2012 - 10:54 AM
Newbie


Joined: Apr 04, 2012
Posts: 3


Hi theusch,

I really appreciate your help.
the changes has been made and now it shows the output pertty well.
Quote:
TCCR3B |= (1<<WGM33); // Phase and frequency correct PWM mode

since I am not an experienced guy in programming I wonder if there is any alternative way for witing a code.
Thank you for your time. Very Happy Smile
 
 View user's profile Send private message  
Reply with quote Back to top
pmcdonnell
PostPosted: May 21, 2012 - 11:49 AM
Newbie


Joined: May 05, 2011
Posts: 9


Theusch has given you a massive hint.

Quote:
uint8_t speed


You have set the variable to be one byte as in 0-255 but it seems your TOP is 1250

Quote:
ICR3 = 1250; // 200 Hz
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits