Forum: Mikrocontroller und Digitale Elektronik BTM und Atmega8 UART-Probleme


von P. F. (pfuhsy)


Angehängte Dateien:

Lesenswert?

Jungs helft mir bitte mal, ich bekomme das Ding einfach nicht zum 
laufen.

Ich hab die Schaltung wie mit Bild verschaltet, die Software des µC 
sieht so aus:
1
#define F_CPU 3686400      //Taktfrquenz
2
#define BAUD 9600        //einstellte Baudrate
3
//-----------------------------
4
#include <ctype.h>
5
#include <avr\io.h>
6
#include <avr\delay.h>
7
#include <avr/interrupt.h>
8
//-----------------------------
9
char _buffer[6];        //für die empfangenen Zeichen
10
int _i = 0;
11
bool Befehl = false;
12
//----------------------------------------------------------------------
13
void initPorts();
14
void initUART();
15
void Senden(char buffer[]);
16
void putChar(char data);
17
char getChar();  
18
//----------------------------------------------------------------------
19
void initPorts() 
20
{
21
  //Ausgänge PORT B deklarien
22
  DDRB = (1<< PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)|(1<<PB6); 
23
}
24
//----------------------------------------------------------------------
25
void initUART() 
26
{
27
  UBRRL = (F_CPU / BAUD - 16) / 16;    //Baudberchnnung
28
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  //Transmitter/Receiver zulassen
29
  sei();                  // Interrupts zulassen
30
}
31
//----------------------------------------------------------------------
32
void putChar(char data)            //Zeichen senden
33
{
34
  while (!(UCSRA&32));          //warte bis UDR leer ist
35
  UDR = data;                //senden
36
}
37
//----------------------------------------------------------------------
38
char getChar()                //Zeichen empfangen
39
{
40
  char data=0;
41
  while (!(UCSRA&128));           //warte bis RX-complete RXC UCSRA
42
  data=UDR;                 //empfangen
43
44
  data = toupper(data);
45
  putChar(data); 
46
47
  return data;
48
}
49
//----------------------------------------------------------------------
50
void Senden(char buffer[])           //ganze Strings senden
51
{
52
  for (int i=0 ; buffer[i] !=0 ; i++)
53
    putChar(buffer[i]);
54
}
55
//----------------------------------------------------------------------
56
ISR(USART_RXC_vect)             //UART-Receive Interrupt-Routine
57
{
58
  getChar();                //Zeichen empfangen
59
}
60
//----------------------------------------------------------------------
61
//----------------------------------------------------------------------
62
main()
63
{
64
  initPorts();
65
  initUART();
66
67
  do
68
  {
69
  }
70
  while (true);
71
}

Sie macht nichts anderes als ein empfangenes kleines Zeichen in ein 
großes umzuwandlen und zurück zu schicken. Spannung am Board 
eingeschaltet (grüne LED) und Board auf Datenmodus gestellt (2 grüne 
LEDs am USB-Modul).

Nun habe ich folgendes getestet:
1. Ich sende über die USB-Schnittstelle vom AVR-Board ein kleines 
Zeichen und bekomme das große Zeichen zurück. Gut.

2. Ich verbinde das BTM über Bluetooth mit dem Hyperterminal. Jetzt 
sende ich wieder (Punkt 1) über die USB-Schnittstelle vom AVR-Board ein 
kleines Zeichen und bekomme das große Zeichen zurück. Dieses Zeichen 
sehe ich jetzt noch zusätzlich am Hyperterminal des BTMs. Auch Gut.

3. Nun sende ich über den Hyperterminal des BTMs (über Bluetooth) kleine 
Zeichen und erwarte nun große Zeichen zurück. Negativ, es passiert rein 
gar nichts !!! Die Daten-Transfer-LED vom BTM blinkt beim tippen aber 
fröhlich, also sendet er tatsächlich was.

Jetzt hab ich die Transistorschaltung 100 mal überprüft und keinen 
Fehler gefunden. Gut, ich verwende anstatt des BC547B, BC546B, aber 
damit muss es auch gehen.

Jetzt dachte ich, gut könnte der Tx vom BTM vielleicht ne macke haben. 
Alles klar, Schaltung auseinander gefrickelt, MAX-Modul dazwischen und 
an den PC. AT-Befehl "ati1" eingegeben und bekomme sämtliche 
Einstellungen des Modul als Antwort. D.h. der Tx vom BTM ist garantiert 
nicht defekt.

Warum reagiert der µC nicht was die gesendeten Zeichen vom BTM ???
Ich komme einfach nicht mehr weiter, bitte um Hilfe.

von P. F. (pfuhsy)


Angehängte Dateien:

Lesenswert?

Sorry, das ist der richtige Schaltplan.

von Michael A (Gast)


Lesenswert?

Hast du den Schaltplan auch wenigstens im Postkartenformat?
Briefmarke ist übelst zu lesen ;-)

von P. F. (pfuhsy)


Lesenswert?

Hallo,

also wenn Du das Bild einklickst hast Du dann unten rechts die 
Möglichkeit es zu vergößern (mit Maus drüber gehen).

Gruss

von Michael A (Gast)


Lesenswert?

Peter F. schrieb:
> also wenn Du das Bild einklickst hast Du dann unten rechts die
> Möglichkeit es zu vergößern (mit Maus drüber gehen).

Das Bezog sich auf den ersten Schaltplan, der war echt so klein.

Bei der seriellen Schnittstelle hast du Empfänger mit Empfänger und 
Sender mit Sender verbunden, wenn dein Bild stimmt.

von P. F. (pfuhsy)


Angehängte Dateien:

Lesenswert?

Vergiss die 1.Zeichnung.

Ach Mensch, jetzt aber. Ich hab nochmal nachgeguckt, in der Zeichnung 
ist es verdreht. Also nochmal die richtige Zeichnung.

von Hugi (Gast)


Lesenswert?

Servus,

was für ein Uart-Modus verwendest Du denn?
Sehe da nirgends die Init dafrür.
Ich glaube Du brauchst für das Modul 8N1.

Und warum nimmst Du den Interrupt des Uart wenn Du später sowieso wieder 
die Funktion getChar() aufrufst?
Wieso nicht direkt im Interrupt einfach das Zeichen abholen?
Also:
1
ISR(USART_RXC_vect)
2
 {
3
 putChar(toupper(UDR));
4
 }

Schau mal hier:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART#Interruptbetrieb

Da haste dann auch gleich ne Vorlage für ganze Strings zu empfangen.

Wenn das nichts hilft, hast Du ein Debugger?
Dann mach mal nen Breakpoint in die Empfangsroutine und sende ein 
Zeichen über Bluetooth.
Scheinbar liegts ja an Deiner Empfangsroutine.

Grüße

von P. F. (pfuhsy)


Lesenswert?

Hugi schrieb:
> Und warum nimmst Du den Interrupt des Uart wenn Du später sowieso wieder
> die Funktion getChar() aufrufst?
> Wieso nicht direkt im Interrupt einfach das Zeichen abholen?

OK, hab ich ausprobiert, ändert aber nichts an den Problem.

Hugi schrieb:
> Wenn das nichts hilft, hast Du ein Debugger?

Nein, hab ich leider. Ich benutze das myAVRBoard MK2 mit USB-Modul. Auf 
der Homepage priesen die an, dass man en "pseudo debug" mit der 
seriellen Schnittstelle durchführen kann. Jedoch ist da genau mein 
Problem. Gibt es vielleicht eine andere Möglichekit ???

Hugi schrieb:
> Scheinbar liegts ja an Deiner Empfangsroutine.

Wieso denn ? Die Empfangroutine für die Eingabe über das USB-Modul ist 
die selbe wie die als würde ich die Daten über Bluetooth schicken.

Nach langem ausprobieren bin ich der Ansicht, dass der µC die Daten vom 
BTM gar nicht erst empfängt.

Hast jemand vielleicht die selbe Hardware zuhause und könnte es 
ausprobieren ???


Gruss

von Hugi (Gast)


Lesenswert?

Wie gesagt, mach mal ne richtige Init vom UART.
So sieht es ungefähr aus:
1
void uart_init(void)
2
{
3
  UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  // UART RX, TX und RX Interrupt einschalten
4
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
5
 
6
  UBRRH = UBRR_VAL >> 8;
7
  UBRRL = UBRR_VAL & 0xFF;
8
}

Und in den Defaults des BTM heißt es:
1
The factory settings of UART are as follows: 
2
* Baud rate: 19200 bps 
3
* ...
4
* ...
Du hast aber 9600 Baud eingestellt!
Hast Du das auch beim BTM eingestellt?

Wenn alles nichts hilft, schick mal ein "ATZ0" dann sollte es auf 
Default zurückgesetzt werden. (Nur falls Du aus Versehen was verstellt 
haben solltest).

Grüße

von P. F. (pfuhsy)


Lesenswert?

OK, Baudrate ist jetzt überall auf 19200 umgestellt. Die 
Uart-Initialisierung sieht jetzt so aus:
1
#define BAUD 19200        //einstellte Baudrate
2
3
void initUART() 
4
{
5
 UBRRL = (F_CPU / BAUD - 16) / 16;   //Baudberchnnung
6
 UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE); //Transmitter/Receiver zulassen
7
 UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
8
9
 sei(); // Interrupts zulassen
10
}

Ist jedoch keinerlei Veränderung, Problem besteht !!!

Wofür ist den
1
  UBRRH = UBRR_VAL >> 8;
2
  UBRRL = UBRR_VAL & 0xFF;

Bei UBRR_VAL meldet der Controller mir einen Fehler "error: 'UBRR_VAL' 
was not declared in this scope". Ist die Baudberechnung nicht dafür 
gedacht ?

Ich habs auch mal mit
1
UBRRL = 11;
versucht.

Kann doch nicht sein, das es dafür keine Lösung gibt.

von ... (Gast)


Lesenswert?

Peter F. schrieb:
> Bei UBRR_VAL meldet der Controller mir einen Fehler "error: 'UBRR_VAL'
> was not declared in this scope". Ist die Baudberechnung nicht dafür
> gedacht ?
Das Makro mußt Du schon selbst definieren.
1
#ifndef F_CPU
2
#error "F_CPU not defined!"
3
#endif
4
 
5
#define BAUD 19200UL      // Baudrate
6
 
7
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
8
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
9
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
10
 
11
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
12
  #error "Baudrate error > 1%"
13
#endif
und dann
1
UBRR = UBRR_VAL;
bzw.
1
UBRRH = UBRR_VAL >> 8;
2
UBRRL = UBRR_VAL & 0xFF;
siehe
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART

von P. F. (pfuhsy)


Lesenswert?

Oh man, ich hab jetzt alle Tipps eingepflegt, jedoch ohne erfolg. Das 
Problem ist immernoch das selbe. Die Software sieht jetzt so aus:
1
#define F_CPU 3686400      //Taktfrquenz
2
//#define BAUD 19200        //einstellte Baudrate
3
//------------------------
4
#ifndef F_CPU
5
#error "F_CPU not defined!"
6
#endif
7
8
#define BAUD 19200UL      // Baudrate
9
10
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)
11
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))
12
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)
13
14
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
15
#error "Baudrate error > 1%"
16
#endif
17
//-----------------------------
18
#include <ctype.h>
19
#include <avr\io.h>
20
#include <avr\delay.h>
21
#include <avr/interrupt.h>
22
//-----------------------------
23
char _buffer[6];        //für die empfangenen Zeichen
24
int _i = 0;
25
bool Befehl = false;
26
//----------------------------------------------------------------------
27
void initPorts();
28
void initUART();
29
void Senden(char buffer[]);
30
void putChar(char data);
31
char getChar();  
32
//----------------------------------------------------------------------
33
void initPorts() 
34
{
35
  //Ausgänge PORT B deklarien
36
  DDRB = (1<< PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3)|(1<<PB4)|(1<<PB5)|(1<<PB6); 
37
}
38
//----------------------------------------------------------------------
39
void initUART() 
40
{
41
  UBRRH = UBRR_VAL >> 8;
42
  UBRRL = UBRR_VAL & 0xFF;
43
  //UBRRL = (F_CPU / BAUD - 16) / 16;    //Baudberchnnung
44
  UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  //Transmitter/Receiver zulassen
45
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
46
47
  sei();                  // Interrupts zulassen
48
}
49
//----------------------------------------------------------------------
50
void putChar(char data)            //Zeichen senden
51
{
52
  while (!(UCSRA&32));          //warte bis UDR leer ist
53
  UDR = data;                //senden
54
}
55
//----------------------------------------------------------------------
56
char getChar()                //Zeichen empfangen
57
{
58
  char data=0;
59
  while (!(UCSRA&128));           //warte bis RX-complete RXC UCSRA
60
  data=UDR;                 //empfangen
61
62
  data = toupper(data);
63
  putChar(data); 
64
65
  return data;
66
}
67
//----------------------------------------------------------------------
68
void Senden(char buffer[])           //ganze Strings senden
69
{
70
  for (int i=0 ; buffer[i] !=0 ; i++)
71
    putChar(buffer[i]);
72
}
73
//----------------------------------------------------------------------
74
ISR(USART_RXC_vect)             //UART-Receive Interrupt-Routine
75
{
76
  putChar(toupper(UDR));
77
  //getChar();                //Zeichen empfangen
78
}
79
//----------------------------------------------------------------------
80
//----------------------------------------------------------------------
81
main()
82
{
83
  initPorts();
84
  initUART();
85
86
  do
87
  {
88
  }
89
  while (true);
90
}

Hat jemand noch eine andere Idee, ich komme nicht weiter ???

von P. F. (pfuhsy)


Lesenswert?

Hat keiner eine weitere Idee ?

von P. F. (pfuhsy)


Lesenswert?

Schade, ich dachte hier könnte mir jemand helfen.

Trotzdem danke.

von P. F. (pfuhsy)


Lesenswert?

Ich hab neue Erkenntnisse. Verbinde ich den Tx vom BTM direkt (ohne 
Transistorverschaltung) mit dem Rx vom µC erkennt er die Zeichen, jedoch 
nur wenn ich den Rx vom BTM abklemme. Hat jemand darauf eine Idee ?

von P. F. (pfuhsy)


Lesenswert?

Falls es noch jemanden interessiert, ich hab den Fehler gerade gefunden. 
Die Masse vom AVR-Board und dem Steckboard mit dem BTM + Pedelwandler 
hat gefehlt.

Meine Güte, was habe ich da Zeit invesstiert und nun sowas...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.