pin change interrupt on attiny85 - Page 1
Forum section: electronics / general

author: eugene
author_rank: Frequent Contributor
timestamp: February 11, 2022, 04:46:07 pm
content: 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:// pin change interrupt handlerISR (PCINT0_vect){PORTB ^= (1<<PB4); // toggle IC pin 3}int main(void){// configure ic pin 3 as outputDDRB= (1<<DDB4);// configure interruptsGIMSK= (1<<PCIE); // enable pin change interruptsPCMSK= (1<<PCINT3); // IC pin 2 to trigger interruptsei(); // turn on global interruptswhile(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.I also do not understand why the toggled output has such slow response on the falling edge. Perhaps related?

author: Carel
author_rank: Regular Contributor
timestamp: February 11, 2022, 05:02:39 pm
content: What I miss is that one writes to PortB, one reads from PinB.

author: eugene
author_rank: Frequent Contributor
timestamp: February 11, 2022, 05:43:33 pm
content: @Carel, that is a good thought. I changedCode:PORTB ^= (1<<PB4);toCode:PORTB = PINB ^ (1<<PB4);But no joy; same result as before.

author: ledtester
author_rank: Super Contributor
timestamp: February 11, 2022, 05:47:31 pm
content: You can also toggle a port pin by writing a 1 to the PINx register:Quotefrom page 53 ofhttps://ww1.microchip.com/downloads/en/devicedoc/atmel-2586-avr-8-bit-microcontroller-attiny25-attiny45-attiny85_datasheet.pdf

author: Carel
author_rank: Regular Contributor
timestamp: February 11, 2022, 06:05:41 pm
content: Quote from: eugene on February 11, 2022, 05:43:33 pmI 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, PinBLdi r17,0x10Eor r16,r17Out PortB,r16Or to center on the problem, take a variable, turn Bit4 around and store it in PortB.

author: Carel
author_rank: Regular Contributor
timestamp: February 11, 2022, 06:16:19 pm
content: Quote from: ledtester on February 11, 2022, 05:47:31 pmLovely, found this feature also in the ATMEGA328 datasheet. A nice timesaver!

author: eugene
author_rank: Frequent Contributor
timestamp: February 11, 2022, 08:32:06 pm
content: Quote from: ledtester on February 11, 2022, 05:47:31 pmThanks. 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. Italmostworks 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.

author: eugene
author_rank: Frequent Contributor
timestamp: February 11, 2022, 09:48:39 pm
content: 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.I'm going to put it aside until tomorrow.

author: Carel
author_rank: Regular Contributor
timestamp: February 11, 2022, 11:09:00 pm
content: Quote from: eugene on February 11, 2022, 09:48:39 pmAlways 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.

author: eugene
author_rank: Frequent Contributor
timestamp: February 12, 2022, 02:44:36 pm
content: Quote from: Carel on February 11, 2022, 11:09:00 pmYes. 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.

author: Siwastaja
author_rank: Super Contributor
timestamp: February 12, 2022, 02:48:59 pm
content: 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.

author: Carel
author_rank: Regular Contributor
timestamp: February 13, 2022, 05:56:29 pm
content: 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,TempLdi Temp,(1<<PCINT3)Sts PCMSK0,TempPC_INT0:Sbic PinB,3 ;skip next instuction if PinB,3 is zeroRjmp IntClr ;Sbi PortB,4 ;Set PortB,4 to oneRjmp IntOut ;readyIntClr:Cbi PortB,4 ;PinB,3 is one, set PortB,4 to zero ;IntOut:RetiAnd here is it running at a leisurely 134 Khz. On edit: Blue = PB3, Yellow = PB4

author: Mechatrommer
author_rank: Super Contributor
timestamp: February 13, 2022, 06:24:52 pm
content: Quote from: eugene on February 11, 2022, 09:48:39 pmor maybe you left both pin 3 and 4 floating? how about adding 1Kohm pull down resistors to both and see if it working?