AVR - Interrupt-Vektor und Globale Variable
Ich bin mit einem ATmega32 zu unterbrechen, alle 32ms zu tun, einige willkürliche Sachen, die nicht wirklich wichtig für den Moment.
Ich bin mit dem timer overflow von timer0 interrupt funktioniert erwartungsgemäß und einwandfrei.
Mein problem ist ich habe eine Globale variable:
volatile int isSampling;
Ist das nicht geschrieben in der interrupt-Vektor. Ich habe gelesen, dass die integer benötigt werden volatile
zu entfernen die Möglichkeit, die compiler-Optimierungen, aber ich erklärte es als volatile
und seine immer noch nicht funktioniert.
#include <AVR/IO.h>
#include <util/delay.h>
#include <avr/interrupt.h>
char studentID[12] = {'S',1,2,3,4,5,6,7,'A','B','C','D'};
char buffer[72]; //Max bitlength = 6. * studentID length
char repcount[72];
int pointer;
volatile int isSampling;
void setup(void);
void startup(void);
void loadValue(unsigned char loadedValue);
void processValue(unsigned char processedValue, short bitLength);
void sendDot(void);
void sendDash(void);
int main(){
setup();
while(1)
{
if (isSampling == 1){
startup();
int i;
for (i = 0; i < 12; i++){
loadValue(studentID[i]);
//Flash lights after letter sent.
_delay_ms(500);
PORTB = 0xF0;
_delay_ms(500);
}
}
}
}
void setup(void){
DDRB = 0xFF;
sei();
TCCR0 = TCCR0 | 0x05;
TIMSK|=(1<<TOIE0);
TCNT0 = 0;
pointer = 0;
isSampling = 1;
}
ISR(TIMER0_OVF_vect)
{
//Every 32ms this interrupt vector is called.
isSampling = 0;
}
void startup(void){
//Play LED startup pattern
int i;
for (i = 0; i < 4; i++){
PORTB = 0b11110011; //Bit 5 is constantly sampled. 4 is output
_delay_ms(250);
PORTB = PORTB & 0x00;
_delay_ms(250);
}
_delay_ms(500);
_delay_ms(500);
}
void loadValue(unsigned char loadedValue){
switch (loadedValue){
case 1: processValue(0b01111000, 5);
case 2: processValue(0b00111000, 5);
case 3: processValue(0b00011000, 5);
case 4: processValue(0b00001000, 5);
case 5: processValue(0b00000000, 5);
case 6: processValue(0b10000000, 5);
case 7: processValue(0b11000000, 5);
case 8: processValue(0b11100000, 5);
case 9: processValue(0b11110000, 5);
case 0: processValue(0b11111000, 5);
case 'A': processValue(0b01000000, 2);
case 'B': processValue(0b10000000, 4);
case 'C': processValue(0b10100000, 4);
case 'D': processValue(0b10000000, 3);
case 'E': processValue(0b00000000, 1);
case 'F': processValue(0b00100000, 4);
case 'G': processValue(0b11000000, 3);
case 'H': processValue(0b00000000, 4);
case 'I': processValue(0b00000000, 2);
case 'J': processValue(0b01110000, 4);
case 'K': processValue(0b10100000, 3);
case 'L': processValue(0b01000000, 4);
case 'M': processValue(0b11000000, 2);
case 'N': processValue(0b10000000, 2);
case 'O': processValue(0b11100000, 3);
case 'P': processValue(0b01100000, 4);
case 'Q': processValue(0b11010000, 4);
case 'R': processValue(0b01000000, 3);
case 'S': processValue(0b00000000, 3);
case 'T': processValue(0b10000000, 1);
case 'U': processValue(0b00100000, 3);
case 'V': processValue(0b00010000, 4);
case 'W': processValue(0b01100000, 3);
case 'X': processValue(0b10010000, 4);
case 'Y': processValue(0b10110000, 4);
case 'Z': processValue(0b11000000, 4);
case '.': processValue(0b01010100, 6);
case ',': processValue(0b11001100, 6);
case '?': processValue(0b00110000, 6);
case '!': processValue(0b00110000, 5);
case ':': processValue(0b11100000, 6);
case '=': processValue(0b10001000, 5);
}
}
void processValue(unsigned char processedValue, short bitLength){
unsigned char result;
int i;
//Enter Loop at the length of bits in numerical morse code
for (i = 0; i < bitLength; i++){
result = processedValue & 0x80;
processedValue = processedValue << 1;
if (result) sendDash();
if (!result) sendDot();
_delay_ms(1000);
}
}
void sendDot(void){
//Send Dot
PORTB = 0x05;
_delay_ms(250);
PORTB = 0x00;
}
void sendDash(void){
//Send Dash
PORTB = 0x06;
_delay_ms(750);
PORTB = 0x00;
}
Okay ich hab gefunden, der den fehlerhaften code, der das problem verursacht, aber ich bin nicht sicher, warum die, die es verursacht.
Wenn ich entfernen loadValue(studentID[i])
von der Haupt-while-Schleife, der code funktioniert wie vorhergesagt. Aber wenn ich es wieder, es bricht wieder.
- Btw. Ich nehme an, Ihr mithilfe von C-code. C++ unterstützt keine default-int.
- Für diese extrem kurze Programm, dem empfehle ich, Lesen Sie den erzeugten Assembler-code.
- Sie sagte: "überlauf des timer0 interrupt funktioniert erwartungsgemäß und einwandfrei". Hast du wirklich überprüfen? Wenn nicht, schlage ich vor, fügen Sie einige code in der ISR schaltet einen Ausgang-Zeile und beobachten Sie es mit einem Rahmen.
- Ich denke, das problem ist, dass der Schreibzugriff auf "isSampling" ist nicht broadcastet der main-loop oder es nie geschrieben.
- Okay, ich habe in den code, wie verlangt. Ich fand den fehlerhaften code, so scheint es zu sein, die loadValue(studentID[i]) - Methode das ist, was es ist. Ich habe keine Ahnung, warum, aber...
- Und ja, ich kann stellen Sie sicher, dass die interrupts arbeiten, 100%
- Ich würde raten, dass die
_delay_ms
Funktion ist messing mit der interrupt-Maske irgendwie. Versuchen Sie, vereinfachen Sie den code unten, um eine viel einfachere Anwendung und sehen, ob du immer noch das Problem. - Hinzufügen eines default: arm auf Ihre switch-Anweisung.
- Charlesworth. Es scheint Ihr Recht, wenn ich kommentiere alle die _delay_ms Funktionen der code funktioniert wie vorhergesagt, es ist nur einmal habe ich Sie in Sie verwirren mit der globalen variable. Ich bin mir nicht sicher, aber vielleicht, vielleicht seine aufgrund der atomaren Natur der isSampling? Bitte beantworten Sie die Frage, damit ich akzeptieren kann. Danke.
- Ich verstehe nicht, wie
_delay_ms
könnte dies Auswirkungen auf die globalen Variablen; bei den meisten, ich könnte es mir vorstellen das clearing der interrupt-Maske, so dass deine ISR ist deaktiviert, wenn Sie einige Zeit.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die _delay_ms(500) Zeilen verursachen das problem wie bereits von Oli Charlesworth. Die _delay_ms () - Funktion kann zu unvorhersehbarem Verhalten führen, wenn ein zu hoher (über 250ms).
Nicht sicher, ob es das problem erklärt, aber Sie sind absichtlich nicht mit einer Pause nach jedem switch case Wert?
das problem trat an die definition des char-array
die Zahl 1,2,...,7 sollte wie unten