keyboard app and avr interrupts ?

Thread Starter

Mathematics!

Joined Jul 21, 2008
1,036
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
Rich (BB code):
#include <avr/interrupt.h>
Any help with this would be great
 
Last edited:

Thread Starter

Mathematics!

Joined Jul 21, 2008
1,036
atmega32 avr chip

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

Rich (BB code):
#include <stdio.h>
#include <avr/interrupt.h>
#include <AVR\io.h>

int main (void)
{
  
 while (1) { }
}

ISR(INT0_vect)
{
  
  // Code to handle the event.
}
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

Rich (BB code):
ISR(PA0_vect)  //<- is this a valid interrupt for pin 1 of PORTA
{
  //What makes this method be triggered for high to low
  //What makes this method be triggered for low to high
 // What makes this method be triggered for changes in state
  // Code to handle the event.
}
 

hgmjr

Joined Jan 28, 2005
9,027
atmega32 avr chip

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

Rich (BB code):
#include <stdio.h>
#include <avr/interrupt.h>
#include <AVR\io.h>
 
int main (void)
{
 
 while (1) { }
}
 
ISR(INT0_vect)
{
 
  // Code to handle the event.
}
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

Rich (BB code):
ISR(PA0_vect)  //<- is this a valid interrupt for pin 1 of PORTA
{
  //What makes this method be triggered for high to low
  //What makes this method be triggered for low to high
 // What makes this method be triggered for changes in state
  // Code to handle the event.
}
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
 

Thread Starter

Mathematics!

Joined Jul 21, 2008
1,036
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.
 

hgmjr

Joined Jan 28, 2005
9,027
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
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.
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.
The ATMEGA32 does not have a PINCHANGE interrupt feature as some of the AVRs do.
Their should be away to find out what pins or pin caused the interrupt?
The ATMEGA32 does not have the feature that allows an interrupt to be generated by a change on any pin on the AVR.
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.
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
 

hgmjr

Joined Jan 28, 2005
9,027
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
 

Thread Starter

Mathematics!

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

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

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

Rich (BB code):
#include <stdio.h>
#include <avr/interrupt.h>
#include <AVR\io.h>
 
int main (void)
{
 
  MCUCR = 0x00 ;  //This I don't know what to set it to for pin 16 interrupt to be triggered from high to low 
  //GICR  = 0x00 ; < ---this gives me a syntax error say that their is no variable GICR declared
 
sei() ;   // this turns interrupts on if they aren't on already.
 
 while (1) { }
}
 
ISR(INT0_vect)
{
 
  // Code to handle the event.
 
}
 
Last edited:

bertus

Joined Apr 5, 2008
22,278
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
 

retched

Joined Dec 5, 2009
5,207
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?
 

Thread Starter

Mathematics!

Joined Jul 21, 2008
1,036
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???
Rich (BB code):
#include <stdio.h>
#include <avr/interrupt.h>
#include <avr/io.h>

int main (void)
{
  MCUCR = 0x02 ;  //MCU control register 0x02 is for falling edge interrupts
  sei() ;

 while (1) { }
}

ISR(INT0_vect)
{
  
  // Code to handle the event.
  if( PIND | 0x05 ) //I put the keyboard data pin on PD4
  {
  // the if statement should execute if PD4 is high
  
  // if we got here it is a logical one
  }
  else
  {
   // if we got here it is a logical zero
  }
  
}

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.
 

hgmjr

Joined Jan 28, 2005
9,027
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???
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
 

Thread Starter

Mathematics!

Joined Jul 21, 2008
1,036
I noticed that you have omitted the GICR setup. Does using GICR as an L-value still generate an error?
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

Rich (BB code):
#include <stdio.h>
#include <avr/interrupt.h>
#include <avr/io.h>
volatile int keyboard_data = 0 ;
volatile int bitnumber = 0 ;
int main (void)
{
 
  MCUCR = 0x02 ;  //MCU control register 0x02 is for falling edge interrupts
  sei() ;
 
 while (1) { }
}
 
ISR(INT0_vect)
{
 
  if( bitnumber >= 13 )
  {
    bitnumber = 0 ;
    // AT this point the keyboard data has all lower 13 bits out of the
 //16 bits set with the error code , scancode ,...etc
 //so KNOW I NEED TO STORE THIS DATA IN SOME WAY?
 //I was think creating a large int array but maybe their is a better way.
 // Or some eeprom function I should use 
    // After keyboard_data is stored set it back to zero for next key
    keyboard_data = 0 ;
  }
  // Code to handle the event.
  if( PIND | (1<<PIND4) ) //I put the keyboard data pin on PD4
  {
  // the if statement should execute if PD4 is high
  // if we got here it is a logical one for that particular bit
  // switch statement turns a specific bit on logical 1
   switch( bitnumber )
   {
 
     case 0:
     keyboard_data = 0x01 ;
  break ;
 
     case 1:
     keyboard_data = keyboard_data | 0x02 ;
  break ;
  case 2:
     keyboard_data = keyboard_data | 0x04 ;
  break ;
  case 3:
     keyboard_data = keyboard_data | 0x08 ;
  break ;
  case 4:
     keyboard_data = keyboard_data | 0x10 ;
  break ;
  case 5:
     keyboard_data = keyboard_data | 0x20 ;
  break ;
 
     case 6:
     keyboard_data = keyboard_data | 0x40 ;
  break ;
     case 7:
     keyboard_data = keyboard_data | 0x80 ;
  break ;
  case 8:
     keyboard_data = keyboard_data | 0x100 ;
  break ;
  case 9:
     keyboard_data = keyboard_data | 0x200 ;
  break ;
  case 10:
     keyboard_data = keyboard_data | 0x400 ;
  break ;
  case 11:
     keyboard_data = keyboard_data | 0x800 ;
  break ;
  case 12:
     keyboard_data = keyboard_data | 0x1000 ;
  break ;
 
  default:
  //shouldn't ever get here !
  break ;
 
   }  
 
 
  }
  else
  {
   // if we got here it is a logical zero
   // set nothing 
  }
 
  bitnumber++ ; // increment what bit we are on next out of the 13 bit protocal
}

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
 

hgmjr

Joined Jan 28, 2005
9,027
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
 

hgmjr

Joined Jan 28, 2005
9,027
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
 

retched

Joined Dec 5, 2009
5,207
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.
 

Thread Starter

Mathematics!

Joined Jul 21, 2008
1,036
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?
 
Top