keyboard app and avr interrupts ?

Discussion in 'Computing and Networks' started by Mathematics!, Apr 8, 2010.

  1. Mathematics!

    Thread Starter Senior Member

    Jul 21, 2008
    1,022
    4
    This question is a continuation of my previous thread
    http://forum.allaboutcircuits.com/showthread.php?t=35917

    I am trying to program my avr chip to read the keyboard data.
    So I am assuming I need an interrupt function for when the clock pin goes low...etc

    My problem is I am chosing one of the PORTA pins for use for the data and clock pins. However I don't know how to setup an interrupt function for a specific pin....etc
    And how to have it triggered if the voltage state goes low or high.

    I have included
    Code ( (Unknown Language)):
    1.  
    2. #include <avr/interrupt.h>
    3.  
    Any help with this would be great
     
    Last edited: Apr 8, 2010
  2. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Which AVR microcontroller are you using to implement your keybard app?

    hgmjr
     
  3. Mathematics!

    Thread Starter Senior Member

    Jul 21, 2008
    1,022
    4
    atmega32 avr chip

    From what I know their is 21 interrupts and only 3 of them are external interrupts (i.e int0 , int1, int2 ... )

    Code ( (Unknown Language)):
    1.  
    2. #include <stdio.h>
    3. #include <avr/interrupt.h>
    4. #include <AVR\io.h>
    5.  
    6. int main (void)
    7. {
    8.  
    9.  while (1) { }
    10. }
    11.  
    12. ISR(INT0_vect)
    13. {
    14.  
    15.   // Code to handle the event.
    16. }
    17.  
    18.  
    19.  
    It compiles fine but I am wondering when it is going to get triggered.
    Mainly I want to have an interrupt that is called when the clock pin goes from a high to low state.

    More generally I want to beable to set an interrupt up for a certain pin.
    (and only that pin) as well as having it being triggered only if it goes from high to low.

    I am wondering their should be away to set it to this.
    I am unsure of what are the valid vector names and their uses.

    http://wiki.msoe.us/cs280/interrupts

    Thanks for any help

    like could I have

    Code ( (Unknown Language)):
    1.  
    2. ISR(PA0_vect)  //<- is this a valid interrupt for pin 1 of PORTA
    3. {
    4.   //What makes this method be triggered for high to low
    5.   //What makes this method be triggered for low to high
    6.  // What makes this method be triggered for changes in state
    7.   // Code to handle the event.
    8. }
    9.  
     
  4. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    There are some AVRs that permit many if not all of the pins to be used to trigger interrupts. The ATMEGA32 does not have this feature. Therefore the example you have posed to use PORTA Pin 1 is not valid.

    If you want to use an external signal to interrupt the ATMEGA32 then you should consider using INT0, INT1, or INT2. Your interrupt service routine using INT0 should work fine. You do need to set up the interrupt on INT0.

    hgmjr
     
  5. Mathematics!

    Thread Starter Senior Member

    Jul 21, 2008
    1,022
    4
    Wait so I have been think about it.
    And if the int0 interrupt is triggered by many different pins then
    thats still ok. As long as I have some sort of way to determine if the interrupt was caused by a specific pin

    Is their away? I was think PINA ,...etc bits but that only gives you if the pin is low or high but not if it was triggering the interrupt.

    Their should be away to find out what pins or pin caused the interrupt?

    Also does this interrupt get called when a pin goes from low to high or high to low or both (just changes state)

    Their should be away to set it so it only gets notified if a pin goes from high to low?

    And curious what is the difference between int0 , int1 , int2

    Thanks for your help this is my first time working with avr interrupts.
     
  6. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    The INT0 interrupt is only triggered by a change on the pin labeled INT0. It does not get triggered by any other signal change on any other pin.
    The ATMEGA32 does not have a PINCHANGE interrupt feature as some of the AVRs do.
    The ATMEGA32 does not have the feature that allows an interrupt to be generated by a change on any pin on the AVR.
    The INT0, INT1, and INT2 each have a bit in a register that is used to determine which change in the pin hi-to-lo or lo-to-hi triggers the interrupt.

    hgmjr
     
  7. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    You will need to set the bits associate with the external INT? interrupt you choose in the MCUCR register to select the desired input signal change polarity and you will need to make sure to enable the interrupt in GICR register.

    Also you will need to make sure you add the statement sei(); to enable global interrupts.

    hgmjr
     
  8. Mathematics!

    Thread Starter Senior Member

    Jul 21, 2008
    1,022
    4
    OK , I am going to use int0 it is on pin 16 of the chip.


    I am using a c program to do this so I don't know how to do what the above quote states?

    Would I do something like this

    Code ( (Unknown Language)):
    1.  
    2.  
    3. #include <stdio.h>
    4. #include <avr/interrupt.h>
    5. #include <AVR\io.h>
    6.  
    7. int main (void)
    8. {
    9.  
    10.   MCUCR = 0x00 ;  //This I don't know what to set it to for pin 16 interrupt to be triggered from high to low
    11.   //GICR  = 0x00 ; < ---this gives me a syntax error say that their is no variable GICR declared
    12.  
    13. [B]sei() ;   // this turns interrupts on if they aren't on already.[/B]
    14.  
    15.  while (1) { }
    16. }
    17.  
    18. ISR(INT0_vect)
    19. {
    20.  
    21.   // Code to handle the event.
    22.  
    23. }
    24.  
    25.  
     
    Last edited: Apr 10, 2010
  9. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    OK. What C-language compiler tools are you using?

    hgmjr
     
  10. bertus

    Administrator

    Apr 5, 2008
    15,634
    2,342
    Hello,

    I am a noob in these things but what I see in this text :
    #include <stdio.h>
    #include <avr/interrupt.h>
    #include <AVR\io.h>


    You use a slash in the second line and a back-slash in the third line.
    I do not know if this makes a difference.

    Bertus
     
  11. retched

    AAC Fanatic!

    Dec 5, 2009
    5,201
    312
    I noticed the same.. Also does the compiler care if you capitalize 'AVR' in one and lowercase 'avr' in the other? Does it consider 'avr' and 'AVR' two different directories?
     
  12. Mathematics!

    Thread Starter Senior Member

    Jul 21, 2008
    1,022
    4
    I am using avr studio with winavr2009 from my gcc compiler

    The code I have now looks like this
    It compiles fine I am just wondering if I am forgetting any thing?
    Also wondering how I can print to the computer screen what is happening.
    Like for instance to make sure everything is working properly I need to beable to display what is going on in the interrupt....but I don't know any way of doing it their is no printf function???
    Code ( (Unknown Language)):
    1.  
    2.  
    3. #include <stdio.h>
    4. #include <avr/interrupt.h>
    5. #include <avr/io.h>
    6.  
    7. int main (void)
    8. {
    9.   MCUCR = 0x02 ;  //MCU control register 0x02 is for falling edge interrupts
    10.   sei() ;
    11.  
    12.  while (1) { }
    13. }
    14.  
    15. ISR(INT0_vect)
    16. {
    17.  
    18.   // Code to handle the event.
    19.   if( PIND | 0x05 ) //I put the keyboard data pin on PD4
    20.   {
    21.   // the if statement should execute if PD4 is high
    22.  
    23.   // if we got here it is a logical one
    24.   }
    25.   else
    26.   {
    27.    // if we got here it is a logical zero
    28.   }
    29.  
    30. }
    31.  
    32.  

    To store the key stroke values should I just use an array or is their some eeprom memory function I should use?

    Thanks for any help
    Maybe their is somebody else that knows more about this.
    Probably should be in the MCU forum...
    Feel free to move.
     
  13. retched

    AAC Fanatic!

    Dec 5, 2009
    5,201
    312
    You can print to the serial port then monitor the incoming serial data instead of a printf
     
  14. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    I noticed that you have omitted the GICR setup. Does using GICR as an L-value still generate an error?

    hgmjr
     
  15. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    A common technique for providing feedback on a program's execution is to provide a few LEDs connected to your spare inputs. You can then light each of the LEDs depending on where you are in your program execution.

    hgmjr
     
  16. Mathematics!

    Thread Starter Senior Member

    Jul 21, 2008
    1,022
    4
    I tried but the compiler gives me a syntax error when I use GICR ?
    It say's no declared varible.
    Plus I am not really sure on what value to give it even if I was to get it to work.... don't really understand what the GICR is for.....????
    Currently I have this as my code

    Code ( (Unknown Language)):
    1.  
    2. #include <stdio.h>
    3. #include <avr/interrupt.h>
    4. #include <avr/io.h>
    5. volatile int keyboard_data = 0 ;
    6. volatile int bitnumber = 0 ;
    7. int main (void)
    8. {
    9.  
    10.   MCUCR = 0x02 ;  //MCU control register 0x02 is for falling edge interrupts
    11.   sei() ;
    12.  
    13.  while (1) { }
    14. }
    15.  
    16. ISR(INT0_vect)
    17. {
    18.  
    19.   if( bitnumber >= 13 )
    20.   {
    21.     bitnumber = 0 ;
    22.     // AT this point the keyboard data has all lower 13 bits out of the
    23.  //16 bits set with the error code , scancode ,...etc
    24.  //so KNOW I NEED TO STORE THIS DATA IN SOME WAY?
    25.  //I was think creating a large int array but maybe their is a better way.
    26.  // Or some eeprom function I should use
    27.     // After keyboard_data is stored set it back to zero for next key
    28.     keyboard_data = 0 ;
    29.   }
    30.   // Code to handle the event.
    31.   if( PIND | (1<<PIND4) ) //I put the keyboard data pin on PD4
    32.   {
    33.   // the if statement should execute if PD4 is high
    34.   // if we got here it is a logical one for that particular bit
    35.   // switch statement turns a specific bit on logical 1
    36.    switch( bitnumber )
    37.    {
    38.  
    39.      case 0:
    40.      keyboard_data = 0x01 ;
    41.   break ;
    42.  
    43.      case 1:
    44.      keyboard_data = keyboard_data | 0x02 ;
    45.   break ;
    46.   case 2:
    47.      keyboard_data = keyboard_data | 0x04 ;
    48.   break ;
    49.   case 3:
    50.      keyboard_data = keyboard_data | 0x08 ;
    51.   break ;
    52.   case 4:
    53.      keyboard_data = keyboard_data | 0x10 ;
    54.   break ;
    55.   case 5:
    56.      keyboard_data = keyboard_data | 0x20 ;
    57.   break ;
    58.  
    59.      case 6:
    60.      keyboard_data = keyboard_data | 0x40 ;
    61.   break ;
    62.      case 7:
    63.      keyboard_data = keyboard_data | 0x80 ;
    64.   break ;
    65.   case 8:
    66.      keyboard_data = keyboard_data | 0x100 ;
    67.   break ;
    68.   case 9:
    69.      keyboard_data = keyboard_data | 0x200 ;
    70.   break ;
    71.   case 10:
    72.      keyboard_data = keyboard_data | 0x400 ;
    73.   break ;
    74.   case 11:
    75.      keyboard_data = keyboard_data | 0x800 ;
    76.   break ;
    77.   case 12:
    78.      keyboard_data = keyboard_data | 0x1000 ;
    79.   break ;
    80.  
    81.   default:
    82.   //shouldn't ever get here !
    83.   break ;
    84.  
    85.    }  
    86.  
    87.  
    88.   }
    89.   else
    90.   {
    91.    // if we got here it is a logical zero
    92.    // set nothing
    93.   }
    94.  
    95.   bitnumber++ ; // increment what bit we are on next out of the 13 bit protocal
    96. }
    97.  
    98.  

    As for printing to a serial port is their any other way to print this to a computer screen while debugging or something.

    The led idea is not really going to help me that much because keyboard data is processed really fast and I want to beable to look at the 13 bit values..... leds won't keep up with this and it would be confusing anyway.
    Not that its not a good idea it is just not going to work for me in this situation.

    As for storing the values of the keyboard_data should I just but it in a
    array int[] or is their a better way using something else....

    Because I was just thinking of makeing the largest integer array possible.
    And storing it that way.

    input needed
     
  17. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    It sounds like AVRSTUDIO4 is not finding iom32.h header file in the AVRSTUDIO4 application folder.

    The first thing to check is that you have correctly selected the ATMEGA32 as the target AVR device in AVRSTUDIO4. The quickest way to do this is to bring up your AVRSTUDIO4 project and look at the bottom bar of the AVRSTUDIO4 window. You should see ATMEGA32 in the bar about two-thirds the way over.

    Let me know if you see this indication. If not, you will need to go through the procedure for telling AVRSTUDIO4 that you are developing code to be run on the ATMEGA32.

    hgmjr
     
  18. hgmjr

    Moderator

    Jan 28, 2005
    9,030
    214
    Since you are not receptive to the LED approach you have a couple of ways to go. Both are a lot more involved than the LED approach.

    You can purchase a Character-type LCD display and output messages to it or you can set up the ATMEGA32's UART to output the information to a PC that has an RS-232 serial port. You can run HYPERTERMINAL on the monitoring PC and send text strings to it. You will need to add a 5V logic level to RS-232 signal level converter to your hardware to insure reliable serial data transfer.

    All of this is well within your capability but it is a lot to bite off on your first introduction to microcontrollers. Granted, if you tackle this project you will be well and truly initiated into the wonderful world of microcontrollers. Indeed, you will be ready to tackle anything at that point.

    hgmjr
     
  19. retched

    AAC Fanatic!

    Dec 5, 2009
    5,201
    312
    I agree. You might as well go with the alphanumeric lcd approach. That way you are getting a full education on user input and visual output regarding uCs.

    The easy way out, is the hyperterminal way. That is what I used to do. If yor compiler has a serout or like command, you can send strings to the serial port, or use various protocols. These can be monitored via hyperterm.

    BUT, it is rather cool to see your uC communicating with a lcd for the first time. You get a huge boost. You get the realization that you can now build about 90% of the consumer electronics out there.
     
  20. Mathematics!

    Thread Starter Senior Member

    Jul 21, 2008
    1,022
    4
    Well I don't see any thing on the bottom bar except the name
    JTAGICE mkII.

    When I do a connect I select an AVRISP mkII on the programing window I have device atmega32.

    I don't know where else I have to set it. When I leave out the GICR it compile fine and I am able to program it with no problems?

    Thanks for any help with this one.

    As for the displaying of the content I am not up for buying LCD screens etc,... so I will probably try the serial thing.

    But I am a little unsure about what pins on the serial cable go to what pins on the atmega32 chip for me to use hyperterminal to see it.
    Note I still want to program the chip using the usb and avisp mkII.

    Also what should I set the GICR if I was to get it to work and why?
     
Loading...