Hallo,
Habe ein kleines Problem, habe hier eine Testschaltung mit einem Atmel
1284P und einem Rauchmelder der bei Auslösung UART Daten auswirft, die
kann ich lesen soweit so gut.
Nun möchte ich das der Atmel solange in Power-Down geht, bis auf dem
UART Daten vom Rauchmelder empfangen werden.
Der Atmel wird mit einem Quarz 10 Mhz betrieben, vom RX habe ich eine
Leitung an PCINT0 (PA0) angeklemmt und verwende folgenden Code:
1
int count;
2
3
int main(void)
4
{
5
sei();
6
uart0_init();
7
unsigned char data;
8
9
while(1)
10
{
11
data = uart_gets();
12
if(data & UART_NO_DATA)
13
{
14
}
15
else
16
{
17
uart1_puts( (unsigned char) data);
18
}
19
20
PCICR = (1<<PCINT0);
21
PCMSK0 = (1<<PCINT0);
22
23
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
24
sleep_enable();
25
sei();
26
27
LED_PORT &= ~(1 << LED_PWR_PIN); // PWR LED Aus
28
29
sleep_cpu();
30
sleep_disable();
31
LED_PORT |= (1<<LED_PWR_PIN); // PWR LED an.
32
}
33
}
34
35
ISR(PCINT0_vect)
36
{
37
count++;
38
}
Da RXD noch mit PCINT0 (PA0) verbunden ist, gibts flanken, leider
erwacht der Atmel nicht aus seinem Dornrößchen schlaf.
An was könnte das liegen? Ist mein Code falsch?
Grüße,
Daniel
Thomas Eckmann schrieb:> Daniel schrieb:>> PCICR = (1<<PCINT0);>> PCMSK0 = (1<<PCINT0);> Das ist zwar grundsätzlich falsch, aber in diesem Fall zufällig richtig.> PCMSK0 = (1 << PCINT0);> PCICR = (1 << PCIE0);>> ist die richtige Initialisierung.>> Nach dem Startbit wird der Controller sofort wieder schlafen gelegt.> Damit läuft auch der UART nicht.>> int count;> unsigned char bSleep;>> int main(void)> {> uart0_init();> unsigned char data;>> PCMSK0 = (1 << PCINT0);> PCICR = (1 << PCIE0);> PCIFR = PCIFR;>> LED_PORT |= (1<<LED_PWR_PIN); // PWR LED an.> set_sleep_mode(SLEEP_MODE_PWR_DOWN);> sleep_enable();> bSleep = 1;> sei();>> while(1)> {> data = uart_gets();> if(data & UART_NO_DATA)> {> }> else> {> uart1_puts( (unsigned char) data);> while(UARAT_BUSY);> bSleep = 1;> }>> if(bSleep)> {> LED_PORT &= ~(1 << LED_PWR_PIN); // PWR LED Aus> sleep_cpu();> bSleep = 0;> LED_PORT |= (1<<LED_PWR_PIN); // PWR LED an.> }> }> }>> ISR(PCINT0_vect)> {> count++;> }>> mfg.
Hallo,
Das ist mir gar nicht aufgefallen, das der UART nicht läuft ist mir
klar, daher habe ich vom UART (RXD) eine Strippe zum INT gezogen, da
eben der UART nicht läuft, aber dennoch flanken am RXD + INT0 ankommen.
passt das dann trotzdem so? das ganze läuft mit 3.3V :)
werde dein Code nachher mal testen, aber richtig, der Atmel legt sich
direkt nach dem Start schlafen, nur wecken funktionierte nicht...
Grüße,
Daniel
Peter Dannegger schrieb:> Was gefällt Dir an PCINT24 nicht?
Das ist erst die nächste Baustelle.
Daniel schrieb:> nur wecken funktionierte nicht...
Woher weisst du das? Das kurze Aufblitzen der Led kriegst du
wahrscheinlich gar nicht mit.
mfg.
Thomas Eckmann schrieb:> Peter Dannegger schrieb:> Was gefällt Dir an PCINT24 nicht?
Mein Problem war mit PCINT24, das auf dem UART nur Mist kam obwohl
nichts gesendet wurde. Liegt evtl am UART Interrupt von der Fleury
Library?
Daher meine Lösung mit nicht PCINT24
> Das ist erst die nächste Baustelle.>> Daniel schrieb:> nur wecken funktionierte nicht...>> Woher weisst du das? Das kurze Aufblitzen der Led kriegst du> wahrscheinlich gar nicht mit.>> mfg.
Das ist korrekt, das kriege ich so nicht mit aber ich hatte noch ein
Salae Logic 16 dran. Und der zeigte lediglich low Pegel für die Power
LED an.
// offtopic an:
Ich habe nur jetzt aktuell das Phänomen, wenn ich übers Atmel Studio 6.2
SP1 den Code per ISP uploade, dann kriege ich keine Verbindung zum Atmel
obwohl mir im Studio die 3.3V angezeigt werden beim auslesen.
Was noch auffällig ist, ist der Code oben und ich flashe neu, steht
hinter meinem AVR JTAGice mkII [Busy] ich muss erst den jtagice vom USB
trennen bevor das wieder läuft. Und das nach jedem flashen via ISP 6
PIN.
Habe das selbe Problem mit einem avrisp mkII, was mich verwirrt.
Daher kann ich das aktuell nicht testen :/
Daniel schrieb:> Ich habe nur jetzt aktuell das Phänomen, wenn ich übers Atmel Studio 6.2> SP1 den Code per ISP uploade, dann kriege ich keine Verbindung zum Atmel> obwohl mir im Studio die 3.3V angezeigt werden beim auslesen.>> Was noch auffällig ist, ist der Code oben und ich flashe neu, steht> hinter meinem AVR JTAGice mkII [Busy] ich muss erst den jtagice vom USB> trennen bevor das wieder läuft. Und das nach jedem flashen via ISP 6> PIN.>> Habe das selbe Problem mit einem avrisp mkII, was mich verwirrt.
Dann bring erstmal deine Umgebung in Ordnung. Eventuell durch
Neuinstallation. Du wärest nicht der erste, der sich da was zerschossen
hat.
So ist nicht gewährleistet, dass das Programm überhaupt richtig
übertragen wird.
mfg.
Hallo,
// offtopic an
So, nach Software und Treiber Problemen, klappts nun, aber nicht so wie
gedacht. (Der Fehler lag definitiv am Atmel Studio 6.2, keine Probleme
mehr mit Studio 6.1 SP1)
Zur Erklärung, ich habe ein Rauchmelder der Firma GIRA, der verfügt über
ein UART Ausgang, das es hier auch Funk-Module für teures Geld zu kaufen
gibt, daher bau ich ein eigenes.
Da später noch ein RFM Modul dran kommt, ist der Power-Down eigentlich
schon Wichtig, wenn ich nich an 30 Meldern nach Wochen Batterien
wechseln möchte.
Der Atmega1284p ist aktuell nur mein Entwicklungsboard, dieser wird
später ersetzt durch ein Atmega8L, bevor fragen kommen :)
So habe den Code aktuell nun so modifiziert, das er aktuell perfekt
funktioniert:
uart1_puts("=> Frage Seriennummer von Rauchmelder ab\r\n");
58
gira_rm_authentication();
59
_delay_ms(250); // Auf ACK vom Melder warten
60
rauchmelder_serial = gira_rm_getSerialNumer(); // Rauchmelder sendet 5 mal Seriennummer via UART0
61
_delay_ms(50);
62
63
while(1)
64
{
65
uart_rm_data = uart_getc();
66
67
if(uart_rm_data & UART_NO_DATA)
68
{
69
/* Tu nichts */
70
}
71
else
72
{
73
// Empfangene Daten an UART1 Debug übergeben
74
75
uart1_putc((unsigned char) uart_rm_data);
76
//while(uart_busy()); // Auskommentiert, da es in der fleury keine UART_BUSY gibt.
77
bSleep = 1;
78
}
79
80
if(bSleep)
81
{
82
LED_PORT &= ~ (1 << LED_PWR_PIN); // PWR LED Aus
83
sleep_cpu();
84
bSleep = 0;
85
LED_PORT |= ( 1 << LED_PWR_PIN);
86
}
87
}
88
}
89
90
ISR(PCINT0_vect)
91
{
92
count++;
93
}
Nach der Authentifizierung kriege ich vom Melder ein ACK zurück, kann
dann die Seriennummer abfragen, diese schickt mir der melder nach
absenden ca 0,2 - 0,3 Sekunden das erste mal Zurück. Dann weitere 4 mal
im 5 Sekunden abstand.
So, im Power-Down Modus kriegt der Atmel das "ACK" vom Melder zurück,
frägt die Seriennummer des Melders an geht (Geht auch über den UART
raus) direkt danach in den Power-Down und kriegt (logisch) die erste
Seriennummer übertragung nach ca 0,2 - 0,3 Sekunden nicht mehr mit bzw
die Hochfahrzeit wohl ist zu lang durch den 8 Mhz Quarz/Crystal.
In den nachfolgenden 4 Übertragungen wacht der Atmel zwar auf, aber bei
der UART Übertragung zum PC kommt nur mist an.
Die PWR-LED "Blinkt" zwar kurz wenn der Atmel etwas empfangen hat, aber
ich weiß nicht ob der Atmel auch den vollen String vom Rauchmelder
empfängt.
Nun stelle ich natürlich die Intelligente Frage die jeder Stellt, wie
muss ich die Fleury UART lib erweitertern, so das ich evtl. mit bekomme
ob der UART Busy ist?
Mein Code hier:
1
uint8_t uart_busy(void)
2
{
3
return UART0_CONTROL & _BV(UART0_UDRIE);
4
}
funktioniert nich so dufte, welche Möglichkeit habe ich denn den
"Schlafmodus" so zu verzögern, das die Übertragung gewährleistet ist?
Der Rauchmelder sendet mir mit jedem Event den Anfang und das Ende des
Strings immer mit einem <STX>MELDUNG<ETX>
Oder kann ich die UART Lib irgendwie dazu kriegen die sleep_mode zu
disablen?
grüße,
daniel
Daniel schrieb:> Hallo, keiner eine Idee ?!?
LOL.
Warten must du sowieso, ob das die UART-gesteuerten genauen 1,04ms
sind oder deine 1ms mit delay ist eigentlich egal, oder ?
1
{
2
// Empfangene Daten an UART1 Debug übergeben
3
4
uart1_putc((unsignedchar)uart_rm_data);
5
//while(uart_busy()); // Auskommentiert, da es in der fleury keine UART_BUSY gibt.
6
7
_delay_ms(1);// reingeschrieben, da die Fleury-Lib grosstenteils Mist ist
8
9
bSleep=1;
10
}
Es funktioniert mit 1ms bestimmt, da der Stoppbit == Idle und ist somit
sogar schneller.
Falls doch nicht, einfach auf 2ms verlängern oder delay_us hinterher.
Daniel schrieb:> Der Fehler lag definitiv am Atmel Studio 6.2, keine Probleme> mehr mit Studio 6.1 SP1
Na ja, auf den ersten Blick fällt schon mal ein fehlendes volatile auf.
Oliver
Daniel schrieb:> funktioniert nich so dufte, welche Möglichkeit habe ich denn den> "Schlafmodus" so zu verzögern, das die Übertragung gewährleistet ist?Daniel schrieb:> In den nachfolgenden 4 Übertragungen wacht der Atmel zwar auf, aber bei> der UART Übertragung zum PC kommt nur mist an.
Grundsätzlich solltest du die Kommunikation erstmal ohne Sleepmode zum
Laufen bringen. Wenn das zu 100% funktioniert, baust du den Sleep ein.
Im Moment kämpfst du an 2 Fronten. Du bist dir einerseits nicht sicher,
ob sie sich überhaupt verstehen oder ob es am Sleepmode hapert.
Daniel schrieb:> Oder kann ich die UART Lib irgendwie dazu kriegen die sleep_mode zu> disablen?
Ein paar Bytes über UART einzulesen ist weder Hochtechnologie noch
Geheimwissenschaft. Bau dir deine eigenen Funktionen zum Senden und
Empfangen. Die Herausforderung liegt ohnehin in der Auswertung der
empfangenen Daten. Dabei hilft dir die Fleury-Lib aber sowieso nicht.
mfg.