direct PWM

Hey, guys!
Does anybody know which registers to use for PWM through direct port manipulation? Are any tricks to doing it this way?

Yes, the TCCR0A/B, TCCR1A/B, and TCCR2A/B registers. It's a bit lengthy but the descriptions in Section 15.9 of the ATmega328P datasheet explains it all. This is for Timer 1; similar descriptions exist for Timers 0 and 2.

As for tricks? There are no tricks, just careful coding :slight_smile: Maybe study how the built-in tone() and analogWrite() functions work to get a sense for how to work with these registers.

--
The Gadget Shield: accelerometer, RGB LED, IR transmit/receive, light sensor, potentiometers, pushbuttons

PWM is generated by using a timer and an Output Compare Register. Specifically, for the ATmega328P there are three timers: Timer0, Timer1, and Timer2. Each timer has two Output Compare Registers and each OCR can be connected to an output pin that is toggled at times depending on the timer frequency (controlled by a prescaler register for that timer) and by the timer mode and by the value entered into the OCR.

Here's a summary of the timers and pins that can be used with the ATmega328p:


ATmega328p       OC        ATmega328p     avr-gcc         Arduino
  Timer        Register    28-DIP Pin     Port Pin      Digital Pin
-------------------------------------------------------------------
 Timer 0        OC0A           12           PD6               6
 Timer 0        OC0B           11           PD5               5

 Timer 1        OC1A           15           PB1               9
 Timer 1        OC1B           16           PB2              10 

 Timer 2        OC2A           17           PB3              11
 Timer 2        OC2B            5           PD3               3

Note that a particular OCR is connected to its pin by setting a bit in one of the timer control registers. When that bit is not set, that pin is available for "normal" I/O.

Also note, particularly, that Timer0 is used for millis() and delay() functions, so using Timer0 for PWM may require some care (or else...)

Regards,

Dave

I'm rather new to microcontrollers in earnest. I'm kind of pressed for time on a project and I'm wondering, can this be effectively done within the Arduino IDE, should I take up ASM, or should I just do bona fide GCC? What are the options with Linux (Ubuntu) (which I am also fairly new to)?

This can be done from the IDE, as you are mainly writing GCC-type code. The IDE simply makes it easy to pull in the Arduino infrastructure code (stuff that lets you call analogWrite() and such). You don't have to use that code. You can reprogram the timer registers but then take care not to try to use the Arduino infrastructure code that expects to have the timers configured in a certain way.

You can also write basic GCC code using only AVR-LIBC interfaces and forget about the Arduino infrastructure code. All of these tools are available for Ubuntu (check out avr-gcc in the package manager). You can download your program to your board using AVRDUDE (also should be in the package manager).

I don't think there's any need to write in assembly language unless your project demands it (and the vast majority don't).

--
The Quick Shield: breakout all 28 pins to quick-connect terminals

Also note, particularly, that Timer0 is used for millis() and delay() functions, so using Timer0 for PWM may require some care (or else...)

Yeah, I had read that PWM might not shut off completely under certain conditions associated with delay instructions. I need to control some H-bridges that carry several amps, so that kind of made me anxious. I won't need to delay or time anything, though. If I don't use any delay() or millis(), will that get rid of the complications?

will that get rid of the complications?

I haven't tried to do away with all of the mechanism that is used with millis() and delay() functions. So much stuff out there (various libraries that people use) depends on them that I would be reluctant to plan on trying to defeat them, knowing that all kinds of other stuff depends on Timer0.

I mean, anything is possible, but that doesn't mean that it is easy. (Of course it might be easy, but...)

Regards,

Dave