I'm trying to control DC motor speed. As of right now, to my limited understanding, I suppose I'm able to control the motor with just high and low by setting and clearing bits. The goal is to have the motor run at its 50% or 70% of the max speed, preferrably while gradually increasing and decreasing the speed. Please see the following piece of code and the circuit diagram for the current system configuration.
Here's the motor's datasheet: https://www.ti.com/lit/ds/symlink/drv8801.pdf
The board I'm using is:
ATmega64A Atmel AVR 8-bit Microcontroller
#define MOTOR_CON PORTA
#define DC_ENABLE_ON sbi(PORTA, 3)
#define DC_ENABLE_OFF cbi(PORTA, 3)
#define DC_PHASE_ON sbi(PORTA, 2)
#define DC_PHASE_OFF cbi(PORTA, 2)
#define DC_MODE_ON sbi(PORTA, 1)
#define DC_MODE_OFF cbi(PORTA, 1)
void MotorSpeedSwingUp(void)
{
DC_ENABLE_ON;
}
void MotorSpeedSwingDn(void)
{
DC_ENABLE_OFF;
}
void MotorForwardPhase(void)
{
DC_PHASE_ON;
DC_MODE_OFF;
}
void MotorReversePhase(void)
{
DC_PHASE_OFF;
DC_MODE_OFF;
}
void MotorRun(void)
{
if(motor_swing_flag == TRUE)
{
motor_swing_flag = FALSE;
MotorSpeedSwingUp();
}
else
{
motor_swing_flag = TRUE;
MotorSpeedSwingDn();
}
}
void MotorBrake(void)
{
DC_PHASE_OFF;//Forward
DC_ENABLE_OFF;
DC_MODE_ON;
}
Many thanks for helping!
The concept of PWM control is to repeat ON and OFF in a very short cycle as shown in Figure 9-3 and so on. The ratio of ON time in the cycle is called "duty cycle" and is proportional to the motor rotation speed as enhzflep comments.
Let's suppose the cycle is 200usec and we want to have the motor rotate at 70% speed. Then we should repeat the following sequence:
Assuming your C compiler supports usleep()
function, would you please
try something like (not tested):
#define CYCLE 200 // 200usec for 1 cycle
#include <unistd.h>
/*
* have the motor run at "duty" speed for "duration" seconds
* 0.0 <= duty <= 1.0
*/
void PwmRun(double duty, int duration)
{
if (duty < 0.) duty = 0.; // lower limit of "duty"
if (duty > 1.) duty = 1.; // upper limit of "duty"
int ontime = (int)(CYCLE * duty); // PWM on time
int offtime = (int)(CYCLE * (1. - duty)); // PWM off time
for (int t = 0; t < duration * 1000000; t += CYCLE) {
if (ontime > 0) DC_ENABLE_ON;
usleep(ontime);
if (offtime > 0) DC_ENABLE_OFF;
usleep(offtime);
}
}
// example to run the motor at 70% speed for 3 seconds
PwmRun(0.7, 3);
It will be easy to modify the code to gradually increase the speed from 50% to 70%.