AtTiny45: Pinchange interrupt and timer questions

Hello,

I am having two problems concerning interrupt handling on my attiny45, using an Arduino UNO r3 as an ISP.

1.) Timer

My intention is to drive a piezo-speaker through the PWM-output on PIN PB1 (equals PIN 6 as a hardware-pin). When driving the Attiny45 with a 1Mhz clock, the frequency of the PWM output is around 60Hz, when clocking it at 8Mhz it equals roughly 480Hz (around 8 times more i guess ;)).

Now I want to drive my speaker at a frequency that I want to be able to influence. That is why I read through some pages of the datasheet for setting the PWM Timer (should be timer1):

As a prescaler I chose 256, which results in ~4kHz @ 1Mhz base clock and a compare register size of 0, which should be reset at the desired frequency (ctc mode enabled).

Now this is the code I am using to set the timer up:

TCNT1 = 0;  // reset counter to 0

TCCR1 = 0;  // reset tccr, I was having severe problems with timer interrupts when not doing this!

TCCR1 |= (1 << COM1A1) | (1 << COM1A0) | (1 << PWM1A) | (1 << CTC1) | (1 << CS13) | (1 << CS10);
  // [b]COM1A1 and COM1A0[/b], each set to "1": 
  // OC1x Set on compare match. Cleared when TCNT1= $00. (NOT)OC1x not connected.

  // PWM1A: Should enable PWM based on comparator OCR1A

  // CTC1: Clear counTer on Compare ;)

  // CS13/CS10: Set Prescaler to 256
OCR1A = 0;

Now I am still getting 60Hz/480Hz of PWM output on my desired output pin. Where lies the problem?

2.) Interrupt

When using “attachInterrupt(interrupt, function, mode)”, which pin is that interrupt assigned to? Can any pin be used as an interrupt pin? Judging by the pin layout given in the datasheet it seems as though all pins could be assigned intterupt functionality…

Thanks in advance!

elagil:
Hello,

I am having two problems concerning interrupt handling on my attiny45, using an Arduino UNO r3 as an ISP.

1.) Timer

My intention is to drive a piezo-speaker through the PWM-output on PIN PB1 (equals PIN 6 as a hardware-pin).
Now this is the code I am using to set the timer up:

TCNT1 = 0;  // reset counter to 0

TCCR1 = 0;  // reset tccr, I was having severe problems with timer interrupts when not doing this!

TCCR1 |= (1 << COM1A1) | (1 << COM1A0) | (1 << PWM1A) | (1 << CTC1) | (1 << CS13) | (1 << CS10);
  // COM1A1 and COM1A0, each set to “1”:
  // OC1x Set on compare match. Cleared when TCNT1= $00. (NOT)OC1x not connected.

// PWM1A: Should enable PWM based on comparator OCR1A

// CTC1: Clear counTer on Compare :wink:

// CS13/CS10: Set Prescaler to 256
OCR1A = 0;




I don't think that's the way to do it. PWM varies the duty cycle, you want to change the frequency.

Set CTC1=1, PWM1A=0, COM1A1=0 and COM1A0=1 (plus your prescalar...)

This resets the timer every time the counter reaches the value in OCR1C, and toggles the output pin. You can use OCR1C to control the frequency (It's only 8 bits so it won't be very musical :) )


**[u]2.) Interrupt[/u]**

When using "attachInterrupt(interrupt, function, mode)", which pin is that interrupt assigned to? Can any pin be used as an interrupt pin? Judging by the pin layout given in the datasheet it seems as though all pins could be assigned intterupt functionality..

Thanks in advance!

Don’t use attachInterrupt() (are you ever going to detach it?), just declare the interrupt directly, eg.:

ISR(TIMER1_COMPA_vect)
{
  ...put code here
}

The names of the interrupt vectors are in the section “Interrupts” on the datasheet.

Is there a reason for not using the tone() library to achieve what you want

Erni: Is there a reason for not using the tone() library to achieve what you want

It's only a Tiny45...?

Don't use attachInterrupt() (are you ever going to detach it?), just declare the interrupt directly, eg.:

well, no. I could manually set up the interrupt.

Now, that has nothing to do with the timer as those are two seperate problems (while the second one is not actually a problem, I only would like to know, which pin of the attiny is used for the interrupt).

The ISR you posted refers to a timer interrupt, what is it for?..

Is there a reason for not using the tone() library to achieve what you want

I do not know whether that works with the Attiny45 but it is meant for me to understand the basis of timers.

I do not know whether that works with the Attiny45

It does, actually it is not a library, it is part of the tiny core.

it is meant for me to understand the basis of timers.

I see, in that case I will follow your progress, I have never fully understood them either. I once was adviced by Coding Badly to use Timer0 instead of Timer1 because it is much different than timers on other Atmels

elagil:

Don't use attachInterrupt() (are you ever going to detach it?), just declare the interrupt directly, eg.:

well, no. I could manually set up the interrupt.

The ISR you posted refers to a timer interrupt, what is it for?..

You put that code in your sketch and that's it. No need for attachInterrupt().

elagil: Now, that has nothing to do with the timer as those are two seperate problems (while the second one is not actually a problem, I only would like to know, which pin of the attiny is used for the interrupt).

No pin is used for the interrupt. The timer causes it whenever it passes the value in OCR1A, which you set to zero so you get an interrupt whenever the timer passes zero.

Yes I know that, but I actually wanted to establish a pin change interrupt not a timer interrupt! The timer interrupt I testet earlier works flawlessly, just the PWM adjustment does not.

elagil: Yes I know that, but I actually wanted to establish a pin change interrupt not a timer interrupt!

You said "I want to drive my speaker at a frequency that I want to be able to influence"...

You don't even need an interrupt for that, the timer can put a square wave on the pin all by itself.

elagil: The timer interrupt I testet earlier works flawlessly, just the PWM adjustment does not.

What's the normal value for the prescalar? Maybe you're setting the same value.

Try random values, see if anything happens.

but I actually wanted to establish a pin change interrupt

If you want a pin change interrupt, you should look in table 9.3.2 and 9.3.4

You can choose whatever pin you want, below I have chosen pin PB3

ISR(PCINT0_vect){
digitalWrite(PB4,!(digitalRead(PB4)));
}

void setup(){
pinMode(PB4,OUTPUT);
GIMSK=_BV(PCIE);  //Table 9.3.2
PCMSK=_BV(PCINT3); //Table 9.3.4
}

void loop() {}