pwm and attiny441/841

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

Hi,
Does someone have example or tutorial how to implement hardware PWM output (servo signal) on a pin of the Attiny441 ?
I am bit lost among TOCC1, TOCPMSA1, FOC1A, in the right order and may miss something.
Thanks

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

I'll go out on a limb--you'll never need to touch FOC1A.

That AVR model series is pretty new. On the surface, 16-bit timers 1 and 2 look pretty much like any other "normal" AVR8 16-bit timer. Same modes, capabilities, ...

The only addition I see at first glance is that instead of using the designated pin on the AVR for e.g. OC1A, you have the ability to map it to one of four possibilities using the TOCP registers.

I also am a bit unclear on

Quote:
12.12.5 TOCPMCOE – Timer/Counter Output Compare Pin Mux Channel Output Enable
Bits 7:0 – TOCCnOE: Timer/Counter Output Compare Channel Output Enable

These bits enable the selected output compare channel on the corresponding TOCCn pin, regardless if the output compare mode is selected, or not.

The TOPCMSAn seems fairly straightforward.

Tell your desired period (20ms?) and AVR clock speed and selected output pin(s) and I'll put the CodeVision Wizard to work and see what it makes of it. ;)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

20 msec is fine, Attiny clock 16mhz, pin PA3.

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

Here's a quick test using two 16 bit timers with PWM for three servo signals on a tiny841 at 8MHz.

// Three servos on tiny841 using 16 bit timers 1 and 2.
#include 

int main(void)
{
    // TOCC[0:2] = OC1A, OC1B, OC2B (01, 01, 10)
    TOCPMSA0 = (1<<TOCC0S0) | (1<<TOCC1S0) | (1<<TOCC2S1);
    // Enable TOCC[0:2]
    TOCPMCOE = (1<<TOCC0OE) | (1<<TOCC1OE) | (1<<TOCC2OE);
    //PA1:3 OUTPUT
    DDRA = 7<<1;
    
    // Fast PWM, mode 14, non inverting, presc 1:8
    TCCR1A = (1<<COM1A1)|(1<<COM1B1) | 1<<WGM11;
    TCCR1B = 1<<WGM12 | 1<<CS11  |  1<<WGM13 | 1<<WGM12;
    TCCR2A = (1<<COM2B1) | 1<<WGM21;
    TCCR2B = 1<<WGM22 | 1<<CS21  |  1<<WGM23 | 1<<WGM22;
    // Set TOP for 20ms period
    ICR1 = 20000 - 1;
    ICR2 = 20000 - 1;

    // Set servos to 20, 50 and 80%
    OCR1A = 1200;
    OCR1B = 1500;
    OCR2B = 1800;

    while(1)
    {
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I copied your code into AtmelStudio 6.2, compiled in release mode and flashed the hex file. Fuses are set for 8MHz internal Oscillator and no clock division factor. But I am getting odd results. On PA1 I get a square wave of 29.5 Hz spanning 0..2.5V and on PA2 I am getting same frequency but the amplitude spanning from 1 to 3.5V.

I tried yesterday for the full day (using Codevision) to get out something reasonable, without understandable success. For some setting I could get a 800kHz quare wave on PA1 using Timer0. Mostly I end up with the strange frequency of 29.5 Hz and those odd amplitudes.

Notably, I can toggle the Pins as expected with voltage swing between 0.5 and 5V so the chip seems to be ok, at least partially...

I am less than an C-expert. In some settings you have used brackets, in others not. Do the brackets matter?

TCCR1A = (1<<COM1A1)|(1<<COM1B1) | 1<<WGM11;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's strange. I get 50Hz 5V square-waves on PA1, PA2, and PA3.

Quote:
Do the brackets matter?
Not in this case, the shift operators have higher precedence than the bitwise or operator. But I guess I could have been more consequent.

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

Quote:

spanning 0..2.5V

What is connected to those pins?
Quote:

of 29.5 Hz

What speed is your AVR >>really<< running at? How have you proven that?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Thanks for the hint to both prewriters. Connected was the JtagICE MkII. After unplugging it, everything is ok. Puh.

I never have had that issue with other chips (Tinys). The programmer was always being connected during tests. Potentially this could be a problem with debugging using the debugwire.

Replaced the JtagICE with the AVRISP MKII. Everything works as expected. So, that seems to be an issue for the JtagICE firmware. Too bad -can't use the debugger - which is not of that much use anyway since it just replicated whats written to the registers. Unfortunately one can't see the actual routing of the timers to the Port pins and unplugging the programmer each time is not that much fun either.

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

Quote:

Potentially this could be a problem with debugging using the debugwire.

??? I thought the only connection for debugWire is the /RESET pin?
Quote:

Connected was the JtagICE MkII.

I assume for ISP purposes? then still a mystery, as the ISP pins are PA4/PA5/PA6.

Or did you connect wires to PA1/PA2/PA3 "just for fun"?

What about the resulting frequency?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

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

Quote:
I thought the only connection for debugWire is the /RESET pin?

Then it would be ok (I don't know what happens to the other wires running into the programmer).

Quote:
I assume for ISP purposes? then still a mystery, as the ISP pins are PA4/PA5/PA6.

Yes, The ICE was used as ISP programmer after one initial session using the debugwire and getting out of that mode since that was not very enlighting.

Nothing else is connected to the pins rather than the programmer and nothing was changed on the board from the beginning. I had checked with an Ohmsmeter that the chip pins were connected to the right pins of the programming adapter, and I never received programming error messages.

Now the interesting part:
I replaced the AVRISP again with the ICE. Everything kept working! Any of the outputs is at 51.3 Hz and the amplitudes are right. And I can exchange the programmers without getting a problem.

So I must conclude that something must have been got locked within the chip (or the ICE?) to get that mysterious frequency of 29 Hz and the weak pulse amplitudes -almost independently on what I had flashed into the chip (without getting errors). And that had persisted over night having everything switched off from power!

I remember to have had a similar issue earlier. The first programmer some chip had seen was the ICE (like in this case) and the result was odd. But then using the AVRISP once the chip worked and I could exchange both types of programmers without any problem.
Is there any suggestion for the cause?

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

OP has chosen to continue this afresh here:

https://www.avrfreaks.net/index.p...

Locked.

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

 I think the OC1A output pin is linked and set with  (1<<TOCC1S0) and OC1B output pin is linked and set with (1 <<TOCC0S0) as per the table 12-7 of ATtiny441-841 datasheet?

so this becomes 

 

    // TOCC[0:2] = OC1B, OC1A, OC2B (01, 01, 10)
    TOCPMSA0 = (1<<TOCC0S0) | (1<<TOCC1S0) | (1<<TOCC2S1);

and not the following: 

// TOCC[0:2] = OC1A, OC1B, OC2B (01, 01, 10)
    TOCPMSA0 = (1<<TOCC0S0) | (1<<TOCC1S0) | (1<<TOCC2S1);

 

Tell me if I'm wrong and if wrong please explain me?

 

also  don't you people think that the clock should be assigned at last! and after loading the OCR1A and OCR1B registers? what I mean is following:

 

// Three servos on tiny841 using 16 bit timers 1 and 2.
#include 

int main(void)
{
    // TOCC[0:2] = OC1A, OC1B, OC2B (01, 01, 10)
    TOCPMSA0 = (1<<TOCC0S0) | (1<<TOCC1S0) | (1<<TOCC2S1);
    // Enable TOCC[0:2]
    TOCPMCOE = (1<<TOCC0OE) | (1<<TOCC1OE) | (1<<TOCC2OE);
    //PA1:3 OUTPUT
    DDRA = 7<<1;
    
    // Fast PWM, mode 14, non inverting, presc 1:8
    TCCR1A = (1<<COM1A1)|(1<<COM1B1) | 1<<WGM11;
    TCCR2A = (1<<COM2B1) | 1<<WGM21;
    // Set TOP for 20ms period
    ICR1 = 20000 - 1;
    ICR2 = 20000 - 1;

    // Set servos to 20, 50 and 80%
    OCR1A = 1200;
    OCR1B = 1500;
    OCR2B = 1800;

    TCCR1B = 1<<WGM12 | 1<<CS11  |  1<<WGM13 | 1<<WGM12;
    TCCR2B = 1<<WGM22 | 1<<CS21  |  1<<WGM23 | 1<<WGM22;
    
    while(1)
    {
    }
}

as opposed to:

 

// Three servos on tiny841 using 16 bit timers 1 and 2.
#include 

int main(void)
{
    // TOCC[0:2] = OC1A, OC1B, OC2B (01, 01, 10)
    TOCPMSA0 = (1<<TOCC0S0) | (1<<TOCC1S0) | (1<<TOCC2S1);
    // Enable TOCC[0:2]
    TOCPMCOE = (1<<TOCC0OE) | (1<<TOCC1OE) | (1<<TOCC2OE);
    //PA1:3 OUTPUT
    DDRA = 7<<1;
    
    // Fast PWM, mode 14, non inverting, presc 1:8
    TCCR1A = (1<<COM1A1)|(1<<COM1B1) | 1<<WGM11;
    TCCR1B = 1<<WGM12 | 1<<CS11  |  1<<WGM13 | 1<<WGM12;
    TCCR2A = (1<<COM2B1) | 1<<WGM21;
    TCCR2B = 1<<WGM22 | 1<<CS21  |  1<<WGM23 | 1<<WGM22;
    // Set TOP for 20ms period
    ICR1 = 20000 - 1;
    ICR2 = 20000 - 1;

    // Set servos to 20, 50 and 80%
    OCR1A = 1200;
    OCR1B = 1500;
    OCR2B = 1800;

    while(1)
    {
    }
}

 

again correct me why I'm wrong?

 

Thanks!

"Great Men fall in the service of humanity ,not in front of any God or demon "

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
    // TOCC[0:2] = OC1B, OC1A, OC2B (01, 01, 10)
    TOCPMSA0 = (1<<TOCC0S0) | (1<<TOCC1S0) | (1<<TOCC2S1);

Yes, the order in that comment reflects which pins gets which PWM output.

 

And yes, it's often a good idea to start the timers after you have set the compare and TOP values. And some times it doesn't matter.

 

BTW, wasn't this thread locked in the old forum?

Last Edited: Tue. Sep 23, 2014 - 11:08 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

snigelen wrote:
BTW, wasn't this thread locked in the old forum?
[eye-rub-of-frustration]... probably means every locked thread from the old forum is now unlocked.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Topic locked