Apr 15, 2009
PWM by AVR-GCC
Arduino NG supports PWM with three pins – 9, 10 and 11. Those pins are assigned to Atmega8 PB1(OC1A), PB2(SS/OC1B) and PB3(MOSI/OC2) pings
PB1 (OC1A) – Arduino Pin 9
PB2(OC1B) – Arduion Pin 10
PB3(MOSI/OC2) – Arduion Pin 11
TCCR1A (Timer/Counter 1 Control Register A) and TCCR1B (Timer/Counter 1 Control Register B)
TCCR1A and TCCR1B are registers to configure PWM function.
TCCR1A Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
COM1A1 | COM1A0 | COM1B1 | COM1B0 | – | – | PWM11 | PWM10 |
TCCR1A Bit | Name | Meaning | Opportunities |
---|---|---|---|
7 | COM1A1 | Compare Output A | 00: OC1A/B not connected 01: OC1A/B changes polarity 10: OC1A/B to zero 11: OC1A/B to one |
6 | COM1A0 | ||
5 | COM1B1 | Compare Output B | |
4 | COM1B0 | ||
3 | (not used) | ||
2 | |||
1 | PWM11 | Pulse with modulator (analog output) | 00: PWM off 01: 8-Bit PWM (0 – 255) 10: 9-Bit PWM (0 – 511) 11: 10-Bit PWM (0 – 1023) |
0 | PWM10 |
Example code:
TCCR1A = (1<<COM1A1)|(1<<PWM0); // Non-Inverted PWM, 8-Bit PWM
TCCR1B Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
ICNC1 | ICES1 | – | – | CTC1 | CS12 | CS11 | CS10 |
TCCR1B Bit | Name | Meaning | Opportunities |
---|---|---|---|
7 | ICNC1 | Input Capture 1 Noise Canceller (4CKs) | 0: Noise Canceller disabled 1: Voltage change on ICP must last at least 4 clock cycles |
6 | ICES1 | Input Capture 1 Edget Select | 0: Falling edge on ICP triggers T/C1 capure 1: Rising edge on ICP triggers T/C1 capture |
5 | – | ||
4 | – | ||
3 | CTC1 | Clear Timer/Counter1 on Compare Match | 0: Doesn’t reset T/C1 on Compare Match 1: T/C1 is reset to $0000 on Compare Match |
2 | CS12 | ADC Channel Select | 000: STOP! T/C1 is stopped 001: T/C1 counts at the clock speed (CK) 010: T/C1 counts at CK/8 011: T/C1 counts at CK/64 100: T/C1 counts at CK/256 101: T/C1 counts at CK/1024 110: T/C1 counts on falling edget of T1 pin 111: T/C1 counts on rising edge of T1 pin |
1 | CS11 | ||
0 | CS10 |
Example code:
TCCR1B = (1<<CS10); //Start PWM
OCR1A (Timer/Counter 1 Output Compare register A) 16 bit register
OCR1A is a 16 bit register to store value of PWM. Highbyte of OCR1A can be acessed by using OCR1AH and lowbyte by OCR1AL. If PWM is set as 8-bit PWM, highbyte of OCR1AH is not used.
OCR1AH (Highbyte) 8 bit
OCR1AL (Lowbyte) 8 bit
OCR1A Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|---|---|
– | – | – | – | – | – | – | – |
Example code:
for (i=0; i<255; i++) {
OCR1AL = i; //Change lowbyte of OCR1A
_delay_ms(10);
}
Dimming LED
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
OCR1AH = 0;
DDRB |= (1<<PB1); //PortB 1 as output
TCCR1A = (1<<COM1A1)|(1<<1); // OC1A to zero, 8-Bit PWM
TCCR1B = 1; //Start PWM
for (;;) {
int i;
for (i=0; i<255; i++) {
OCR1AL = i; //Change lowbyte of OCR1A
_delay_ms(10);
}
for (i=255; i>0; i–) {
OCR1AL = i;
_delay_ms(10);
}
}
return 0; // never reached
}