PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : USART - WARUM GEHT ES NICHT? - BITTE HELFT MIR



Kaiser-F
05.09.2005, 07:14
Hallo,

Ich bin am verzweifeln!

Ich will dass mein ATmega8535 signale per USART empfängt.

Der USART ist ja im prinzip so easy, aber trotzdem bekomm ich es nicht hin, die Signale zu empfangen, ich verstehs nicht warum!

Zunächst mal zum programm.

Ich benutze externe c-files um bestimmt Funktionen einfacher in Projekten einzubinden.

Daher sind auch die USART-Funktionen in der usart.c:







/************************************************** ****************************/
/******************************* Kaiser Franz *********************************/
/************************************************** ****************************/

#include "usart.h"

#define F_CPU 7372800
#define USART_BAUD_RATE 115200
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)


// USART - FUNKTIONEN
//===============================================

void USART_init(void){

UBRRL |= (uint8_t) USART_BAUD_SELECT;

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);


}

void USART_transmit(uint8_t c){
while(!(UCSRA & (1<<UDRE)));
UDR = c;
}

void USART_transmit_string(uint8_t *string){
while(!(UCSRA & (1<<UDRE)));
while( *string){ USART_transmit (*string++); }
}

void USART_transmit_bin(uint8_t c){

if( c & (1<<7) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
if( c & (1<<6) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
if( c & (1<<5) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
if( c & (1<<4) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
if( c & (1<<3) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
if( c & (1<<2) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
if( c & (1<<1) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }
if( c & (1<<0) ){ USART_transmit(0x31); } else { USART_transmit(0x30); }

}



Wichtig hier ist ja eigentlich nur das USART_init():



void USART_init(void){

UBRRL |= (uint8_t) USART_BAUD_SELECT;

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);


}



Hier noch die main.c:



/************************************************** **************************/
//
// Programmname : USART
//
// Chip type : ATmega8535
// Clock frequency : 7,3728 MHz
//
//************************************************** **************************/


// INCLUDE & DEFINE
//================================================== ===========================


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#include <usart.h>


// HAUPTFUNKTION
//================================================== ===========================
int main (void)
{
// D A T E N R I C H T U N G :
//===============================================

// PORTA Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRA = 0b11111111; //
PORTA = 0b00000000; //

// PORTB Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRB = 0b00000000; //
PORTB = 0b00000000; //

// PORTC Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRC = 0b00000000; //
PORTC = 0b11111111; //

// PORTD Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRD = 0b00000000; //
PORTD = 0b00000000; //


// Interrupts freigeben:
//===============================================
sei();


// Funktionen:
//===============================================


SIGNAL( SIG_USART_RECV )
{
uint8_t data;
data = UDR;

/* echo */
USART_transmit(data);

}



// Initialisieren:
//===============================================
USART_init();
USART_transmit_string("USART Init \r");

uint8_t x;

// Hauptschleife
//================================================== ===========================
while (1) {


if (bit_is_clear (PINC, PINC0) & (x == 0)) {

USART_transmit_string("PIND 0 getippt ");

x=1;
}

if (bit_is_clear (PINC, PINC7)){ x=0; }


PORTA = UCSRA;
}
}


mit USART_transmit_string(" BLABLA "); sende ich... da gab es nochnie Probleme damit....

aber nun will ich Empfangen und habe einfach mal das hier geschrieben:



// Interrupts freigeben:
//===============================================
sei();


// Funktionen:
//===============================================


SIGNAL( SIG_USART_RECV )
{
uint8_t data;
data = UDR;

/* echo */
USART_transmit(data);

}


Damit sollte er die Daten Empfangen und gleich wieder weitersenden.



SO, nun zu dem was passiert, (bzw. nicht passiert):

Ich schalte ein:

es wird vom MCU gesendet: USART Init.

UCSRA wird ja an PortA ausgegeben,
nun Leuchtat da :
TXC = USART Transmit Complete
UDRE = USART Data Register Empty



Jetzt sende ich an den MCU, irgend EIN zeichen:

an UCSRA sind alle Bits LOW,
Der MCU reagiert nicht mehr, auch nicht auf meine Tastenbefehle auf PORTC...

An was kann das liegen? bitte helft mir.

Ich habe 3 Testboards, an allen ist das Selbe. Leitungsfehler kann man ausschließen....

kater
05.09.2005, 07:40
Dein Problem liegt hier:


SIGNAL( SIG_USART_RECV )
{
uint8_t data;
data = UDR;

/* echo */
USART_transmit(data);

}

Du versuchst aus einer INT routine heraus USART_transmit aufzurufen. Diese Funktion wartet auf einen INT bis Platz ist ein Zeichen zu senden. Aber die INTs sind dekativiert wenn du in der Routine bist. Also wartet es ewig.
Die Loesung waere USART_transmit im normalen Programm aufzurufen.

Kaiser-F
05.09.2005, 07:47
Hallo kater,

Vielen Dank für deine Antwort!

Ich habe deinen Rat befolgt un habe die datei in eine Variable gespeichert.

Zur übersicht habe ich einen neue main.c File geschrieben in der alles enthalten ist was ich einsetze:



#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define F_CPU 7372800
#define USART_BAUD_RATE 115200
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)



void USART_init(void){

UBRRL |= (uint8_t) USART_BAUD_SELECT;

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);


}

void USART_transmit(uint8_t c){
while(!(UCSRA & (1<<UDRE)));
UDR = c;
}

void USART_transmit_string(uint8_t *string){
while(!(UCSRA & (1<<UDRE)));
while( *string){ USART_transmit (*string++); }
}


uint8_t data;

SIGNAL( SIG_USART_RECV )
{

data = UDR;

}


int main (void)
{
// D A T E N R I C H T U N G :
//===============================================

// PORTA Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRA = 0b11111111; //
PORTA = 0b00000000; //

// PORTB Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRB = 0b00000000; //
PORTB = 0b00000000; //

// PORTC Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRC = 0b00000000; //
PORTC = 0b11111111; //

// PORTD Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRD = 0b11111111; //
PORTD = 0b00000000; //


sei();

USART_init();
USART_transmit_string("USART INIT - OK ");


while (1) {

PORTA = UCSRA;
PORTD = data;

}
}

Leider tritt noch immer das selbe Problem auf. ](*,)

Das will einfach nicht [-(

Ich kann mir das nicht erklären.... Bitte helft mir. 8-[

PicNick
05.09.2005, 08:01
Du mußt "data" auf jeden Fall volatile definieren
volatile static uint8_t data;
Sonst haben die signal-routine und "main" verschiedene "data"

Kaiser-F
05.09.2005, 08:06
Hallo,

Danke für deine Antwort...

Leider immer noch das selbe Spiel...




#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define F_CPU 7372800
#define USART_BAUD_RATE 115200
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)



void USART_init(void){

UBRRL |= (uint8_t) USART_BAUD_SELECT;

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);


}

void USART_transmit(uint8_t c){
while(!(UCSRA & (1<<UDRE)));
UDR = c;
}

void USART_transmit_string(uint8_t *string){
while(!(UCSRA & (1<<UDRE)));
while( *string){ USART_transmit (*string++); }
}


volatile static uint8_t data;

SIGNAL( SIG_USART_RECV )
{

data = UDR;

}


int main (void)
{
// D A T E N R I C H T U N G :
//===============================================

// PORTA Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRA = 0b11111111; //
PORTA = 0b00000000; //

// PORTB Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRB = 0b00000000; //
PORTB = 0b00000000; //

// PORTC Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRC = 0b00000000; //
PORTC = 0b11111111; //

// PORTD Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRD = 0b11111111; //
PORTD = 0b00000000; //


sei();

USART_init();
USART_transmit_string("USART INIT - OK ");


while (1) {

PORTA = UCSRA;
PORTD = data;

}
}

PicNick
05.09.2005, 08:20
Du, ich stelle da mal ein zip mit einem gcc-projekt im Entwicklungs-Stadium rein. das tut eigentlich nix, außer daß es jede sekunde mal zum Terminal eine Text schickt, und wenn man dort ein "L" eingibt, brint er den text "left", sonst "right".
Also absolut geistlos, aber das Uart-Zeugs funktioniert.
(Senden und Empfangen ist beide gepuffert und mit interrupt)

Schau die alles an, was irgendwie "usart" heißt, vielleicht fällt dir ja selbst was auf.

SprinterSB
05.09.2005, 08:22
Was mit auffällt:
-1- sei() sollte nach USART_init() stehen.
-2- UBRRL = (uint8_t)... und nicht |=
-3- UBRRH = 0; fehlt
-4- am Ende von USRT_init() UDR auslesen um evtl undefinierten Zustand zu beheben. zB data = UDR.

Kaiser-F
05.09.2005, 08:39
Vielen Dank für die große Hilfe!

Tatsächlich lag es daran dass "sei();" nach "USART_init();" gehört,

Also am besten hirekt vor der Hauptschleife "while(1){}"

EDIT: Das ist mir auch im beispiel von PicNick aufgefallen...




#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define F_CPU 7372800
#define USART_BAUD_RATE 115200
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)

volatile static uint8_t data;

void USART_init(void){

UBRRH = 0;
UBRRL = (uint8_t) USART_BAUD_SELECT;

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

data = UDR;

}

void USART_transmit(uint8_t c){
while(!(UCSRA & (1<<UDRE)));
UDR = c;
}

void USART_transmit_string(uint8_t *string){
while(!(UCSRA & (1<<UDRE)));
while( *string){ USART_transmit (*string++); }
}




SIGNAL( SIG_USART_RECV )
{

data = UDR;

}


int main (void)
{
// D A T E N R I C H T U N G :
//===============================================

// PORTA Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRA = 0b11111111; //
PORTA = 0b00000000; //

// PORTB Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRB = 0b00000000; //
PORTB = 0b00000000; //

// PORTC Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRC = 0b00000000; //
PORTC = 0b11111111; //

// PORTD Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRD = 0b11111111; //
PORTD = 0b00000000; //




USART_init();
USART_transmit_string("USART INIT - OK ");

sei();

while (1) {

PORTA = UCSRA;
PORTD = data;

}
}


An dieser Stelle hätte ich noch eine kurze Frage;

Wenn ich ein signal empfange, dann führt der MCU die Interruptroutine aus, aber er sendet auch wieder "USART INIT - OK",

Er führt also die main-Funktion von anfang an wieder aus...

dachte immer Interrupts "stoppen" das programm an der aktuellen stelle, Frühren die Interruptroutine aus, und machen dort weiter wo sie aufgehört haben....?

Das ist jetzt mei mir nicht so...

Könntet ihr mich da kurz aufklehren..?

SprinterSB
05.09.2005, 09:02
hmmm ist wohl noch die alte Quelle.

::Edit::

sorry, lag an meine Brauser-Cache

Kaiser-F
05.09.2005, 09:03
Wie meinst du das?

SprinterSB
05.09.2005, 09:12
An dieser Stelle hätte ich noch eine kurze Frage;

Wenn ich ein signal empfange, dann führt der MCU die Interruptroutine aus, aber er sendet auch wieder "USART INIT - OK",

Er führt also die main-Funktion von anfang an wieder aus[...]
Das kann eigentlich nur dann passieren, wenn dein AVR abschmiert und ab RESET neu anfängt. Das könnte zB passieren, wenn dein SRAM überläuft (Stack etc) oder ein Interrupt ausgelöst wird, zu dem es keine ISR gibt. Die avr-gcc Defaults für die VECTAB sind RESET-Einträge.

Allerdings sehe ich jetzt nicht, warum das in deinem Beispiel so sein sollte.

SprinterSB
05.09.2005, 09:29
hmmm in der ISR muss man das RXC-Flag löschen, damit direkt nach Beenden der ISR diese nicht sofort wieder angesprungen wird. Das geschieht normalerweise durch Lesen von UDR.
Im Fehlerfalls empfieht das Manual nen flush der Art
while (UCSRA & (1 << RXC)) dummy = UDR;

Falls das RXC-Flag das Poblem ist, verstehe ich aber immer noch nicht, warum ein Restart gemacht wird. Und falls der flush fehlt, geht er solange in die ISR bis das RXC resettet ist... *grübel*

Kaiser-F
05.09.2005, 11:13
Oh mann oh mann....

dass das immer bei mir sein muss? und ausgerechnet bei eigentlich einfachen sachen???

Ich les grad nochmal den interrupt bereich im Datenblatt.... evtl steht da was...

PicNick
05.09.2005, 11:23
Um es auszuschließen: Schau mal, ob die RAMTOP Annahme des Compilers mit der Realität übereinstimmt. (Und ob er eh für den richtigen Prozessor übersetzt )
Wenn nicht, kann es sehr seltsame Effekte geben.

SprinterSB
05.09.2005, 11:31
Um auch das auszuschliessen: Du benutzt doch nen Pegelwandler wie MAX232?

Kaiser-F
05.09.2005, 11:43
Jap, ich benutze ein MAX232:

Um es mal ein wenig greifbarer zu machen;

Biddeschön ;-)

EDIT: Wohlgemerkt, ich kann jetzt Daten Empfangen, aber wie gesagt, das mit dem Interrupt ist so komisch, dass der die MAIN() Funktion NEU ausführt, den Gesendeten Wert merkt er sich... und gibt in aus

SprinterSB
05.09.2005, 11:46
hmmm Mus dass TxD des PC nicht zum RxD des µC?
Rxd ist IN unf TxD ist OUT, sonst schaltest zu 2 Ausgänge/Eingänge zusammen.
Wundert mich, daß su überhaupt was rüberkommt...

Kaiser-F
05.09.2005, 11:49
Am board sind Jumper, welche ich um 90°drehe, um diese zu kreuzen... weil ich ja noch einen USART-Stecker habe, mir den ich zwei testboards verbinde.... da muss dann eines kreuzbar sein....

das stimmt dann schon. Bei interesse kann ich euch ja den Ganzen Plan geben...



EDIT:

Hier die LSS file, für PickNicks Ausschließverfahren ;-)

PS: in der Makefile steht:
# MCU name
MCU = atmega8535


main.elf: file format elf32-avr

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000000ec 00000000 00000000 00000094 2**0
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000012 00800060 000000ec 00000180 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000001 00800072 00800072 00000192 2**0
ALLOC
3 .noinit 00000000 00800073 00800073 00000192 2**0
CONTENTS
4 .eeprom 00000000 00810000 00810000 00000192 2**0
CONTENTS
5 .stab 000003b4 00000000 00000000 00000194 2**2
CONTENTS, READONLY, DEBUGGING
6 .stabstr 000005af 00000000 00000000 00000548 2**0
CONTENTS, READONLY, DEBUGGING
Disassembly of section .text:

00000000 <__vectors>:
0: 14 c0 rjmp .+40 ; 0x2a
2: 2d c0 rjmp .+90 ; 0x5e
4: 2c c0 rjmp .+88 ; 0x5e
6: 2b c0 rjmp .+86 ; 0x5e
8: 2a c0 rjmp .+84 ; 0x5e
a: 29 c0 rjmp .+82 ; 0x5e
c: 28 c0 rjmp .+80 ; 0x5e
e: 27 c0 rjmp .+78 ; 0x5e
10: 26 c0 rjmp .+76 ; 0x5e
12: 25 c0 rjmp .+74 ; 0x5e
14: 24 c0 rjmp .+72 ; 0x5e
16: 23 c0 rjmp .+70 ; 0x5e
18: 22 c0 rjmp .+68 ; 0x5e
1a: 21 c0 rjmp .+66 ; 0x5e
1c: 20 c0 rjmp .+64 ; 0x5e
1e: 1f c0 rjmp .+62 ; 0x5e
20: 1e c0 rjmp .+60 ; 0x5e
22: 1d c0 rjmp .+58 ; 0x5e
24: 1c c0 rjmp .+56 ; 0x5e
26: 1b c0 rjmp .+54 ; 0x5e
28: 1a c0 rjmp .+52 ; 0x5e

0000002a <__ctors_end>:
2a: 11 24 eor r1, r1
2c: 1f be out 0x3f, r1 ; 63
2e: cf e5 ldi r28, 0x5F ; 95
30: d2 e0 ldi r29, 0x02 ; 2
32: de bf out 0x3e, r29 ; 62
34: cd bf out 0x3d, r28 ; 61

00000036 <__do_copy_data>:
36: 10 e0 ldi r17, 0x00 ; 0
38: a0 e6 ldi r26, 0x60 ; 96
3a: b0 e0 ldi r27, 0x00 ; 0
3c: ec ee ldi r30, 0xEC ; 236
3e: f0 e0 ldi r31, 0x00 ; 0
40: 02 c0 rjmp .+4 ; 0x46

00000042 <.do_copy_data_loop>:
42: 05 90 lpm r0, Z+
44: 0d 92 st X+, r0

00000046 <.do_copy_data_start>:
46: a2 37 cpi r26, 0x72 ; 114
48: b1 07 cpc r27, r17
4a: d9 f7 brne .-10 ; 0x42

0000004c <__do_clear_bss>:
4c: 10 e0 ldi r17, 0x00 ; 0
4e: a2 e7 ldi r26, 0x72 ; 114
50: b0 e0 ldi r27, 0x00 ; 0
52: 01 c0 rjmp .+2 ; 0x56

00000054 <.do_clear_bss_loop>:
54: 1d 92 st X+, r1

00000056 <.do_clear_bss_start>:
56: a3 37 cpi r26, 0x73 ; 115
58: b1 07 cpc r27, r17
5a: e1 f7 brne .-8 ; 0x54
5c: 2f c0 rjmp .+94 ; 0xbc

0000005e <__bad_interrupt>:
5e: d0 cf rjmp .-96 ; 0x0

00000060 <USART_init>:
volatile static uint8_t data;

void USART_init(void){

UBRRH = 0;
60: 10 bc out 0x20, r1 ; 32
UBRRL = (uint8_t) USART_BAUD_SELECT;
62: 83 e0 ldi r24, 0x03 ; 3
64: 89 b9 out 0x09, r24 ; 9

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
66: 88 e9 ldi r24, 0x98 ; 152
68: 8a b9 out 0x0a, r24 ; 10

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
6a: 86 e8 ldi r24, 0x86 ; 134
6c: 80 bd out 0x20, r24 ; 32

data = UDR;
6e: 8c b1 in r24, 0x0c ; 12
70: 80 93 72 00 sts 0x0072, r24
74: 08 95 ret

00000076 <USART_transmit>:

}

void USART_transmit(uint8_t c){
while(!(UCSRA & (1<<UDRE)));
76: 5d 9b sbis 0x0b, 5 ; 11
78: fe cf rjmp .-4 ; 0x76
UDR = c;
7a: 8c b9 out 0x0c, r24 ; 12
7c: 08 95 ret

0000007e <USART_transmit_string>:
}

void USART_transmit_string(uint8_t *string){
7e: cf 93 push r28
80: df 93 push r29
82: ec 01 movw r28, r24
while(!(UCSRA & (1<<UDRE)));
84: 5d 9b sbis 0x0b, 5 ; 11
86: fe cf rjmp .-4 ; 0x84
while( *string){ USART_transmit (*string++); }
88: 88 81 ld r24, Y
8a: 88 23 and r24, r24
8c: 29 f0 breq .+10 ; 0x98
8e: 89 91 ld r24, Y+
90: f2 df rcall .-28 ; 0x76
92: 88 81 ld r24, Y
94: 88 23 and r24, r24
96: d9 f7 brne .-10 ; 0x8e
98: df 91 pop r29
9a: cf 91 pop r28
9c: 08 95 ret

0000009e <SIG_USART_RECV>:
}




SIGNAL( SIG_USART_RECV )
{
9e: 1f 92 push r1
a0: 0f 92 push r0
a2: 0f b6 in r0, 0x3f ; 63
a4: 0f 92 push r0
a6: 11 24 eor r1, r1
a8: 8f 93 push r24

data = UDR;
aa: 8c b1 in r24, 0x0c ; 12
ac: 80 93 72 00 sts 0x0072, r24
b0: 8f 91 pop r24
b2: 0f 90 pop r0
b4: 0f be out 0x3f, r0 ; 63
b6: 0f 90 pop r0
b8: 1f 90 pop r1
ba: 18 95 reti

000000bc <main>:

}


int main (void)
{
bc: cf e5 ldi r28, 0x5F ; 95
be: d2 e0 ldi r29, 0x02 ; 2
c0: de bf out 0x3e, r29 ; 62
c2: cd bf out 0x3d, r28 ; 61
// D A T E N R I C H T U N G :
//===============================================

// PORTA Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRA = 0b11111111; //
c4: 8f ef ldi r24, 0xFF ; 255
c6: 8a bb out 0x1a, r24 ; 26
PORTA = 0b00000000; //
c8: 1b ba out 0x1b, r1 ; 27

// PORTB Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRB = 0b00000000; //
ca: 17 ba out 0x17, r1 ; 23
PORTB = 0b00000000; //
cc: 18 ba out 0x18, r1 ; 24

// PORTC Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRC = 0b00000000; //
ce: 14 ba out 0x14, r1 ; 20
PORTC = 0b11111111; //
d0: 85 bb out 0x15, r24 ; 21

// PORTD Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRD = 0b11111111; //
d2: 81 bb out 0x11, r24 ; 17
PORTD = 0b00000000; //
d4: 12 ba out 0x12, r1 ; 18




USART_init();
d6: c4 df rcall .-120 ; 0x60
USART_transmit_string("USART INIT - OK ");
d8: 80 e6 ldi r24, 0x60 ; 96
da: 90 e0 ldi r25, 0x00 ; 0
dc: d0 df rcall .-96 ; 0x7e

sei();
de: 78 94 sei

while (1) {

PORTA = UCSRA;
e0: 8b b1 in r24, 0x0b ; 11
e2: 8b bb out 0x1b, r24 ; 27
PORTD = data;
e4: 80 91 72 00 lds r24, 0x0072
e8: 82 bb out 0x12, r24 ; 18
ea: fa cf rjmp .-12 ; 0xe0

PicNick
05.09.2005, 11:51
Na ja, "USART-INIT" kommt ja offenbar richtig raus.

Wie geht's denn rechts mit RTS und CTS weiter ?

Kaiser-F
05.09.2005, 11:54
RTS und CTS können an PD2 und PD3 gejunpert werden.... andernfalls wird CTS HIGH gehalten (10K)


SCHONWIEDER EDIT: Ich benutze übrigens HTerm als Terminalprogramm

PicNick
05.09.2005, 11:58
Willst du nicht kurz mal das Echo anpassen und laufen lassen ?
Wenn das funzt, brauchen wir uns um die Hardware und Kabeln keine Gedanken mehr zu machen

https://www.roboternetz.de/wiki/pmwiki.php?n=Main.BasComVergleich2

Kaiser-F
05.09.2005, 12:16
Mach ich gerne..

Hatte ich vergessen zu erwähnen dass der MC die Daten empfängt?

Wenn ja, SORRY.

Hier der neue Code,




#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define F_CPU 7372800
#define USART_BAUD_RATE 115200
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)

volatile static uint8_t data;

void USART_init(void){

UBRRH = 0;
UBRRL = (uint8_t) USART_BAUD_SELECT;

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

data = UDR;

}

void USART_transmit(uint8_t c){
while(!(UCSRA & (1<<UDRE)));
UDR = c;
}

void USART_transmit_string(uint8_t *string){
while(!(UCSRA & (1<<UDRE)));
while( *string){ USART_transmit (*string++); }
}




SIGNAL( SIG_USART_RECV )
{

data = UDR;

}


int main (void)
{
// D A T E N R I C H T U N G :
//===============================================

// PORTA Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRA = 0b11111111; //
PORTA = 0b00000000; //

// PORTB Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRB = 0b00000000; //
PORTB = 0b00000000; //

// PORTC Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRC = 0b00000000; //
PORTC = 0b11111111; //

// PORTD Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRD = 0b11111111; //
PORTD = 0b00000000; //




USART_init();
USART_transmit_string("USART INIT - OK ");

sei();

uint8_t data_alt;

while (1) {

PORTA = UCSRA;
PORTD = data;


if( data != data_alt ){

USART_transmit(data);

data_alt = data;

}



}
}

Kaiser-F
05.09.2005, 12:17
Mach ich gerne..

Hatte ich vergessen zu erwähnen dass der MC die Daten empfängt?

Wenn ja, SORRY.

Hier der neue Code,




#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define F_CPU 7372800
#define USART_BAUD_RATE 115200
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)

volatile static uint8_t data;

void USART_init(void){

UBRRH = 0;
UBRRL = (uint8_t) USART_BAUD_SELECT;

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

data = UDR;

}

void USART_transmit(uint8_t c){
while(!(UCSRA & (1<<UDRE)));
UDR = c;
}

void USART_transmit_string(uint8_t *string){
while(!(UCSRA & (1<<UDRE)));
while( *string){ USART_transmit (*string++); }
}




SIGNAL( SIG_USART_RECV )
{

data = UDR;

}


int main (void)
{
// D A T E N R I C H T U N G :
//===============================================

// PORTA Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRA = 0b11111111; //
PORTA = 0b00000000; //

// PORTB Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRB = 0b00000000; //
PORTB = 0b00000000; //

// PORTC Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRC = 0b00000000; //
PORTC = 0b11111111; //

// PORTD Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRD = 0b11111111; //
PORTD = 0b00000000; //




USART_init();
USART_transmit_string("USART INIT - OK ");

sei();

uint8_t data_alt;

while (1) {

PORTA = UCSRA;
PORTD = data;


if( data != data_alt ){

USART_transmit(data);

data_alt = data;

}



}
}

PicNick
05.09.2005, 12:34
Ist der Watchdog deaktiviert ? Ich sag dir ehrlich, mir fällt nicht mehr viel ein.

Kaiser-F
05.09.2005, 12:43
Den Watchdog hab ich nochnie hergenommen....

was kann das blos sein?....

PicNick
05.09.2005, 12:45
Den Watchdog hab ich nochnie hergenommen..
Jaja, aber im Programm wird er nicht deaktiviert, vielleicht aber mit den Fuses ?

SprinterSB
05.09.2005, 12:48
Wozu ist denn das data_alt? Das verwendest du uninitialisiert.
Versuch mal nen poll-Betrien also Receive ohne Interrupt zu nutzen.
Ansonsten fällt mir nur ein, daß es eine Silicon-Bug sein könnte. Evtl sagt ds Datenblatt oder die Errata zu deinem AVR was dazu, aber an so war denkt man natürlich nicht gerne...

Kaiser-F
05.09.2005, 12:53
Der Watchdog ist das WDT-BIT,

Da war KEIN Häckchen drinnen, also unprogrammed.

Wenn ich diese Bit setze, dann tut er andauernd reseten, anscheinend weil der Watchdog dann nochnicht richtig eingestellt ist....

Ich werd noch verrückt.... das ist bestimmt wieder so ne Kleinigkeit mir großen Folgen ](*,)

Ich muss mich bei euch recht herzlich für eure große Geduld bedanken!
Ist ehrlich ein feiner Zug von euch!

PicNick
05.09.2005, 12:54
@SprinterSB
Ich seh da grad im Datasheet was von "safety level". Muß mir erst zusammenklamüsern, was es damit auf sich hat

PicNick
05.09.2005, 12:56
... das ist bestimmt wieder so ne Kleinigkeit

Das ist sicher: Wenn wir's dann wissen, werden wir uns alle mit der Faust auf's Hirn klatschen und mit Asche bestreuen.

Kaiser-F
05.09.2005, 12:58
Mal was anderes.....

Wenn ein RESET gemacht wird, dann dürfte er doch eigentlich den zuvor gesendeten Wert, welcher ja im SRAM gespeichert ist, nicht mehr aufrufen können... Oder?

Das tut er aber, er sendet mir den wert ja zurück.

Also führt er kein Reset durch, sondern startet die MAIN-Funktion von anfang an wieder. Ist das richtig?


Wozu ist denn das data_alt? Das verwendest du uninitialisiert.
Versuch mal nen poll-Betrien also Receive ohne Interrupt zu nutzen.
Ansonsten fällt mir nur ein, daß es eine Silicon-Bug sein könnte. Evtl sagt ds Datenblatt oder die Errata zu deinem AVR was dazu, aber an so war denkt man natürlich nicht gerne...

Sorry Sprinter, diese Antwort hab ich jetzt völlig übersehen...

das mit data_alt hätte ich anders machen sollen... mir ist auf die schnelle nur das gekommen. Das er halt nicht periodisch sendet....
Hätte ich mit der "Flag-methode" machen sollen ;-)

Den interrupt zu benutzen wäre mir schon lieber, da ich Zeichenketten empfange... nicht dass ich da mal ein Zeichen verpasse... das ist dann nicht so toll....

SprinterSB
05.09.2005, 13:00
Welchen Wert im SRAM?

PicNick
05.09.2005, 13:01
Nochmal genau die Symptomatik:
1 Er bringt "..INIT ok"
2 dann wartet er
3 und wenn du was schickst,
reagieren die LED ?
4 kommt wieder "..INIT ok"

Kaiser-F
05.09.2005, 13:07
Also:
Ich schalte das Teil ein (bzw. er ist mit dem schreiben fertig)

1. Das Programm startet.
2. Am PC empfange ich " USART Init - OK "

Dann sende ich zB.: A

1. Am PC empfange ich "USART Init - OK A"



die LED für den Empfang leuchtet warscheinlich so kurz auf dass man es nicht sieht. ich zu mal die interrupt routine ausklinken, um zu sehen was aufleuchtet... moment

Kaiser-F
05.09.2005, 13:11
Ist ja interessant.

Also der Code der nun drauf ist:



#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

#define F_CPU 7372800
#define USART_BAUD_RATE 115200
#define USART_BAUD_SELECT (F_CPU/(USART_BAUD_RATE*16L)-1)

volatile static uint8_t data;

void USART_init(void){

UBRRH = 0;
UBRRL = (uint8_t) USART_BAUD_SELECT;

/* Aktivieren des Empfängers, des Senders und des "Daten empfangen"-Interrupts */
UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

/* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

data = UDR;

}

void USART_transmit(uint8_t c){
while(!(UCSRA & (1<<UDRE)));
UDR = c;
}

void USART_transmit_string(uint8_t *string){
while(!(UCSRA & (1<<UDRE)));
while( *string){ USART_transmit (*string++); }
}



/*
SIGNAL( SIG_USART_RECV )
{

data = UDR;

}
*/

int main (void)
{
// D A T E N R I C H T U N G :
//===============================================

// PORTA Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRA = 0b11111111; //
PORTA = 0b00000000; //

// PORTB Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRB = 0b00000000; //
PORTB = 0b00000000; //

// PORTC Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRC = 0b00000000; //
PORTC = 0b11111111; //

// PORTD Pin: 76543210 ( 0 = Eingang/Pullup aus, 1= Ausgang/Pullup ein )
DDRD = 0b11111111; //
PORTD = 0b00000000; //




USART_init();
USART_transmit_string("USART INIT - OK ");

sei();

uint8_t data_alt;

while (1) {

PORTA = UCSRA;
PORTD = data;

/*
if( data != data_alt ){

USART_transmit(data);

data_alt = data;

}
*/


}
}

Nun...

1. ich schalte ein
2. PC empfang "USART Init - OK"
3. Ich sende
4. PC empfang"USART Init - OK"

Wenn ich meine Gedanken mal preisgeben darf: "BAHNHOF"!

PicNick
05.09.2005, 13:11
Moment:
Mach mal line feed in den ok-string
"USART INIT - OK\n\r"
dadurch fängt er dann eine neue Zeile an.
in dieser neuen Zeile sollte dann nurmehr das "A" stehen oder sonstwas
aber nicht nochmal "blabla OK"

SprinterSB
05.09.2005, 13:16
Nimm mal das sei() raus, dann müsste es immer noch gehen.

Kaiser-F
05.09.2005, 13:24
Also OHNE sei():

Da Leuchtet dann was neues auf!

Und zwar in UCSRA BIT7: RXC = USART Receive Complete


das mit dem Zeilenumbruch... HTERM erkennt keinen ;-(

SprinterSB
05.09.2005, 13:29
und der Start-String kommt immer noch 2x?
Den Zeilenumbruch musst du auch senden (mit '\n') und HTERM anpassen.

PicNick
05.09.2005, 13:31
Das war vorher sicher auch schon da, aber das Lesen von UDR löscht das.
Inzwischen liest es aber keiner mehr, also bleibt es stehen.

HTERM ? kein Zeilenumbruch ? scheint mir ein merkwürdiges Programm.

Kaiser-F
05.09.2005, 13:32
Also wenn sei(); weggelassen wird, dann sind ja interrupts deaktiviert.

Dann kommt der Start-String nur einmal. auch wenn ich sende, da leuchtet dann "USART RECEIVE COMPLETE" auf.


Also im Datenblatt steht zu den Interrupts nicht so der HIT drinn...
keine Hinweise darauf oder so... nur generelle sachen. aber das kanns doch nicht sein !?!?

WO IST DER WURM? ](*,)

SprinterSB
05.09.2005, 13:39
Das kann dann doch nur bedeuten, daß ein anderer Interrupt ausgelöst wird... Vielleicht der SIG_UART_UCDRE bze SIG_UART_DATA?
Prog mal den, wie er genau heisst siehst du im header, ich vermute mal SIG_UART_DATA.

PicNick
05.09.2005, 13:41
Ja, aber RXEN is noch da, und deshalb received er.

SprinterSB
05.09.2005, 13:49
Ist ja auch ok. Aber wenn er nen Restart macht, dann doch nur, weil irgend ein Interrupt nicht bedient wird. Und das muss doch ein SIG_UART_xxx sein.

Dino Dieter
05.09.2005, 13:51
Hallo

Die Int Recive Routine heißt


SIGNAL(SIG_UART_RECV)

und nicht


SIGNAL( SIG_USART_RECV )

Von daher dein Neustart

MFG
Dieter

Kaiser-F
05.09.2005, 13:52
Das hab ich in der iom8535.h gefunden:


/* Interrupt vectors */

#define SIG_INTERRUPT0 _VECTOR(1)
#define SIG_INTERRUPT1 _VECTOR(2)
#define SIG_OUTPUT_COMPARE2 _VECTOR(3)
#define SIG_OVERFLOW2 _VECTOR(4)
#define SIG_INPUT_CAPTURE1 _VECTOR(5)
#define SIG_OUTPUT_COMPARE1A _VECTOR(6)
#define SIG_OUTPUT_COMPARE1B _VECTOR(7)
#define SIG_OVERFLOW1 _VECTOR(8)
#define SIG_OVERFLOW0 _VECTOR(9)
#define SIG_SPI _VECTOR(10)
#define SIG_UART_RECV _VECTOR(11)
#define SIG_UART_DATA _VECTOR(12)
#define SIG_UART_TRANS _VECTOR(13)
#define SIG_ADC _VECTOR(14)
#define SIG_EEPROM_READY _VECTOR(15)
#define SIG_COMPARATOR _VECTOR(16)
#define SIG_2WIRE_SERIAL _VECTOR(17)
#define SIG_INTERRUPT2 _VECTOR(18)
#define SIG_OUTPUT_COMPARE0 _VECTOR(19)
#define SIG_SPM_READY _VECTOR(20)

#define _VECTORS_SIZE 42

/*
The Register Bit names are represented by their bit number (0-7).
*/

/* General Interrupt Control Register */
#define INT1 7
#define INT0 6
#define INT2 5
#define IVSEL 1
#define IVCE 0

/* General Interrupt Flag Register */
#define INTF1 7
#define INTF0 6
#define INTF2 5

/* Timer/Counter Interrupt MaSK register */
#define OCIE2 7
#define TOIE2 6
#define TICIE1 5
#define OCIE1A 4
#define OCIE1B 3
#define TOIE1 2
#define OCIE0 1
#define TOIE0 0

/* Timer/Counter Interrupt Flag register */
#define OCF2 7
#define TOV2 6
#define ICF1 5
#define OCF1A 4
#define OCF1B 3
#define TOV1 2
#define OCF0 1
#define TOV0 0



#define SIG_UART_RECV _VECTOR(11)
#define SIG_UART_DATA _VECTOR(12)
#define SIG_UART_TRANS _VECTOR(13)

Im Datenblatt:

Addresslable:

0B = 11 ; USART_RXC ( USART RX COMPLETE Handler )
0C = 12 ; USART_UDRE ( UDR Empty Handler )
0D = 13 ; USART_TXC ( USART TX COMPLETE Handler )

Kaiser-F
05.09.2005, 13:55
... das ist bestimmt wieder so ne Kleinigkeit

Das ist sicher: Wenn wir's dann wissen, werden wir uns alle mit der Faust auf's Hirn klatschen und mit Asche bestreuen.

Was glaubst was ich jetzt gemacht habe?

PicNick
05.09.2005, 14:03
Nun. Dann sollte der Fehler aber verschwinden, wenn ALLE Interrupts belegt wären. Das könnt er ja versuchen (mit cut & paste & edit aus der h-file, damit keiner vergessen wird)
Schlechter kann's ja nicht werden

Kaiser-F
05.09.2005, 14:21
Bin ich erleichtert..

Ich danke euch vielmals für eure Hilfe...

Jetzt muss ich ersmal relaxen :-)


Vielen Dank!

SprinterSB
05.09.2005, 14:33
*ARGL*
*Tischkante-beiss*

PicNick
05.09.2005, 14:38
Hat einer der Kollegen etwas Asche für mich übrig ?
:oops:

Kaiser-F
12.09.2005, 16:54
Hallo Leute.

Ich habe wieder mal ein für mich unerklärliches Problem....

Und schonwieder mit dem UART!


Ich habe nun meine Steuerung mit dem Mega8535 beendet und starte mit der Einheit mit dem Mega128.

Wie man das so macht will man zwischenwerte per UART ausgeben.

Um auf dem Punkt zu kommen:

Da kommt nicht so ganz das Richtige an:
https://www.roboternetz.de/phpBB2/download.php?id=4142

Ankommen sollte:



OK
CNF1:
HEXWERT
CNF2:
HEXWERT
CNF3:
HEXWERT

1
2
3



hier mein init:



void UART_init(void){
UBRR0L = 3;
UCSR0B = (1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);
UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}

void UART_transmit(uint8_t c){
while(!(UCSR0A & (1<<UDRE0)));
UDR0 = c;
}

void UART_transmit_string(uint8_t *string){
while(!(UCSR0A & (1<<UDRE0)));
while( *string){ UART_transmit (*string++); }
}


F_CPU ist 7,372800 MHz

UBRR0L = 3 wie im Datenblatt... um Sicher zu gehen....

EDIT:
Es sieht halt nach falscher Bausrate aus, aber 3 stimmt zu dieser Taktfrequenz. Die Fuses Stimmen auch. also versteh ich es nicht.

BAUD = 115200

Könnt Ihr mir helfen???

Kaiser-F
13.09.2005, 13:21
Hallo,

Der Fehler lag am Pegelwandler! :oops:

Ich hab an meinem Mega8535-Testboard einen Pegelwandler drauf, daher habe ich den am Mega128 nicht getestet. Der ging zwar zuvor wunderbar, aber anscheinend war die Platine unter Spannung und es hat sich was gelöst...

Hab den Pegelwandler nämlich in ein D-Sub9 gehäuse engebaut....

naja... zum Verrükt werden so sachen.

Aber ich muss sagen, wenn man garnicht weiterkommt, dann hört man am besten auf, und packt es am nächsten tag wieder an... Ansonsten grämt man sich in ein immer tieferes Loch und sucht an der Falschen Stelle.