Pages: [1]   Go Down
Author Topic: 16bit timer1 phase & frequency PWM mode. some assembly required  (Read 584 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello Arduino Universe.

I'm figuring out how to use Assembly within the Arduino IDE... turns out the underlying libraries made some provisions to use Assembly directly.

Anyway, I'm trying to access the 16bit Timer1 PWM on the USBoarduino (from Adafruit) ATmega328P. I have the datasheet in front of me and I'm reading all the instructions on how to turn on this bit and turn off that bit...etc

I got the chip to do the following:

-read a potentiometer on A0,
-copy the value into OCR1A, and ICR1 registers
-TCNT1 seems to be counting up and down based on the OCR1A, ICR1 values..

however there is no State Change on the designated PWM pins (D8, D9 on the USBoarduino)

Do I really have to write an interrupt routine to toggle the appropriate pins every time there is a Compare Match happening?
what am I missing?

here's some fun code:
Code:


#include <avr/io.h>            //added these libraries to make sure I can use predefined Assembly code... probably redundant.
#include <avr/interrupt.h>
#include "wiring_private.h"
#include "Wire.h"

byte PinA0 = A0;
word pot1 = 0x0003; //minimum resolution is 3.
byte PB1 = 8;
byte PB2 = 9;

void setup()
{
  cbi(TCCR1B,CS12); //set prescaler to 1 on Timer1
  cbi(TCCR1B,CS11);
  sbi(TCCR1B,CS10);
 
  sbi(TCCR1B,WGM13);  //enable PWM, Phase and Frequency Correct.  using ICR1A
  cbi(TCCR1B,WGM12);
  cbi(TCCR1A,WGM11); 
  cbi(TCCR1A,WGM10);
 
  sbi(TCCR1A,COM1A1); //set OC1A on Compare Match when up-counting
  sbi(TCCR1A,COM1A0);
  sbi(TCCR1A,COM1B1); //set OC1B on Compare Match when up-counting
  sbi(TCCR1A,COM1B0);
 
   
  sbi(DDRB,DDB1);      //extra redundant here
  pinMode(PB1, OUTPUT); //arduino pin8 = PB1 = OC1A

  sbi(DDRB,DDB2);      //extra redundant here
  pinMode(PB2, OUTPUT); //arduino pin9 = PB2 = OC1B
 
  Serial.begin(9600);

}

void loop()
{
  pot1 = analogRead(PinA0);
  OCR1A = pot1;
  ICR1 = pot1;

  Serial.print("pot1=");
  Serial.print(pot1);   
  Serial.print("\tOCR1B=");   
  Serial.print(OCR1B);
  Serial.print("\tOCR1A=");
  Serial.print(OCR1A);
  Serial.print("\tICR1=");
  Serial.print(ICR1);
  Serial.print("\tTCNT1=");
  Serial.println(TCNT1);
 
  delay(200);
}





Logged

0
Offline Offline
Shannon Member
****
Karma: 162
Posts: 10523
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Timer1 controls pins 9 and 10, not 8 and 9.  channel A to pin 9, channel B to pin 10

You need to set OCR1A and OCR1B to values strictly less than ICR1 to get any pwm signal out.  Set ICR1 to 1024, it should start to do something.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 31
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes you are right about the pins.... my bad!!

MarkT, you = Awesomeness!!

IT works!!!
Logged

Pages: [1]   Go Up
Jump to: