Tiny2313 pwm timer1 does not work the OCR1A and OCR1B

Hello

 

I want to control 2 DC motors...

 

I set the Timer1 for fast pwm no problem... I run at 4 mhz....

 

what prescaller I need?

and even if I set the OCR1A and OCR1B the speed is constant... any ideea?

 

 

thanks

 

TCCR1A |= (1<<WGM10)|(1<<WGM11)|(1<<COM1B1)|(1<<COM1B0)|(1<<COM1A1)|(1<<COM1A0);

TCCR1B |= (1<<CS11)|(1<<WGM13)|(1<<WGM12); //prescaller

here is the whole

here is the whole code

 

 

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
/* PB4 M1    - pwm
 * PB2 M1
 * PB3 M2    - pwm
 * PB1 M2
 * PD6 M1    -enable
 * PB0 M2    -enable
 * forward: PB1,PB2 low, pwm
 * reverse: PB1,PB2 high, inverted pwm
 * stop: PB1,PB2 low, pwm 0(low);
 * protocol has to send first the direction, 2. left speed (M2), 3. right speed
 */

void forward(void);
void reverse(void);
void left(void);
void right(void);
void stop(void);
void USART_init(uint16_t ubrr_value);
unsigned char USART_get(void);
void btimer(void);

int direction;  //0-stop, 1-forward, 2-reverse, 3 - left, 4 - right

int main()
    {
    DDRB |= 0xFF;    //motors output
    DDRD |= (1<<PD6);    //motor output
    PORTD |= (1<<PD6);    //enable 1
    PORTB |= (1<<PB0);    //enable 2
    USART_init(51);    //9600 baud
    sei();

    while(1)
    {
    direction = 1;
    switch(direction)
        {
    case 0:
        stop();
        while(direction==0);
        break;
    case 1:
        forward();
        OCR1A = 25;
        OCR1B = 25;
        while(direction==1);
        break;
    case 2:
        reverse();
        while(direction==2);
        break;
    case 3:
        left();
        while(direction==3);
        break;
    case 4:
        right();
        while(direction==4);
        break;
        }
    }
    };

void reverse()
    {
    PORTB = 0x00;
    PORTB |= (1<<PB2)|(1<<PB0);
    PORTD |= (1<<PD6);
    TCCR1A = 0x00;
    TCCR1A |= (1<<WGM10)|(1<<WGM11)|(1<<COM1A1)|(1<<COM1B1)|(1<<COM1B0);
    btimer();
    TCCR1C = 0x00;
    };

void forward()
    {
    PORTB = 0x00;
    PORTB |= (1<<PB1)|(1<<PB0);
    PORTD |= (1<<PD6);
    TCCR1A = 0x00;
    TCCR1A |= (1<<WGM10)|(1<<WGM11)|(1<<COM1A1)|(1<<COM1B1)|(1<<COM1A0);
    btimer();
    TCCR1C = 0x00;
    };

void right()
    {
    PORTB |= (1<<PB1);
    PORTB |= (1<<PB2);
    PORTB |= (1<<PB0);
    PORTD |= (1<<PD6);
    TCCR1A = 0x00;
    TCCR1A |= (1<<WGM10)|(1<<WGM11)|(1<<COM1B1)|(1<<COM1B0)|(1<<COM1A1)|(1<<COM1A0);
    btimer();
    TCCR1C = 0x00;
    };

void left()
    {
    PORTB = 0x00;
    PORTB |= (1<<PB0);
    PORTD |= (1<<PD6);
    TCCR1A = 0x00;
    TCCR1A |= (1<<WGM10)|(1<<WGM11)|(1<<COM1A1)|(1<<COM1B1);
    btimer();
    TCCR1C = 0x00;
    };

void stop()
    {
    if(direction==2)
    {
    forward();
    _delay_ms(100);
    };
    if(direction==1)
    {
    reverse();
    _delay_ms(100);
    };
    PORTB = 0x00;
    PORTD = 0x00;
    TCCR1A = 0x00;
    TCCR1B = 0x00;
    TCCR1C = 0x00;
    };


//UART PART
void USART_init(uint16_t ubrr_value)
{
   UBRRL = ubrr_value;
   UBRRH = (ubrr_value>>8);

   UCSRC = (1 << UCSZ1) | (1 << UCSZ0);        //8bit 1 stop bit
   UCSRB=(1<<RXEN)|(1<<TXEN)|(1<<RXCIE);    //interrupt enable
};


unsigned char USART_get(void)
{
    while ( !(UCSRA & (1<<RXC)) );
    return UDR;
};


ISR(USART_RX_vect)
    {
    direction=USART_get();
    OCR1A=USART_get();
    OCR1B=USART_get();
    };

void btimer()
    {
    TCCR1B = 0x00;
    TCCR1B |= (1<<CS10)|(1<<CS12)|(1<<WGM13)|(1<<WGM12); //prescaller
    };

hey check this link

hey check this link out: http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html

it has some formulas that should help you calculate the prescaler and the output frequency.

Next step: you got fast pwm with SET on compare match and CLEAR at bottom. Point is that the TOP is OCR1A…so basically it sets at the TOP and right after that it CLEARS, i guess that’s a problem as it stays on for almost no time, this would make the OC1A output useless. (mind that it’s 24.00 so i’m really tired…could have made some mistakes in checking the datasheet)

I suggest you use a fast PWM mode with a fixed TOP, such as the 0101, 0110 or 0111 (these 4 bits are WGM13, 12, 11 and 10).

Strange how speed doesn’t change though…

ok working :smiley:

ok working :smiley: