Inverted Output to an another Output

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi dear !

I've generated a waveform with timer0 and I want to set an another output with this waveform but inverted !

With a pic it's very easy ...

I try to use PORTD.7 =! PIND.6 but AVR STUDIO 6 doesn't want to compile my code.

And bit mask're a bit complicate to do that , I guess ...

How I can do that ?

Sylvain.

 

 

Last Edited: Thu. Apr 30, 2015 - 09:41 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I try to use PORTD.7 =! PIND.6 but AVR STUDIO 6 doesn't want to compile my code.

Why are you surprised that is not valid C?!?

 

There is one C compiler for AVR that has an extension that allows .6 and .7 to be used - that is Codevision but when you say "AVR STUDIO 6" I'm guessing you mean you are using avr-gcc?  If so try standard C notation:

if (PIND & (1 << 6)) {
  PORTD |= (1 << 7);
}
else {
  PORTD &= ~(1 << 7);
}

Alternatively find sbit.h for avr-gcc and use:

#include "sbit.h"

PORT_D7 = !PIN_D6;

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

if (PIND & (1 << 6)) {
  PORTD |= (1 << 7);
}
else {
  PORTD &= ~(1 << 7);
}

 

This one work well but my 2 waveforms aren't perfectly in phase ...

 

Here's my code :

 

ISR (TIMER0_COMPA_vect)
{
    if (PINB & (1 << 7))
    {
        PORTC &= ~(1 << 7);
    }
    else
    {
        PORTC |= (1 << 7);
    }
}
int main(void)
{
    DDRB = 0X80;
    DDRC= 0X80;

    TCCR0A |= (1<<COM0A0)|(1<<WGM01); //Active le mode toggle de la sortie OCR0A, active le mode CTC
    TCCR0B |= (1<<CS01); //Active le timer sans pré division
    OCR0A = 24; // comparaison constante avec TCNT0, flag OCF0A activé lors d'un match
    TCNT0 = 0; // set le compteur à 0
    TIMSK0 = (1<<OCIE0A); //active l'interruption correspondante au match TIMER/COUNTER0
    sei (); //Active le registre d'interruption générale
        
    //while(burst_send == 0){}
    
    while(1)
    {

    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

aren't perfectly in phase ...

And why were you expecting them to be? You only sense the state of B.7 and output to C.7 each time the ISR() triggers. Also there's probably the best part of 20 cycles from the actualy COMPA event until code gets into the ISR so that means C7 is going to lag B7 by at least that amount.

 

Most AVR timers have the ability to drive two outputs and one can be set to the complement of the other - so why not look at doing that instead (it will depend on which model of AVR but there may be more chance of finding this for a 16 bit rather than an 8bit timer).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

And why were you expecting them to be? You only sense the state of B.7 and output to C.7 each time the ISR() triggers. Also there's probably the best part of 20 cycles from the actualy COMPA event until code gets into the ISR so that means C7 is going to lag B7 by at least that amount.

Yes, you're right !

clawson wrote:

Most AVR timers have the ability to drive two outputs and one can be set to the complement of the other - so why not look at doing that instead (it will depend on which model of AVR but there may be more chance of finding this for a 16 bit rather than an 8bit timer).

I use a Atmega32U4 but just for development after that I want to switch to a lowcost uC ...

I don't see inverted pin for TIMER0 and I need timer1 for other application.

How can I inverted OCOA compared to OCOB ?

Last Edited: Thu. Apr 30, 2015 - 12:33 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

After some research, I've found and realised these things :

 

1) Generate a waveform on OC0A and the inverted waveform on OC0B with timer0 in PWM => BUT I can't adjust the frequency by this way ...

 

2) Generate a waveform with correct frequency on OC1A and the inverted on OC1B with timer1 in PWM PHASE AND FREQUENCY correction, BUT I need this timer for INPUTCAPTURE

 

So, my question're :

 

1) Can I adjust presicely the frequency with timer0 in PWM mode ?

 

2) Are there cheap uC with 2 16-bit timer ? And how I can found it ? There're a lot of Tiny , atmega  and I can't lost my time to check all datasheets :(

Last Edited: Thu. Apr 30, 2015 - 03:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Judging from your first attempt, software PWM is fast enough.

// play leapfrog.  use toggle mode.  start pins as complements of each other
ISR( compare match 0A ) {
    unit8_t tmp=...;
    OCR0A=tmp;
    OCR0B=tmp;
}

 

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:

Judging from your first attempt, software PWM is fast enough.

// play leapfrog.  use toggle mode.  start pins as complements of each other
ISR( compare match 0A ) {
    unit8_t tmp=...;
    OCR0A=tmp;
    OCR0B=tmp;
}

 

 

I don't understand you,

What do you saying ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or simply disable the toggling of the pins by the timer itself and toggle both in the ISR.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Several Tinys have complementary OCxx pins.

I believe the AT90PWMxxx chips have them as well.

 

With a regular Mega,  just select a PWM mode and make OC0A and OC0B have the same duty-cycle.   One in inverted and the other in non-inverted mode.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With a regular Mega,  just select a PWM mode and make OC0A and OC0B have the same duty-cycle.   One in inverted and the other in non-inverted mode.

 Except that the OP has to use timer0 which would mean that he can't control the frequency.

Regards,
Steve A.

The Board helps those that help themselves.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oops.    I did not spot that the period needed to be variable.    The 8-bit Timer0 uses OCR0A for variable period PWM modes.

 

Apparently,  the OP is using a ATmega32U4.

 

So she has two 16-bit Timers.    Generate your waveform with one of these Timers.   e.g. use a PWM mode with period determined by ICR3.

And set the modes for OC3A, OC3B

 

Using the hardware should generate perfectly synchronised and complementary signals.

 

Of course,   a simple inverter gate would be another solution.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Koshchi wrote:

With a regular Mega,  just select a PWM mode and make OC0A and OC0B have the same duty-cycle.   One in inverted and the other in non-inverted mode.

 Except that the OP has to use timer0 which would mean that he can't control the frequency.

He doesn't need to.

He can use normal mode and update the compare match registers in an ISR.

Iluvatar is the better part of Valar.

Last Edited: Fri. May 1, 2015 - 03:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Finaly done ! :)

 

david.prentice wrote:

With a regular Mega,  just select a PWM mode and make OC0A and OC0B have the same duty-cycle.   One in inverted and the other in non-inverted mode.

this is the method that I used

Koshchi wrote:

 Except that the OP has to use timer0 which would mean that he can't control the frequency.

and for choosing my frequency I use ''TCCR0 = X'' in my overflow interrupt ...

david.prentice wrote:

Apparently,  the OP is using a ATmega32U4.

So she has two 16-bit Timers.    Generate your waveform with one of these Timers.   e.g. use a PWM mode with period determined by ICR3.

And set the modes for OC3A, OC3B

Yes. I use an Atmega32U4 for development but I need my 16 bits timer for another thing and the most common uC(168,328 ...) have only one 16 bits timer and one input capture.

 

Thanks all for your quick and helpfull answers!