How I would do it, if you really really want to use interrupts:
(untested:)
volatile unsigned char pressed = 0;
void setup()
{
pinMode(2,INPUT);
Serial.begin(9600);
attachInterrupt(0, bpress, RISING);
}
void loop()
{
if (pressed == 1) {
Serial.println("Pressed");
pressed = 0;
}
}
void bpress()
{
pressed = 1;
}
The theory:
In the loop:
If the variable "pressed" is 1, then print out that the button is pressed, then set the variable "pressed" to 0.
In the interrupt:
Set the variable "pressed" to 1.
You press the button, which sets the pressed flag. The main loop notices that the pressed flag is set, and tells you, resetting the pressed flag so it only tells you once. Next time you press the button the pressed flag gets set to 1 again, and the main loop tells you, etc.
The main thing to notice here is that the "pressed" variable is set as "volatile". This tells the compiler it shouldn't trust what it thinks the variable might contain and optimize it away, and instead force it to get the value from memory every time it is referenced. This is needed for interrupts, as the compiler cannot know for sure when the variable will have been changed, so its optimizations will be wrong.
Also, the variable is an "unsigned char", aka "byte". This is a single byte of memory, and most simple operations, like assignments etc, are fairly atomic, and the interrupt shouldn't cause any problems interrupting accesses to that variable. If it were an int, then it would take multiple assembly instructions to access or modify the variable, and there is a chance the interrupt could be fired in the middle of accessing the variable, with the possibility of the variable ending up corrupted. Not really an issue for this example, but something to keep at the back of your mind.