//
// 38kHz to atmega328p D3
// based on https://gist.github.com/chendy/69454f6ec77b54f9a710
//
//
byte oscOut = 3 ; // Atmega328p OC2A=D11 ; OC2B=D3 ;
void setup(){
pinMode(oscOut, OUTPUT);
OCR2A = 51; // defines the frequency 51 = 38.4 KHz, 54 = 36.2 KHz, 58 = 34 KHz, 62 = 32 KHz
OCR2B = 26; // defines the duty cycle - Half the OCR2A value for 50%
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // COM2B1 (output to OC2B) ; WGMode 7 Fast PWM (part 1)
TCCR2B = _BV(WGM22) | _BV(CS21); // prescalere x8 ; WGMode 7 Fast PWM (part 1)
}
void loop(){ }
This works fine for pin OC2B (pin D3) of my Uno clone.
If, however, I change the pin to OC2A (D11) and replace COM2B1 with COM2A1 in setting register TCCR2A, it does not work. The pin is simply HIGH
Looking at the data sheet for the Atmega328p, timer2 appears quite symmetrical between OC2A and OC2B with the exception that there is special mode when COM2A1==0 and COM2A0=1 which has no equivalent on the "B" side. That and several what appears to be cut and paste relics belonging to timer 0 in the timer2 description.
So, clearly I am missing something, but what ? Can anyone see it ?
OCR2A = 51; // defines the frequency 51 = 38.4 KHz, 54 = 36.2 KHz, 58 = 34 KHz, 62 = 32 KHz
OCR2B = 26; // defines the duty cycle - Half the OCR2A value for 50%
TCCR2A = _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); // COM2B1 (output to OC2B) ; WGMode 7 Fast PWM (part 1)
TCCR2B = _BV(WGM22) | _BV(CS21); // prescalere x8 ; WGMode 7 Fast PWM (part 1)
}
void loop(){ }
This works fine for pin OC2B (pin D3) of my Uno clone.
If, however, I change the pin to OC2A (D11) and replace COM2B1 with COM2A1 in setting register TCCR2A, it does not work. The pin is simply HIGH
Looking at the data sheet for the Atmega328p, timer2 appears quite symmetrical between OC2A and OC2B with the exception that there is special mode when COM2A1==0 and COM2A0=1 which has no equivalent on the "B" side. That and several what appears to be cut and paste relics belonging to timer 0 in the timer2 description.
So, clearly I am missing something, but what ? Can anyone see it ?
Mode 7 uses register OCR2A to set TOP, so pin 11 is not programmable for PWM in that mode.
MarkT:
Mode 7 uses register OCR2A to set TOP, so pin 11 is not programmable for PWM in that mode.
OK. Thanks. It is clear to me that Wave Generation Mode 7 uses register OCR2A to set top. Indeed as does modes 2 and 5. But why does that preclude the use of OC2A as an oscillator output pin for those modes ? Can you point to a reference in the data sheet which makes that restriction clear or defines the behaviour of OC2A in those modes?
Can you point to a reference in the data sheet which makes that restriction clear or defines the behaviour of OC2A in those modes?
If you set COM2A0 you can get the pin 11 A output to toggle at the frequency set by the OCR2A top, but that is the only hardware output you can get on that pin other than HIGH or LOW when OCR2A is TOP.
The extreme values for the OCR2A Register represent special cases when generating a PWM waveform
output in the fast PWM mode. If the OCR2A is set equal to BOTTOM, the output will be a narrow spike for
each MAX+1 timer clock cycle. Setting the OCR2A equal to MAX will result in a constantly high or low
output (depending on the polarity of the output set by the COM2A[1:0] bits.)
Note:
A special case occurs when OCR2A equals TOP and COM2A1 is set. In this case the compare
match is ignored, but the set or clear is done at BOTTOM. Refer to Fast PWM Mode for details.
This statement appears to me to be not relevant to my example because OCR2A is not set to either MAX (0xFF) or BOTTOM (0x00):
The extreme values for the OCR2A Register represent special cases when generating a PWM waveform
output in the fast PWM mode. If the OCR2A is set equal to BOTTOM, the output will be a narrow spike for
each MAX+1 timer clock cycle. Setting the OCR2A equal to MAX will result in a constantly high or low
output (depending on the polarity of the output set by the COM2A[1:0] bits.)
This, however, appears to be the explanation:
Note:
A special case occurs when OCR2A equals TOP and COM2A1 is set. In this case the compare
match is ignored, but the set or clear is done at BOTTOM. Refer to Fast PWM Mode for details.
because this matches exactly what my failing example is attempting and what my tests show.
However, the exact equivalent of that statement appears also on the "B" side (table:18-6 in my version of the datasheet):
Note: 1. A special case occurs when OCR2B equals TOP and COM2B1 is set. In this case, the Compare Match is
ignored, but the set or clear is done at BOTTOM. See ”Phase Correct PWM Mode” on page 148 for more
details.
So the question now is not why my second example failed, but how my first example which sets COM2B1 could have worked since it relies on the compare/match function which the footnote states does not work.
Edit.
I've looked again at the data sheets and I'm still not convinced that this is the answer either. This phrase: "A special case occurs when OCR2A equals TOP and COM2A1 is set" must mean when OCR2A has the value 0xFF, not when OCR2A is used to define TOP as it is in modes 7, 5 and 2.
Table 18-3 in the datasheet specifically refers to the setting / clearing of OC2A in fast PWM Mode (7) and that is what I believe should happen in the test script which apparently fails.
I've also had a look at some datasheets for other Atmel processors with an 8bit PWM timer to see if I could find any clues about special behaviour which may have been omitted in error from the Atmega328p data sheet, but found nothing.
I've looked again at the data sheets and I'm still not convinced that this is the answer either. This phrase: "A special case occurs when OCR2A equals TOP and COM2A1 is set" must mean when OCR2A has the value 0xFF, not when OCR2A is used to define TOP as it is in modes 7, 5 and 2.
I think the word TOP is a generic term which covers several situations. For timer2 it can be either 0xFF or OCR2A. For 16 bit timer1, TOP can be 0xFFFF, 0x00FF,0x01FF,0x03FF, OCR1A, ICR1.
Take a look at table 17-8 describing the modes for Timer 2,
6v6gt:
OK. Thanks. It is clear to me that Wave Generation Mode 7 uses register OCR2A to set top. Indeed as does modes 2 and 5. But why does that preclude the use of OC2A as an oscillator output pin for those modes ?
This intrigued me so I did a bit of "research" by pretending I was trying to write the code myself learning as I go.
As far as I can see the problem arises because the compare match for OC2B is the value in OCR2B and the compare match for OC2A is the value in OCR2A. That allows for 2 different duty cycles on the two output pins in some modes.
When you choose mode 7 OCR2A is used as top and also as the compare match value for OC2A. That means that the state of pin OC2A is cleared and immediately set because the timer jumps straight from top to bottom in that mode. This effectively precludes generating PWM on OC2A in mode 7.
I guess this statement in the datasheet is intended to cover the point, but it is very opaque
A special case occurs when OCR2A equals TOP and COM2A1 is set. In this case, the Compare Match is ignored, but the set or clear is done at BOTTOM. See ”Fast PWM Mode” on page 150 for more details.
He also attributed the problem to the attempted dual use of OCR2A as both the TOP and the Compare Register in this case.
I'm sure the "special case" statements in the data sheet are hints at this, but since these appear to apply equally to the "A" side and the "B" side, it makes it difficult to understand why one works and one does not.
I've made a small picture which begins to make clear that the "A" side and "B" side are not completely symmetric and that maybe OCRnA can't fulfill 2 roles simultaneously-
The very complex wording to conceal missing functionality looks like Atmel marketing had a hand in the compilation of the documentation. An engineer would say A does not work and it would be clear. A marketting person would attempt to present it as a useful feature and also litter the data sheet with stuff like this which is extemely irritating when you are seeking technical information:
This high frequency makes the fast PWM mode well suited for power regulation, rectification, and
DAC applications. High frequency allows physically small sized external components (coils, capacitors), and therefore reduces total system cost.
6v6gt:
The very complex wording to conceal missing functionality looks like Atmel marketing had a hand in the compilation of the documentation.
If there is a choice between a cock-up and a conspiracy then a cock-up is infinitely more likely.
I suspect the piece I quoted reflects the fact that the engineers new the thing so well that they considered that everyone would understand it perfectly clearly. This is a common problem when experts try to explain things to mere mortals. It behoves us all to ensure that we don't do the same when we try to answer questions for Forum newbies.