bitte nur ein kuzes beispiel um zu testen ob ein interrapt überhaupt funktioniert
Druckbare Version
bitte nur ein kuzes beispiel um zu testen ob ein interrapt überhaupt funktioniert
dann musst du sagen in was du proggen tust.
mfg pebisoft
volatile sagt mir leider garnichts
#include <stdint.h>
was mach die datei da ich sie nicht habe kann ich das leider nicht selbst herasufinden
in c. ich binutze winavr
Wenn du nicht am Quellcode des Compilers rumgepfuscht hast (unwahrscheinlich, da du Windows benutzt), funktionieren Interrupts auf jeden Fall.
Du musst schon genauer beschreiben, was du erreichen und testen möchtest.
Code:#include <avr/pgmspace.h>
#include "kb.h"
#include "serial.h"
#include "gpr.h"
#include <avr/signal.h>
#include <avr/interrupt.h>
#include "scancodes.h"
#include <stdio.h>
#include <avr/io.h>
#define BUFF_SIZE 64
unsigned char edge, bitcount; // 0 = neg. 1 = pos.
unsigned char kb_buffer[BUFF_SIZE];
unsigned char *inpt, *outpt;
void init_kb(void)
{
DDRD = DDRD & 0xFB;
inpt = kb_buffer; // Initialize buffer
outpt = kb_buffer;
buffcnt = 0;
MCUCR = 2; // INT0 interrupt on falling edge
edge = 0; // 0 = falling edge 1 = rising edge
bitcount = 11;
// enable_external_int(SIG_INTERRUPT0);
}
SIGNAL(SIG_INTERRUPT0)
{buffcnt++; //zum testen
static unsigned char data; // Holds the received scan code
if (!edge) // Routine entered at falling edge
{
if(bitcount < 11 && bitcount > 2) // Bit 3 to 10 is data. Parity bit,
{ // start and stop bits are ignored.
data = (data >> 1);
if(PIND & 8)
data = data | 0x80; // Store a '1'
}
MCUCR = 3; // Set interrupt on rising edge
edge = 1;
} else { // Routine entered at rising edge
MCUCR = 2; // Set interrupt on falling edge
edge = 0;
if(--bitcount == 0) // All bits received
{
decode(data);
bitcount = 11;
}
}
}
void decode(unsigned char sc)
{
static unsigned char is_up=0, shift = 0, mode = 0;
unsigned char i;
if (!is_up) // Last data received was the up-key identifier
{
switch (sc)
{
case 0xF0 : // The up-key identifier
is_up = 1;
break;
case 0x12 : // Left SHIFT
shift = 1;
break;
case 0x59 : // Right SHIFT
shift = 1;
break;
case 0x05 : // F1
if(mode == 0)
mode = 1; // Enter scan code mode
if(mode == 2)
mode = 3; // Leave scan code mode
break;
default:
if(mode == 0 || mode == 3) // If ASCII mode
{
if(!shift) // If shift not pressed,
{ // do a table look-up
for(i = 0; unshifted[i][0]!=sc && unshifted[i][0]; i++);
if (unshifted[i][0] == sc) {
put_kbbuff(unshifted[i][1]);
}
} else { // If shift pressed
for(i = 0; shifted[i][0]!=sc && shifted[i][0]; i++);
if (shifted[i][0] == sc) {
put_kbbuff(shifted[i][1]);
}
}
} else{ // Scan code mode
print_hexbyte(sc); // Print scan code
put_kbbuff(' ');
put_kbbuff(' ');
}
break;
}
} else {
is_up = 0; // Two 0xF0 in a row not allowed
switch (sc)
{
case 0x12 : // Left SHIFT
shift = 0;
break;
case 0x59 : // Right SHIFT
shift = 0;
break;
case 0x05 : // F1
if(mode == 1)
mode = 2;
if(mode == 3)
mode = 0;
break;
case 0x06 : // F2
clr();
break;
}
}
}
void put_kbbuff(unsigned char c)
{
if (buffcnt<BUFF_SIZE) // If buffer not full
{
*inpt = c; // Put character into buffer
inpt++; // Increment pointer
buffcnt++;
if (inpt >= kb_buffer + BUFF_SIZE) // Pointer wrapping
inpt = kb_buffer;
}
}
int kbgetchar(void)
{
int byte;
while(buffcnt == 0); // Wait for data
byte = *outpt; // Get byte
outpt++; // Increment pointer
if (outpt >= kb_buffer + BUFF_SIZE) // Pointer wrapping
outpt = kb_buffer;
buffcnt--; // Decrement buffer count
return byte;
}
Ok, du hast einen Quellcode gepostet (benutz das nächste Mal bitte code-Tags). Und was ist nun deine Frage?
Willst du, dass ich völlig kommentarlos ein Kochrezept poste? Meine Kristallkugel ist leider gerade in der Reperatur... :/
ich habe zum testen
SIGNAL(SIG_INTERRUPT0)
{
buffcnt++; //zum testen
reingeschriben. In der main lase ich buffcnt auf einem LCD anzeigen. buffcnt bleibt null egal was ich an dem pin mache
Du mußt buffcnt mit dem berühmten "volatile" definieren.
volatile datatyp name;
WinAvr hat die Eigenschaft, für datendefinitionen ganz einfach Register-space zu verwenden. dadurch geht manches recht flott.
ABER: beim interrrupt werden die Register gepusht und dann gepoppt, d.h. was immer die Interrupt routine reinschreibt, ist nachher wieder weg.
Durch "volatile" zwingt man ihn, den Wert im SRAM zu führen, dort hinzuschreiben und zu holen. dadurch funktioniert erst der datenaustausch mit Interrupt-routinen.
Wenn man mich fragt (was aber keiner tut), ist die Bezeichnung nicht ganz glücklich.