Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
adrian.galindo
PostPosted: Apr 12, 2012 - 07:33 AM
Newbie


Joined: Nov 21, 2011
Posts: 8


So I am trying to get PWM to work in complete hardware mode on an attiny85.

  • I am using AVR Studio 6 and currently using only the Simulator(after realizing the code didn't work on an actual attiny85).
  • Using Timer/Counter1 in PWM Mode.
    So far I have the following code:


Code:

#define F_CPU 1000000UL

#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
int main(void)
{
   wdt_disable();//Disable Watchdog
   sei(); //Enable Interrupts
   PLLCSR &= ~_BV(PCKE); //Set Synchronous mode (disable PLL)
   
   DDRB  = _BV(PB4); //Make the Right pin (PB4) an output
   
   
   GTCCR  = _BV(PWM1B); //Enable PWM 1B
   GTCCR |= _BV(COM1B1) | _BV(COM1B0); //Only generate output on the standard not the inverted pin
   
   OCR1C = 254;    //Governs the frequency of PWM
   OCR1B  = 180;  // Governs Duty Cycle (180 ~75% of 256)
   
   TCCR1  = _BV(CS10); //No Prescaler.
   //Since the PLL is not enabled this should be in ref. to cpu clock.
   
   

    while(1)
    {
      //ALL hardware!
   }   
   

}

I have a few questions:
Generic Interrupt Trivia
Since I am in PWM mode, do I still need to enable the TOV1 interrupt for it to be activated (I know I need to manually enable global interrupts with sei() )

Erratic Cycle Counter
While using the simulator I find the cycle counter to be somewhat erratic. I am in disassembly view so it should only be advancing by 1 every time I hit the Step Into (F11) button. Most of the time however it advances by 2. This causes all sorts of interesting problems:

  • The timer (TCNT1) increments by 2 every time I hit the Step Into Key
  • I rarely get to see interrupt flags coming up as they get activated and then cleared by hardware in the next cycle.
  • I'm not sure if the compare to OCR1B is actually happening


Non Functioning Output
While I observe the TCNT1 value steadily increasing from 00 to OCR1B and past it to OCR1C then resetting to 00(albeit going in steps of 2 (see above), the output PB4 never actually changes. In fact the entirety of PORTB is unchanged. What I am doing wrong?

I read somewhere that past versions of simulator have had trouble with timers, but surely that is fixed by now right? I haven't seen any mention of it in the included help manual.

I could really use some help on this, I've been banging my head against this for some time now.

Thanks in advance for any suggestions and help!

(Also I'm wasn't sure if this is the right forum considering I am using the simulator, however after some deliberation I came to the conclusion that for organizational purposes it would be easier to have it related to the chip as opposed to the IDE -- let me know if I am wrong on that.)
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Apr 12, 2012 - 07:59 AM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13840
Location: Vancouver, BC

Quote:
Since I am in PWM mode, do I still need to enable the TOV1 interrupt for it to be activated (I know I need to manually enable global interrupts with sei() )
No. And since you are not using any interrupts, you don't need the sei().
Quote:
The timer (TCNT1) increments by 2 every time I hit the Step Into Key
But the only thing you have in your while loop is an RJMP which takes 2 cycles, so this is expected behavior.
Quote:
I rarely get to see interrupt flags coming up as they get activated and then cleared by hardware in the next cycle.
But there is absolutely nothing in your code that clears these flags, so the should be set once and never cleared. When I simulate your code, this is exactly what happens (note that because of the order that you set things, the OC01B interrupt flag does not get set until the second time the compare happens).
Quote:
While I observe the TCNT1 value steadily increasing from 00 to OCR1B and past it to OCR1C then resetting to 00(albeit going in steps of 2 (see above), the output PB4 never actually changes. In fact the entirety of PORTB is unchanged.
I don't believe that the simulation will show this (it doesn't when I simulate). However, it does change PINB4 on the next step after the output should change, therefore the simulation is in fact working.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
adrian.galindo
PostPosted: Apr 12, 2012 - 05:17 PM
Newbie


Joined: Nov 21, 2011
Posts: 8


Quote:
But the only thing you have in your while loop is an RJMP which takes 2 cycles, so this is expected behavior.

Doh! I totally forgot that RJMP takes a cycle to set the pointer then another to actually jump. Thanks!

Quote:
But there is absolutely nothing in your code that clears these flags, so the should be set once and never cleared.

So I assume that as soon as I create an ISR to handle vector then hardware will clear the flag? I guess this isn't really necessary. Nothing wrong with the flag being set.


Quote:
note that because of the order that you set things, the OC01B interrupt flag does not get set until the second time the compare happens

Ooh that is interesting. Not really important for my project, but still an interesting technical caveat. Could you expand on this a bit? Should I have set OCR1B before OCR1C?


Quote:
I don't believe that the simulation will show this (it doesn't when I simulate).

Ok I could buy that. How am I supposed to know what works in the simulator and what doesn't? I read the manual, and thought I understood the limitations of it...I guess not.


Quote:
However, it does change PINB4 on the next step after the output should change, therefore the simulation is in fact working.


From what I understand the PIN register is used for reading in the value of a physical pin that has been set as input via DDRx. When DDRx has it for output it shows the current value that the physical pin is holding -- right?

In summary:
The code should work as is.

Thanks so much for the clarification!!! Glad to know I'm not entirely crazy.
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Apr 12, 2012 - 05:36 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13840
Location: Vancouver, BC

Quote:
Could you expand on this a bit? Should I have set OCR1B before OCR1C?
No, you need to set OCR1B before you set GTCCR (specifically PWM1B). OCR1B is buffered in PWM mode, so the actual value is not updated until TOP is hit.
Quote:
When DDRx has it for output it shows the current value that the physical pin is holding -- right?
Yes, but it does not update until 1 cycle after the output changes.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
adrian.galindo
PostPosted: Apr 12, 2012 - 08:52 PM
Newbie


Joined: Nov 21, 2011
Posts: 8


You sir are amazing.

Thank You!
 
 View user's profile Send private message  
Reply with quote Back to top
adrian.galindo
PostPosted: Apr 15, 2012 - 04:26 AM
Newbie


Joined: Nov 21, 2011
Posts: 8


So I finally got a chance to try this out on an actual attiny85, but the output just stays HIGH. When I go into debug mode (JTAGICE 3) and disable the timers from running freely in debug mode I can see the TCNT1 value increasing on each step and resetting just as it should on comparison with the OCR1B and C but the PIN register doesn't change. Looking at the actual output of the avr the value is indeed 5v at all times. So what am I doing wrong? When I switch debugging tools back to simulator it works just fine, but not on the actual chip....
 
 View user's profile Send private message  
Reply with quote Back to top
bloody-orc
PostPosted: Apr 15, 2012 - 10:22 AM
Posting Freak


Joined: Dec 17, 2005
Posts: 1498
Location: Europe- Estonia- Tallinn

What do you have connected to the chip? Schematic of some sort would help. As it doesn't seem to be a software issue (the code seems correct), maybe it's a hardware one.
Also, do you have another chip you can try it with?
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
adrian.galindo
PostPosted: Apr 15, 2012 - 04:27 PM
Newbie


Joined: Nov 21, 2011
Posts: 8


All I have is an LED connected on that pin (PB4) and current limited to ground through a small resistor. But even when I take the LED out the pin stays HIGH at all times.

Now I do leave the ISP lines and the reset control lines connected to the JTAGICE 3, but that shouldn't make difference -- that's the point of in circuit programming.

I do have a few other attiny85s that I could try it out on I suppose.
 
 View user's profile Send private message  
Reply with quote Back to top
bloody-orc
PostPosted: Apr 16, 2012 - 11:23 AM
Posting Freak


Joined: Dec 17, 2005
Posts: 1498
Location: Europe- Estonia- Tallinn

How are you measuring the fact that it stays high? try changing the PWM frequency to something that you can see with your eye (e few Hz) if possible, or use a scope or logic analyzer on that pin.
 
 View user's profile Send private message Send e-mail  
Reply with quote Back to top
adrian.galindo
PostPosted: Apr 21, 2012 - 07:19 AM
Newbie


Joined: Nov 21, 2011
Posts: 8


Ok sorry it took me so long, I didn't have access to the device. Something is definitively wrong with the code, I tried it on another attiny85 and it had the exact same behavior (stays high).

I tried setting the clock prescaler super high (16384):
since the device is running off of 8MHz internal Oscillator, with the CLKDIV8 fuse set that gives us an effective clock frequency of 1MHz. Divided by 16384 is about 60Hz effective clock for the timer. According to the datasheet the PWM frequency should be PWMCLK/(OCR1C+1). So if I set OCR1C=60 (or around there) I should get a nice 1Hz blinking....but it stays HIGH!

My measurement tools aren't that great, but I should be able to see a 1Hz blink! But I also have a bus pirate in logic analyzer mode hooked up. It sees the pin go HIGH and then just stays high. The frequency counter on my multimeter reports 0Hz and 5v DC with 0v AC. Unless I am missing something really small I am must be going crazy!

Is it possible the timer doesn't support this slow of a speed?

Please help! Thank YOU...
 
 View user's profile Send private message  
Reply with quote Back to top
Koshchi
PostPosted: Apr 21, 2012 - 05:22 PM
10k+ Postman


Joined: Nov 17, 2004
Posts: 13840
Location: Vancouver, BC

Quote:
So if I set OCR1C=60 (or around there) I should get a nice 1Hz blinking....but it stays HIGH!
What the pin will do also depend on what you set OCR1B to: it must be less that what you have OCR1C set to.

_________________
Regards,
Steve A.

The Board helps those that help themselves.
 
 View user's profile Send private message  
Reply with quote Back to top
adrian.galindo
PostPosted: Apr 21, 2012 - 06:07 PM
Newbie


Joined: Nov 21, 2011
Posts: 8


Quote:
What the pin will do also depend on what you set OCR1B to: it must be less that what you have OCR1C set to.


Yeah I saw that while going through the datasheet. OCR1C = 60 and OCR1B is set to 30 (so about 1Hz pwm frequency at about 50% duty cycle).

I tried setting OCR1B to OCR1C value as well as x00 to try and induce the states the datasheet talks about and it "works" just fine according to the COM1B settings I have. It stays LOW in one state and goes HIGH in the other (just like the datasheet says it will).

Thanks for the idea though.

What in the world am I missing...this isn't supposed to be this tricky....

Thanks Again in advance guys for helping out!
 
 View user's profile Send private message  
Reply with quote Back to top
theusch
PostPosted: Apr 21, 2012 - 07:02 PM
10k+ Postman


Joined: Feb 19, 2001
Posts: 25912
Location: Wisconsin USA

Here is what CodeVision Wizard generates (pertinent bits):
Code:
// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=Out Func3=In Func2=In Func1=In Func0=In
// State5=T State4=0 State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x10;
...
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 7372.800 kHz
// Mode: PWMB top=OCR1C
// OC1A output: Disconnected
// OC1B output: Non-Inv., /OC1B disconnected
// Timer1 Overflow Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
PLLCSR=0x00;

TCCR1=0x01;
GTCCR=0x60;
TCNT1=0x00;
OCR1A=0x00;
OCR1B=0x22;
OCR1C=0x33;

 
 View user's profile Send private message  
Reply with quote Back to top
georges80
PostPosted: Apr 21, 2012 - 07:36 PM
Hangaround


Joined: Jul 25, 2004
Posts: 202
Location: Sunnyvale, CA

I use hardware PWM on tiny85's all the time. I DO remember that there's some weird issue when trying to use the 'B' channel of the PWM hardware if not using the 'A' channel.

What my fuzzy memory reminds me is that you have to set the appropriate COM1A bits in the TCCR1 register - EVEN THOUGH YOU ARE NOT USING PWM ON CHANNEL 'A'.

It was bizarre and I got it working on channel B' through some trial and error with the dragon connected to my tiny85.

I couldn't see anything in the documentation explaining why it was necessary.

I've used Channel 'A' to do all my hardware PWM since then and never had an issue setting it up.

So, unless you have a good reason not to use the Channel 'A' PWM, try setting the PWM COM1A bits in TCCR1 and you should find the PWM will then start to toggle correctly.

cheers,
george.
 
 View user's profile Send private message  
Reply with quote Back to top
snigelen
PostPosted: Apr 21, 2012 - 08:13 PM
Posting Freak


Joined: Jan 08, 2009
Posts: 1155
Location: Lund, Sweden

Sounds like this hardware bug in tiny45. From the errata in the data sheet:
Quote:
4. Timer Counter 1 PWM output generation on OC1B – XOC1B does not work correctly
Timer Counter1 PWM output OC1B-XOC1B does not work correctly. Only in the case when the control bits, COM1B1 and COM1B0 are in the same mode as COM1A1 and COM1A0, respectively, the OC1B-XOC1B output works correctly.

Problem Fix/Work around
The only workaround is to use same control setting on COM1A(1:0) and COM1B(1:0) control bits, see table 14-4 in the data sheet. The problem has been fixed for Tiny45 rev D.
 
 View user's profile Send private message  
Reply with quote Back to top
georges80
PostPosted: Apr 21, 2012 - 08:19 PM
Hangaround


Joined: Jul 25, 2004
Posts: 202
Location: Sunnyvale, CA

Yep, that's exactly it. Had the problem a few years back, so likely around the time the bug was found.

Presumably doesn't exist in the new chips (maybe...).

I just use the channel 'A' PWM to be safe (once burnt, twice shy) Smile

cheers,
george.
 
 View user's profile Send private message  
Reply with quote Back to top
adrian.galindo
PostPosted: Apr 21, 2012 - 11:28 PM
Newbie


Joined: Nov 21, 2011
Posts: 8


Holy Toledo, you guys are awesome!

I added the following line:
Code:
TCCR1 |= _BV(COM1A1) | _BV(COM1A0);

To set the COM1A the same as COM1B and everything started working!


When I saw the datasheet though it says that this particular problem is for the attiny45. When it goes to list the attiny85 errata it says no known errata.

Also how does one tell the revision of a chip? I saw some markings on the bottom of the chip that look promising, but no revision letters from what I could tell.
 
 View user's profile Send private message  
Reply with quote Back to top
georges80
PostPosted: Apr 22, 2012 - 12:31 AM
Hangaround


Joined: Jul 25, 2004
Posts: 202
Location: Sunnyvale, CA

Good to hear it's all now working.

Given the 25/45/85 likely share most of the same silicon, I'd assume whatever bug one has, the other would also have. Then depending on how Atmel rev's the masks there could be overlap between revs/chips.

The datasheet claims:

Revisions are marked on the package (packages 8P3 and 8S2: bottom, package 20M1: top)

The tiny85 I have on hand (purchased Nov 2011) show this on the bottom of the SOIC package:

049TW
6H6271-4
B-P e3

A bit cryptic to say the least...

It would have been NICE if there was a version/revision code that could be read via a register. Maybe there is, but I don't see it being 'public' in the datasheet.

cheers,
george.
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits