avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Simple but wrong code


From: Domenico Formenton
Subject: Re: [avr-gcc-list] Simple but wrong code
Date: Tue, 14 Jan 2014 18:46:37 +0100
User-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0

Hi John,

the code posted is only a test to investigate a problem that has occurred in the real application (without delay, of course). What I see with the LED is also seen with an oscilloscope in a much shorter time, in the millisecond range.

In actual application, there are other sources of interrupt (serial ports, counters, display) that could obscure the problem.

I only wanted to reduce to a minimum both the hardware and the software.

But I have not yet found the solution!

Thanks anyway for the suggestions.
Domenico

John Gallagher ha scritto:
I am not sure what your problem is, but looking briefly over your code I wouldn't be surprised if it is due to using delays inside your ISRs.  This is generally considered a very bad idea, since it can create all sorts of concurrency / blocking problems. The way people generally handle a case like yours would be to set a global flag in the ISR if you want to blink you LED, and then check the flag and do the actual blinking in your while(1) loop.

This may not be causing your issue, but it also may be. Either way, it is probably a good idea to make your ISRs as short as possible, which means removing any delays.


On Tue, Jan 14, 2014 at 11:54 AM, dfx <address@hidden> wrote:
Please consider this code:

#define KEY_PORT PORTD
#define KEY_DDR DDRD
#define KEY_FUNC_SEL PIND4 // --> first key (Port D pin 4)
....
#define LED_PORT PORTB // Test led, to see action on keypress
....

#define FUNC_SEL_KEY 0x10 // First function --> first key (Port D pin 4)
....

int main() {
  init();

  while (1) {
    // waits indefinitely for keypress
  }
  return (EXIT_SUCCESS); // Never reached
}

void init() {
  cli();
  LED_DDR |= (1 << DDB0); // Led out Port B pin 0

  KEY_PORT |= (1 << PORTD4) ; // pull-up resistor
  PCICR |= (1 << PCIE3); // Enable interrupts on PORTD (PCINT31:24)

  PCMSK0 = 0X00; // Disable unnecessary
  PCMSK1 = 0X00;
  PCMSK2 = 0X00;
  PCMSK3 |= (1 << PCINT28); // Enable  key
  sei();
}

ISR(PCINT3_vect) { // FUNCTION KEY
  uint8_t i;

  i = PORTD;
  if ((i & FUNC_SEL_KEY) > 0) { // Test a key
    LED_PORT |= (1 << PORTB0);
    _delay_ms(100);
    LED_PORT &= ~(1 << PORTB0);
    _delay_ms(300);
  }
  reti();
}


ISR(BADISR_vect) {
  LED_PORT |= (1 << PORTB0);
  _delay_ms(200);
  LED_PORT &= ~(1 << PORTB0);
  _delay_ms(200);
  LED_PORT |= (1 << PORTB0);
  _delay_ms(200);
  LED_PORT &= ~(1 << PORTB0);
  _delay_ms(200);
  LED_PORT |= (1 << PORTB0);
  _delay_ms(200);
  LED_PORT &= ~(1 << PORTB0);
  _delay_ms(200);
  reti();
}

the button has a capacitor 1uF for debouncing (together with the pull-up from 10 kohm)

The result is the following:

when I press the button,  are generated two flashes (instead of one),
 and when I release the button  are generated two more flashes.

Similarly, If I comment out the routine (ISR PCINT3_vect),
 the error routine (ISR BADISR_vect) generates double of the expected flashes.

Can anyone help me to understand the problem?

Thank you very much.


--
Domenico



---
Questa e-mail è priva di virus e malware perché è attiva la protezione avast! Antivirus.
http://www.avast.com

_______________________________________________
AVR-GCC-list mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list




_______________________________________________
AVR-GCC-list mailing list
address@hidden
https://lists.nongnu.org/mailman/listinfo/avr-gcc-list




Questa e-mail è priva di virus e malware perché è attiva la protezione avast! Antivirus .


Attachment: dformenton.vcf
Description: Vcard


reply via email to

[Prev in Thread] Current Thread [Next in Thread]