ATMega128 Fast PWM

"Thomas D. Dean" <[email protected]>
Newsgroups gmane.comp.hardware.avr.gcc
Message-ID <[email protected]>
How do I change the polarity of the PWM output, WGM mode 5, OCR1A on the 
fly?

I use WGM mode 5 to provide PWM to drive gearhead motors.  I update the 
OCR values every 50 msec.  The algorithm makes changes gradually.

If, for example, the motor is CCW at 50%, the OCR value is 128.  The 
register values for this are:
(1)
   TCCR1A = _BV(COM1A1) | _BV(WGM10);
   TCCR1B = _BV(WGM12) | _BV(CS11);
   OCR1A = 80;

I want to reverse the direction of the motor.  The register values are:
(2)
   TCCR1A = _BV(COM1A1) | _BV(COM1A0) |_BV(WGM10);
   TCCR1B = _BV(WGM12) | _BV(CS11);
   OCR1A = 80;

The algorithm will slow the motor to stop and then reverse it.  I tried 
setting OCR1A = 0, changing the TCCR1 values, and setting OCR1A = 80. 
This does not work.  After changing from (1) to (2), the PWM stops.

What am I doing wrong?  Any ideas?

Tom Dean

_______________________________________________
AVR-GCC-list mailing list
[email protected]
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list
oc-pwm.c (text/x-csrc, 1 KB)
#include <avr/io.h>  /* ports and registers */
#include <trace.h>

void motor_init(void);
void both_motor_fwd(void);
void both_motor_rev(void);
void initialize(void);

void initialize() {
  TRACE_PORT_DDR = ALL_OUT;
  TRACE_PORT = 0;
}

void both_motor_fwd() {
  TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
  TCCR1B = _BV(WGM12) | _BV(CS11);
  TIFR |= _BV(TOV1);
  OCR1A = 80;
  OCR1B = 160;
}

void both_motor_rev() {
  TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0);
  TCCR1B = _BV(WGM12) | _BV(CS11);
  TIFR |= _BV(TOV1);
  OCR1A = 80;
  OCR1B = 160;
}

void motor_init() {
  DDRB |= _BV(PB6) | _BV(PB5);
  TCCR1A = _BV(COM1A1) | _BV(COM1B1) | _BV(WGM10);
  TCCR1B = _BV(WGM12) | _BV(CS11);
  OCR1A = 80;
  OCR1B = 160;
}

int main() {
  initialize();
  motor_init();
  
  TIFR |= _BV(TOV1);
  while (1) {
	TRACE_ON(0);
	while ((TIFR & _BV(TOV1)) == 0) ;
	TIFR |= _BV(TOV1);
	//both_motor_rev();
	TRACE_ON(1);
	while ((TIFR & _BV(TOV1)) == 0) ;
	TIFR |= _BV(TOV1);
	TRACE_OFF(1);
	TRACE_OFF(0);
	//both_motor_fwd();
  }

  return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.