On Wed, 04 May 2011 13:13:34 -0500, "eneloop"
<eneloop1@n_o_s_p_a_m.gmx.de> wrote:
>Hello, my name is Sammy.
>
>I try to write an interrupt service routine for the keyboard interrupt.
>I'm using a Motorola 68HC08 and freescale's Codewarrior.
>Port A is connected with a button. Port B is connected with LED.
>If I push the button, LED should switch on. If I push it again LED should
>switch off.
>I'm very unexperienced with C and don't know how to do this.
[snippety snip]
Without wading through the Moto-specific registers (haven't touched one
of those since Noah was a seaman) you might want to consider a couple of
things.
Firstly, one very, very rarely wants to tie an external interrupt line
directly to a mechanical switch. Switches (and buttons and relays etc.)
bounce multiple times before they reach steady-state, causing multiple
interrupts, which is probably not the desired behavior.
For switches operating at "human speed" a response that occurs in less
than, say, 100 msec should be perceived as instantaneous. One approach
(there are many; do a 'net search on "switch debouncing") is to have
your program run a system tick that fires every 10 msec or so. When it
fires, poll the state of the switch. If the switch has changed state
since it was last stable *and* if it has been stable in the new state
for at least one polling interval, then declare that the switch has
"switched" and handle it appropriately.
The program should still toggle the port A bit as is, it just may do so
a lot of times...
Other observations: You've got two infinite loops in main(); you'll
never leave the inner (for(;;)) loop.
If setting DDRB to 0xFF is needed to configure the port as an output
(told you it's been forever since I looked at one of these chips), don't
you also need to set the bit for the LED attached to port A? It looks
like you intend to see a "walking bit" on the LEDs (plural) attached to
port B and a toggle of the one LED on port A. True?
--
Rich Webb Norfolk, VA
Reply by Tim Wescott●May 4, 20112011-05-04
On 05/04/2011 11:13 AM, eneloop wrote:
> Hello, my name is Sammy.
>
> I try to write an interrupt service routine for the keyboard interrupt.
> I'm using a Motorola 68HC08 and freescale's Codewarrior.
> Port A is connected with a button. Port B is connected with LED.
> If I push the button, LED should switch on. If I push it again LED should
> switch off.
> I'm very unexperienced with C and don't know how to do this.
>
>
>
> #include<hidef.h> /* for EnableInterrupts macro */
> #include "derivative.h" /* include peripheral declarations */
>
> void KBI_init(void)
> {
> /* This procedure is to prevent False Interrupts at initialisation*/
> KBSCR_IMASKK = 1; /* Mask Keyboard interrupts */
> KBIER_KBIE2 = 1; /* Enables pin2 of KBI by setting KBIE2(PTA2)
> */
> KBSCR_ACKK = 1; /* Clear any false interrupts */
> KBSCR_IMASKK = 0; /* Unmask Keyboard interrupts */
>
> /* END Avoidance of False Interrupts */
> /* Configures KBI Status& Control Register */
> KBSCR = 0; /* IMASKK=0: Clears KBI Mask Bit (Enable Ints)
> */
> /* MODEK=0: Interrupt requests on Falling Edge
> Only */
> }
>
> interrupt 15 void _KB_Interrupt (void)
> {
> KBSCR_ACKK = 1; /* Acknowledge KB Interrupts */
> PTA_PTA1 = ~PTA_PTA1; /* Toggles the LED */
> }
>
>
> // IO_Ports
> int delay = 5000;
>
> static void Delay(void) {
> int cnt = 0;
> while (cnt<delay) {
> __RESET_WATCHDOG(); /* feeds the dog */
> cnt++;
> }
> }
>
> static void LED(void) {
> unsigned char i;
> for (i = 1; i> 0; i<<=1) {
> PTB = i;
> Delay();
> }
> }
>
> // Main
> void main(void) {
> EnableInterrupts; /* enable interrupts */
>
> DDRB = 0xFF; // Data Direction Register Port B
>
> while(1) {
> LED();
> for(;;){
> LED();
> }
> }
>
> /* please make sure that you never leave this function */
> }
>
>
> Thanks in advance
> Sammy
>
>
>
> ---------------------------------------
> Posted through http://www.EmbeddedRelated.com
So, what's actually happening? What else have you done?
This looks good on the surface, except that you have done nothing to
debounce the switch. If you push the button and the light sometimes
changes and sometimes doesn't, then you need debounce.
You're depending on getting too many things right all at once. One of
the characteristics of this sort of task is that you've got all sorts of
things that have to be set up correctly, and sometimes the documentation
is only clear after the fact. You want to try to separate the problem
into small bits and get each little bit working before you move on to
the next.
In your case, you're trying to do three things: light an LED when you
want to, read the state of a button, and make interrupts work. I
_strongly suggest_ that you do those three things _separately_ in
precisely the order I'm giving: first, try to make the LED blink under
software control in the main loop -- don't mess with interrupts, or
buttons: just do this with a delay loop. Then, make the LED follow the
button (i.e., button down = LED on, button up = LED off). If you want
to be fancy change the blink rate with the button -- but don't do
anything in your code other then checking the button bit. Finally, when
you've gotten all that working and verified, _then_ do the last
increment and make it work with interrupts.
Note that in a real system things like button presses are often better
monitored in a task that repeats every 10ms or faster. You're not
getting an interrupt every time the switch bounces, you're not trying to
debounce things in interrupt space, you're not consuming lots of
interrupt time reacting to a human pushing a button, etc.
--
Tim Wescott
Wescott Design Services
http://www.wescottdesign.com
Do you need to implement control loops in software?
"Applied Control Theory for Embedded Systems" was written for you.
See details at http://www.wescottdesign.com/actfes/actfes.html
Reply by Tauno Voipio●May 4, 20112011-05-04
On 4.5.11 9:13 , eneloop wrote:
> Hello, my name is Sammy.
>
> I try to write an interrupt service routine for the keyboard interrupt.
> I'm using a Motorola 68HC08 and freescale's Codewarrior.
> Port A is connected with a button. Port B is connected with LED.
> If I push the button, LED should switch on. If I push it again LED should
> switch off.
> I'm very unexperienced with C and don't know how to do this.
A button does not switch cleanly, if there are no
special measures to handle a thing called contact
bounce: The contacts close and open several times
in the time scale of some milliseconds. The exact
number and timing depends on the mechanical structure
of the button and how it is pushed.
Due to the bounce, you will get a burst of very
quick pushes.
--
Tauno Voipio
Reply by eneloop●May 4, 20112011-05-04
Hello, my name is Sammy.
I try to write an interrupt service routine for the keyboard interrupt.
I'm using a Motorola 68HC08 and freescale's Codewarrior.
Port A is connected with a button. Port B is connected with LED.
If I push the button, LED should switch on. If I push it again LED should
switch off.
I'm very unexperienced with C and don't know how to do this.
#include <hidef.h> /* for EnableInterrupts macro */
#include "derivative.h" /* include peripheral declarations */
void KBI_init(void)
{
/* This procedure is to prevent False Interrupts at initialisation*/
KBSCR_IMASKK = 1; /* Mask Keyboard interrupts */
KBIER_KBIE2 = 1; /* Enables pin2 of KBI by setting KBIE2(PTA2)
*/
KBSCR_ACKK = 1; /* Clear any false interrupts */
KBSCR_IMASKK = 0; /* Unmask Keyboard interrupts */
/* END Avoidance of False Interrupts */
/* Configures KBI Status & Control Register */
KBSCR = 0; /* IMASKK=0: Clears KBI Mask Bit (Enable Ints)
*/
/* MODEK=0: Interrupt requests on Falling Edge
Only */
}
interrupt 15 void _KB_Interrupt (void)
{
KBSCR_ACKK = 1; /* Acknowledge KB Interrupts */
PTA_PTA1 = ~PTA_PTA1; /* Toggles the LED */
}
// IO_Ports
int delay = 5000;
static void Delay(void) {
int cnt = 0;
while (cnt <delay) {
__RESET_WATCHDOG(); /* feeds the dog */
cnt++;
}
}
static void LED(void) {
unsigned char i;
for (i = 1; i > 0; i<<=1) {
PTB = i;
Delay();
}
}
// Main
void main(void) {
EnableInterrupts; /* enable interrupts */
DDRB = 0xFF; // Data Direction Register Port B
while(1) {
LED();
for(;;){
LED();
}
}
/* please make sure that you never leave this function */
}
Thanks in advance
Sammy
---------------------------------------
Posted through http://www.EmbeddedRelated.com