Author Topic: pin change interrupt on attiny85  (Read 2084 times)

0 Members and 1 Guest are viewing this topic.

Offline eugeneTopic starter

  • Frequent Contributor
  • **
  • Posts: 494
  • Country: us
pin change interrupt on attiny85
« on: February 11, 2022, 04:46:07 pm »
I do not have as much experience as some of you, but at the same time I am far from a beginner. This problem has me completely baffled and I need some help.

I'm trying to generate a simple pin change interrupt on an attiny85. Specifically, the pin that should detect the interrupt is acting as a SPI slave select, thus it is normally high and should trigger an interrupt when the pin goes low. But, it is just not detecting either edge. I whittled the code down to the bare essentials:

Code: [Select]
// pin change interrupt handler
ISR (PCINT0_vect)
{
PORTB ^= (1<<PB4); // toggle IC pin 3
}

int main(void)
{
// configure ic pin 3 as output
DDRB = (1<<DDB4);

// configure interrupts
GIMSK = (1<<PCIE); // enable pin change interrupts
PCMSK = (1<<PCINT3); // IC pin 2 to trigger interrupt
sei(); // turn on global interrupts

while(1);

return 0;
}

Normally, I would assume that there is a silly but difficult to see typing error. I've spent hours looking for it (doesn't mean it's not there.) But the weird thing is that when I invert the polarity of the signal, things behave as expected; an interrupt is triggered on both rising and falling edges.

The yellow trace is the pin with the interrupt attached (PB3) and the magenta trace is PB4 which should get toggled on each edge of PB3.

1410289-0
1410295-1

I also do not understand why the toggled output has such slow response on the falling edge. Perhaps related?
90% of quoted statistics are fictional
 

Offline Carel

  • Regular Contributor
  • *
  • Posts: 86
  • Country: nl
Re: pin change interrupt on attiny85
« Reply #1 on: February 11, 2022, 05:02:39 pm »
What I miss is that one writes to PortB, one reads from PinB.
« Last Edit: February 11, 2022, 05:23:50 pm by Carel »
 

Offline eugeneTopic starter

  • Frequent Contributor
  • **
  • Posts: 494
  • Country: us
Re: pin change interrupt on attiny85
« Reply #2 on: February 11, 2022, 05:43:33 pm »
@Carel, that is a good thought. I changed

Code: [Select]
PORTB ^= (1<<PB4);
to

Code: [Select]
PORTB = PINB ^ (1<<PB4);
But no joy; same result as before.
90% of quoted statistics are fictional
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3039
  • Country: us
Re: pin change interrupt on attiny85
« Reply #3 on: February 11, 2022, 05:47:31 pm »
You can also toggle a port pin by writing a 1 to the PINx register:

Quote
Three I/O memory address locations are allocated for each port, one each for the Data Register – PORTx, Data Direction Register – DDRx, and the Port Input Pins – PINx. The Port Input Pins I/O location is read only, while the Data Register and the Data Direction Register are read/write. However, writing a logic one to a bit in the PINx Register, will result in a toggle in the corresponding bit in the Data Register. ...

from page 53 of
https://ww1.microchip.com/downloads/en/devicedoc/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf
 

Offline Carel

  • Regular Contributor
  • *
  • Posts: 86
  • Country: nl
Re: pin change interrupt on attiny85
« Reply #4 on: February 11, 2022, 06:05:41 pm »
@Carel, that is a good thought. I changed

Code: [Select]
PORTB ^= (1<<PB4);
to

Code: [Select]
PORTB = PINB ^ (1<<PB4);
But no joy; same result as before.

I am not that into C, I do assembly. But I see PB4 doing the same action in both versions.

In ASM it would be:

In r16, PinB
Ldi r17,0x10 
Eor r16,r17
Out PortB,r16

Or to center on the problem, take a variable, turn Bit4 around and store it in PortB.
 

Offline Carel

  • Regular Contributor
  • *
  • Posts: 86
  • Country: nl
Re: pin change interrupt on attiny85
« Reply #5 on: February 11, 2022, 06:16:19 pm »
You can also toggle a port pin by writing a 1 to the PINx register:

Quote
Three I/O memory address locations are allocated for each port, one each for the Data Register – PORTx, Data Direction Register – DDRx, and the Port Input Pins – PINx. The Port Input Pins I/O location is read only, while the Data Register and the Data Direction Register are read/write. However, writing a logic one to a bit in the PINx Register, will result in a toggle in the corresponding bit in the Data Register. ...

from page 53 of
https://ww1.microchip.com/downloads/en/devicedoc/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf

Lovely, found this feature also in the ATMEGA328 datasheet. A nice timesaver!
 

Offline eugeneTopic starter

  • Frequent Contributor
  • **
  • Posts: 494
  • Country: us
Re: pin change interrupt on attiny85
« Reply #6 on: February 11, 2022, 08:32:06 pm »
You can also toggle a port pin by writing a 1 to the PINx register:

Thanks. That didn't change anything....

This MCU is on a solderless breadboard for testing. The finished product will use an SMD package on a PCB. But, for testing purposes I was lazy and didn't bother adding the usual 100nF bypass cap. The closest I could find in a leaded part is 1uF, so I added it between VCC and GND. It almost works now. It seems that this is likely to be an electrical issue, not software, so I will try rewiring everything more carefully. FWIW, the MCU is running at only 1MHz.


90% of quoted statistics are fictional
 

Offline eugeneTopic starter

  • Frequent Contributor
  • **
  • Posts: 494
  • Country: us
Re: pin change interrupt on attiny85
« Reply #7 on: February 11, 2022, 09:48:39 pm »
I felt stupid; the slow transition time was a dead giveaway that the power supply was inadequate. So I redid everything with fresh, known good connections. It still doesn't work. Not even with the capacitor.  |O

I'm going to put it aside until tomorrow.
90% of quoted statistics are fictional
 

Offline Carel

  • Regular Contributor
  • *
  • Posts: 86
  • Country: nl
Re: pin change interrupt on attiny85
« Reply #8 on: February 11, 2022, 11:09:00 pm »
I felt stupid; the slow transition time was a dead giveaway that the power supply was inadequate. So I redid everything with fresh, known good connections. It still doesn't work. Not even with the capacitor.  |O

I'm going to put it aside until tomorrow.

Always have at minimum 3 pieces of the components you use. In case of doubt, replace. If the problem persists, it's your problem. If the problem is solved, the loser goes in the bin. Get a new potential loser. Repeat.

 

Offline eugeneTopic starter

  • Frequent Contributor
  • **
  • Posts: 494
  • Country: us
Re: pin change interrupt on attiny85
« Reply #9 on: February 12, 2022, 02:44:36 pm »
Always have at minimum 3 pieces of the components you use. In case of doubt, replace. If the problem persists, it's your problem. If the problem is solved, the loser goes in the bin. Get a new potential loser. Repeat.

Yes. Thank you for your efforts, Carel. I did purchase 3 of these chips. After triple checking that all of the electrical connections were what I intended, I tried the remaining 2 parts: no change in behavior.

When I started this thread it was with the assumption that there was an error in my code and new eyes would spot it. But I've come to the conclusion that the problem is probably not something that can be diagnosed from far away across the internet... I have more work to do.
90% of quoted statistics are fictional
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8180
  • Country: fi
Re: pin change interrupt on attiny85
« Reply #10 on: February 12, 2022, 02:48:59 pm »
Have you tried without the interrupt, i.e., just toggle the IO pin in an endless loop, maybe with _delay_ms(1); or something inbetween. This would help you narrow down if it's related to IO, IO configuration, power supplies; or something to do with the interrupt.

If outputting zeroes and ones work, then the next step is reading the input in the infinite loop, i.e., implement the same functionality without the ISR.
 

Offline Carel

  • Regular Contributor
  • *
  • Posts: 86
  • Country: nl
Re: pin change interrupt on attiny85
« Reply #11 on: February 13, 2022, 05:56:29 pm »
Yesterday, some time after I read about the toggling through writing to PinX, I thought, nice to create pulse trains, but I don't think I have a job for it. What lacks is a defined state. It's only flipping bits. Initialisation or a missed edge can derail it.

So you want PB4 to reflect the inverted state of PB3. Read PinB,3 and transfer this bit, inverted, to PortB,4. That is a defined state.

OK, I was a little challenged that we could not make such a simple thing work, so I build it in in my current project.

       Ldi Temp,(1<<PCIE0)
       Sts PCICR,Temp
       Ldi Temp,(1<<PCINT3)
       Sts PCMSK0,Temp

PC_INT0:
   Sbic PinB,3      ;skip next instuction if PinB,3 is zero
   Rjmp IntClr      ;

   Sbi PortB,4      ;Set PortB,4 to one
   Rjmp IntOut      ;ready

IntClr:
   Cbi PortB,4      ;PinB,3 is one, set PortB,4 to zero   ;

IntOut:
      Reti

And here is it running at a leisurely 134 Khz. On edit: Blue = PB3, Yellow = PB4

« Last Edit: February 13, 2022, 06:22:14 pm by Carel »
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11654
  • Country: my
  • reassessing directives...
Re: pin change interrupt on attiny85
« Reply #12 on: February 13, 2022, 06:24:52 pm »
I felt stupid; the slow transition time was a dead giveaway that the power supply was inadequate.
or maybe you left both pin 3 and 4 floating? how about adding 1Kohm pull down resistors to both and see if it working?
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf