Forum: Compiler & IDEs Brauche Hilfe=)


von Atmega 1. (atmega168)


Lesenswert?

Hallo Leute.
Vorneweg möchte ich sagen, dass ich mich in Sachen Mikrocontroller noch 
nicht so gut auskenne. Allerdings hab ich mich daran gewagt eine 
Roboterhand für mein Maturaprojekt zu bauen.
Nun hab ich mal so alles schön aufgebaut(also die ganze Schaltung zum 
programieren usw) und habe nun folgendes Testprogramm geschrieben:

#include <stdlib.h>
#include <avr/io.h>
#include <string.h>
#include "uart.h"
#include <util/delay.h>
#include <inttypes.h>

#define F_CPU 20000000UL      // Systemtakt in Hz
#define BAUD 9600UL               //Baudrate
#define UBRR ((F_CPU+BAUD*8)/(BAUD*16)-1)    //clever runden


/*void initialUart()
{
  UBRR0H = (unsigned char) (UBRR >>8);        // Baudrate setzen
  UBRR0L = (unsigned char) UBRR;
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
}*/

void uart_Init(void)
{
  /* Set baud rate */
  UBRR0H = (unsigned char)(UBRR>>8);
  UBRR0L = (unsigned char) UBRR;

  /* Enable receiver and transmitter */
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);

  /* Set frame format: 8data, 2stop bit */
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}

int main()
{
  char NextSign;

  uart_Init();
  DDRB|=(1<<DDB1);
  DDRB|=(1<<DDB2);

  while(1)
  {

      NextSign = uart_getc();
    PORTB |= (1<<PB2);
    uart_putc(NextSign);
    _delay_ms(50);
    PORTB &= ~(1<<PB2);

  }
  return 1;
}

Das Progi soll mir einfach den Text den ich über die RS232 Schnittstelle 
schicke über den Mikrocontroller wieder zurückschicken(max232 ist 
zwischen Rs232 und Mikrocontroller). Allerdings empfange ich am Pc nix.
Den Text den ich schicken will schicke ich mit meinen C# Programm:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;

namespace Serialport_test
{
    public partial class Form1 : Form
    {
        SerialPort com;

        public Form1()
        {
            InitializeComponent();
            this.richTextBox2.Enabled = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            com = new SerialPort("com3", 9600, Parity.None, 8, 
StopBits.Two);
            try
            {
                com.Open();
                com.WriteLine(this.richTextBox1.Text);

                Thread lese = new Thread(new ThreadStart(tuewas));
                lese.Start();
                com.Close();
            }
            catch (Exception)
            {
                Console.WriteLine("Comportfehler");
            }
        }

        private static void tuewas()
        {
            try
            {
                SerialPort com = new SerialPort("com3",
                9600, Parity.None, 8, StopBits.Two);

                com.Open();
                Console.WriteLine(com.ReadTo("n"));
                com.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine("Bekomme nix");
            }
        }
    }
}

Könnt ihr mir bitte sagen wieso ich keinen Text empfange bzw. ob ich 
überhaupt was mache mit dem Programm.
Bitte bitte helft mir, es ist wirklich sehr wichtig.


Mfg Atmega 168

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Kennst du den Artikel AVR Checkliste schon?

Bei RS232-Übertragung ist die Verkabelung zwischen µC und PC ein 
essentieller Punkt. Hierzu schreibst du in deiner Frage nichts. Ein 
Schaltplan/Skizze wäre hier hilfreich.

Um ein Problem mit dem selbstgeschriebenen PC-Programm auszuschliessen, 
würde ich die ersten Tests zuerst mit einem bekanntermassen 
funktionierenden Terminalprogramm machen (s. Artikel RS232).

von Atmega 1. (atmega168)


Lesenswert?

Den Artikel hab ich mir schon mal durchgelesen, aber hab nichts 
gefunden. Außerdem funktionnieren Testprogramme (wie zum Beispiel ein 
LED mit dem atmega168 zum blinken zu bringen).

Den Mikrocontroller vom Typ Atmel atmega168 hab ich mit dem Pc so wie 
auf dieser 
Seite(http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART) 
angeschlossen. Ich hab allerdings einen Nullmodemkabel und so musste ich 
Pin3 und 2 am Comport vertauschen.

Außerdem hat mein Mikrocontroller eine stabile 5V 
Gleichspannungsversorgung (7805)und ist an einen Quarz von 20Mhz 
angeschlossen(Fuses hab ich schon entsprechend gesetzt)...

Mein erster Gedanke, dass mein Programmer(selbstgebaut=) ) nicht 
funktioniert war auch falsch. Er lässt sich problemlos programmiern. Wie 
gesagt kleine Programe funktionieren sogar schon.

Nur fehlt noch bei der uart...

Kann es sein, dass mein Quellcode falsch ist?

MfG atmega 168

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Atmega 168 wrote:

> Den Artikel hab ich mir schon mal durchgelesen, aber hab nichts
> gefunden. Außerdem funktionnieren Testprogramme (wie zum Beispiel ein
> LED mit dem atmega168 zum blinken zu bringen).

Das ist gut, denn aus der Blinkrate kann man grob ableiten, ob der 
Taktgeber wie vorgesehen arbeitet. Zwischen 1 Mhz (Werkseinstellung) und 
20 MHz (externer Quarz) sollte man einen Unterschied hinbekommen.

> Den Mikrocontroller vom Typ Atmel atmega168 hab ich mit dem Pc so wie
> auf dieser
> Seite(http://www.mikrocontroller.net/articles/AVR-Tutorial:_UART)
> angeschlossen. Ich hab allerdings einen Nullmodemkabel und so musste ich
> Pin3 und 2 am Comport vertauschen.

µC aus der Fassung raus und an der Fassung die Pins RXD udn TXD brücken. 
Dann sollte beim Senden mit Terminalprogramm auf dem PC der gesendete 
Text als Echo zurückkommen. Damit wäre die RS232-Hardware auf 
grundsätzliche Funktion getestet. Die TXD Leitung auf dem einseitig 
angeschlossenen Kabel kann man mit einem Mutimeter finden. Sie führt iM 
Gegensatz zur RXD Leitung Spannung gegen GND auf dem Kabel.

> Außerdem hat mein Mikrocontroller eine stabile 5V
> Gleichspannungsversorgung (7805)und ist an einen Quarz von 20Mhz
> angeschlossen(Fuses hab ich schon entsprechend gesetzt)...

Schön. ich will dir auch kein schlampiges Arbeiten unterstellen. NUR 
wenn alles per Definition richtig ist, darf auch kein Problem auftreten. 
Tritt ein Problem auf, muss irgendwo ein Bug stecken ;-)

> Nur fehlt noch bei der uart...
> Kann es sein, dass mein Quellcode falsch ist?

Kann sein. Es kann auch sein, dass die Verbindung zwischen µC udn PC 
einen Bug hat. Ich mag/kann in die Diskussion beider Softwares (µC-Teil 
(da fehlt Source) und PC-Teil (C# habe ich keine Ahnung)) nicht 
einsteigen,

von Michael U. (amiga)


Lesenswert?

Hallo,

und wie wäre es mit systematischer Eingrenzung des Fehlers?
z.B. festes Zeichen mit dem µC senden, Terminalprogramm auf dem PC 
öffnen und schauen, ob es richtig ankommt?

Falls nicht -> Fehler in µC Senderoutine suchen und beheben.

Zeichen mit Terminalprogramm schicken und schauen, ob es der µC richtig 
zurückschickt?

Falls nicht -> Fehler in µC Empfangsroutine suchen und beheben.

Test mit Deinem Programm
Falls nicht -> Fehler dort suchen

Evtl. eben Deinen PC mit einem 2. Verbinden, dort Terminalprogramm 
aufmachen und schauen, was Dein Programm sendet.

usw. usw.

PS: als Terminalprogramm nutze ich immernoch gern die alte Version von 
Teraterm. Ist unkompliziert zu handhaben und macht, was es soll. :-)

Gruß aus Berlin
Michael

von Atmega 1. (atmega168)


Lesenswert?

Stefan B. wrote:

> µC aus der Fassung raus und an der Fassung die Pins RXD udn TXD brücken.
> Dann sollte beim Senden mit Terminalprogramm auf dem PC der gesendete
> Text als Echo zurückkommen. Damit wäre die RS232-Hardware auf
> grundsätzliche Funktion getestet. Die TXD Leitung auf dem einseitig
> angeschlossenen Kabel kann man mit einem Mutimeter finden. Sie führt iM
> Gegensatz zur RXD Leitung Spannung gegen GND auf dem Kabel.


Könntest du mir das bitte ein wenig genauer erklären, wie du das da oben 
meinst? Wie meinst du das mit µC aus der Fassungraus?...


MfG
Atmega168

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Ahm, meine Experimentierboards sind alle mit IC-Fassungen aufgebaut und 
in denen steckt eine PDIP-Version des AVRs. Wenn du einen AVR in SMD 
Bauform hast, macht das natürlich keinen Sinn. Bei SMD hättest du eine 
Chance, wenn die TXD/RXD Leitungen über Jumper geführt sind.

Beim meinem Aufbau kann man einfach den µC rausziehen (und so nicht 
elektrisch beschädigen) und an den jetzt freiliegenden Pins der Fassung 
Experimente veranstalten. Z.B. ein Drähtchen von der Pinbuchse für TXD 
zu der Pinbuchse für RXD stecken.

Damit hat man ein sog. Loopbackdevice geschaffen und mit dem kann man 
die ganze Signalkette (Terminalprogramm => PC-Schnittstelle => Kabel => 
Buchse => MAX232 => IC-Fassung => MAX232 => Buchse => Kabel => 
PC-Schnittstelle => Terminalprogramm) auf elektr. Funktion testen.

Nach diesem erfolgreichen Test kann es eigentlich nur noch am Anschluss 
des AVRs (Versorgung, Taktquelle) und dessen Programmierung hängen. Bei 
einem nicht erfolgreichen Loppbacktest sollte man zuerst in der Hardware 
nach Bugs wühlen und danach kann man sich um die AVR Software kümmern, 
falls erforderlich.

von Threadtitel! (Gast)


Lesenswert?

Ist es so schwer, einen sinnvollen Thread-Titel zu wählen?

von Atmega 1. (atmega168)


Lesenswert?

Achso, dann könnte ich wohl auch den Ausgang vom Max232 (R1out) und den 
Eingang vom Max232 (T1In) brücken? Hätte wohl auch den gleichen Effekt 
oder?

MfG
atmega168

von Karl H. (kbuchegg)


Lesenswert?

Ja.
Es geht nur darum, dass alle Signale, die über die RS232 reinkommen ohne 
den Umweg über den µC (der sie verarbeitet) sofort wieder über die 
andere Leitung zurückgeschickt werden. Der PC bedient mit seinem Ausgang 
quasi seinen eigenen Eingang. Nur dass halt die komplette 
elektrische/elektronische Kette Kabel+MAX232 dazwischenhängt.

von Atmega 1. (atmega168)


Lesenswert?

So hab jetzt mal durchgetestet ob vielleicht irgentein Fehler im Max232 
ist, aber alles was ich via Comport gesendet habe ist wieder 
zurückgekommen.
Folglich ist die Hardware und der Aufbau des Max232 richtig.

Also liegt es nur am µC-Programm. Könnte mir nicht bitte einer von euch 
einen Quellcode in C posten, der via Rxd am µC einen String einliest und 
ihn dann via TxD wieder zurück zum Max232 bzw. zum PC sendet?

Ich schreibe meinen String im Terminalprogramm mit

com.Open();
com.WriteLine("String");

und lese ihn mit

com.ReadLine();
com.Close();

in eine Variable ein. Folglich muss der µC solange Zeichen aus dem 
Ringbuffer einlesen bis er auf \n, also neue Zeile (verwendet ja 
WriteLine), stoßt.

Bitte macht mir den Gefallen und postet mir einen Quellcode in C.

MfG
Atmega168

von Klaus (Gast)


Lesenswert?

Ja geil, hast du einen Aussagekräftigen Betreff gewählt...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> So hab jetzt mal durchgetestet ob vielleicht irgentein Fehler
> im Max232 ist, aber alles was ich via Comport gesendet habe
> ist wieder zurückgekommen.
>
> Folglich ist die Hardware und der Aufbau des Max232 richtig.
>
> Also liegt es nur am µC-Programm.

Diese letzte Schlussfolgerung kann ich noch nicht ziehen.

Du schreibst nämlich nicht, wie du durchgetestet hast - mit einem 
Terminalprogramm oder mit dem selbstgeschriebenen PC-Programm. Es kann 
auch ein Problem mit dem selbstgeschriebenen PC-Programm geben.

Z.B. wenn - Spekulation! - dessen Ausgabe gepuffert abläuft und du in 
einem Sendeburst interner Flush) beim '\n' den kleinen 2-Byte Puffer des 
µC so überfährst, dass das letzte Zeichen - das für readline() 
essentielle '\n' - verloren geht.

Abgesehen dacon halte ich das für einen Bug, wenn du auf ein LF warten 
willst:
1
               Console.WriteLine(com.ReadTo("n"));
2
                                             ^

Und in dem PC-Programm oben ist der folgende Block drin:
1
         com.WriteLine(this.richTextBox1.Text);
2
3
         Thread lese = new Thread(new ThreadStart(tuewas));
4
         lese.Start();

Rein aus dem Bauch raus ist das out-of-sequence. Den Lesethread würde 
ich einrichten und starten bevor was an den µC gesendet wird.

In dem Lesethread würde ich auch nicht die Schnittstelle noch mal 
initialisieren und aufmachen.

Rein aus dem Bauch raus, würde ich nämlich annehmen, dass dabei Altdaten 
verworfen werden. Schmeisst das Programm eigentlich zur Laufzeit die 
Exception "Bekomme nix?" - die würde ich erwarten, weil eine bereits 
geöffnete Schnittstelle COM3 nochmal aufgemacht werden soll.

> Bitte macht mir den Gefallen und postet mir einen Quellcode in C.

Hier der Quellcode für das µC-Programm quasi direkt aus dem Datenblatt 
für USART0 und 9600/8/N/2:
1
// MCU = atmega168
2
// F_CPU = 20000000
3
4
#define FOSC 20000000 // Clock Speed
5
#define BAUD 9600
6
#define MYUBRR FOSC/16/BAUD-1
7
8
#include <avr/io.h>
9
10
// 19.7.1 Receiving Frames with 5 to 8 Data Bits
11
unsigned char USART_Receive( void )
12
{
13
  /* Wait for data to be received */
14
  while ( !(UCSR0A & (1<<RXC0)) )
15
    ;
16
  /* Get and return received data from buffer */
17
  return UDR0;
18
}
19
20
21
// 19.6.1 Sending Frames with 5 to 8 Data Bit
22
void USART_Transmit( unsigned char data )
23
{
24
  /* Wait for empty transmit buffer */
25
  while ( !( UCSR0A & (1<<UDRE0)) )
26
    ;
27
  /* Put data into buffer, sends the data */
28
  UDR0 = data;
29
}
30
31
32
// 19.5 USART Initialization
33
void USART_Init( unsigned int ubrr)
34
{
35
  /*Set baud rate */
36
  UBRR0H = (unsigned char)(ubrr>>8);
37
  UBRR0L = (unsigned char)ubrr;
38
39
  Enable receiver and transmitter */
40
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
41
42
  /* Set frame format: 8data, 2stop bit */
43
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
44
}
45
46
47
int main(void)
48
{
49
  unsigned char NextSign;
50
51
  USART_Init(MYUBRR);
52
53
  while(1)
54
  {
55
    NextSign = USART_Receive();
56
    USART_Transmit(NextSign);
57
  }
58
59
  return 0;
60
}

von Atmega 1. (atmega168)


Lesenswert?

Stefan B. wrote:

> Rein aus dem Bauch raus ist das out-of-sequence. Den Lesethread würde
> ich einrichten und starten bevor was an den µC gesendet wird.
>
> In dem Lesethread würde ich auch nicht die Schnittstelle noch mal
> initialisieren und aufmachen.
>
> Rein aus dem Bauch raus, würde ich nämlich annehmen, dass dabei Altdaten
> verworfen werden. Schmeisst das Programm eigentlich zur Laufzeit die
> Exception "Bekomme nix?" - die würde ich erwarten, weil eine bereits
> geöffnete Schnittstelle COM3 nochmal aufgemacht werden soll.


Ich habe mein C#-Programm leicht umgeändert: hab das mit dem Lesethread 
gelassen und auch das Readto("n) ist weg.

Stat dessen steht da jetz sowas:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace Serialport_test
{
    public partial class Form1 : Form
    {
        SerialPort com;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            com = new SerialPort("com3", 9600, Parity.None, 8,
StopBits.Two);

            try
            {
                com.Open();
                com.WriteLine(this.richTextBox1.Text);
                this.richTextBox2.Text=com.ReadLine();
                com.Close();

            }
            catch(Exception e)
            {
                Console.WriteLine("e.getMessage()");
            }
        }
    }
}

Mit diesem Programm habe ich den Max232 durchgetestet.

von Atmega 1. (atmega168)


Lesenswert?

Hab das Problem jetzt gefunden und bekomme jetzt das Signal vom µC auf 
mein Terminalprogramm. Allerdings sende ich mit meinem µC ein Byte mit 
dem Wert 101 und bekomme im Terminalprogramm als Byte den Wert 229. Weis 
jemand von euch warum das so sein könnte?

MfG Atmega168

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Was war das Problem?

101dez = 0b01100101
229dez = 0b11100101
           ^

Hmm. Schuss ins Blaue: Doku auf der PC Seite nachlesen, wie dort das MSB 
Bit7 gehandhabt wird. Initialisierung ist auf beiden Seiten bei der 
Bitzahl gleich?

von Atmega 1. (atmega168)


Lesenswert?

Ja auf beiden Seiten hab ich den 8N1-Modus eingestellt (8 Bit,no Parity, 
1 Stopbit). Danke Stefan, dass du dir die Mühe gemacht hast mit den 
einzelnen Binärcodes der Bytes. Werde das jetzt mal mit den 7. Bit 
durchlesen.

Großen Dank=)

MfG Atmega168

von STK500-Besitzer (Gast)


Lesenswert?

>Ja auf beiden Seiten hab ich den 8N1-Modus eingestellt
>SerialPort("com3", 9600, Parity.None, 8, StopBits.Two
                                          ^^^^^^^^^^^^
Widerspricht sich ein Wenig...

von Atmega 1. (atmega168)


Lesenswert?

Ach ja =),
vergesst alle den Quellcode oben, hab den umgeschrieben.

MfG Atmega 168

von Verweigerer (Gast)


Lesenswert?

www.Beichthaus.de
Da gibts jede Menge Hilfe ..

von Atmega 1. (atmega168)


Lesenswert?

Also hab mir die Handhabung des 7. Bit durchgelesen, bin daraus aber 
nicht schlau geworden.

Wenn ich versuche Daten vom µC an mein C#- Programm zu schicken bekomme 
ich allerdings immer noch fehlerhafte Bytes im C#-Programm.

Schicken mit dem µC 101 (also 01100101)
Bekomme im Terminalprogramm zusätzlich zu 229 (also 11100101) auch noch 
197 (also 11000101)

wird einer von euch daraus schlau?

01100101 = 101
11100101 = 229
11000101 = 197

MfG Atmega 168

von Karl H. (kbuchegg)


Lesenswert?

Atmega 168 wrote:
> Also hab mir die Handhabung des 7. Bit durchgelesen, bin daraus aber
> nicht schlau geworden.
>
> Wenn ich versuche Daten vom µC an mein C#- Programm zu schicken bekomme
> ich allerdings immer noch fehlerhafte Bytes im C#-Programm.
>
> Schicken mit dem µC 101 (also 01100101)
> Bekomme im Terminalprogramm zusätzlich zu 229 (also 11100101) auch noch
> 197 (also 11000101)

Zusätzlich?
Du schickst vom µC also 1 Byte weg und am PC werden 2 empfangen?

Dann stimmt irgendwas mit deiner Baudrate nicht. Sicher, dass dein µC 
wirklich mit 20 Mhz arbeitet? Also nicht nur ein Quarz angeschlossen 
ist, sondern das der auch tatsächlich benutzt wird.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Atmega 168 wrote:

> vergesst alle den Quellcode oben, hab den umgeschrieben.

OK. Vergessen. Wo sind die neuen Quellcodes?

von Atmega 1. (atmega168)


Lesenswert?

1
#define F_CPU 20000000UL // Clock Speed
2
#define BaudRate 9600UL  // Baud-Rate
3
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
9
void uart_init()
10
{
11
    uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16*BaudRate) - 1);
12
 
13
    UBRR0H = (uint8_t) (ubrr>>8);
14
    UBRR0L = (uint8_t) (ubrr);
15
 
16
    // UART Receiver und Transmitter anschalten 
17
    // Data mode 8N1, asynchron 
18
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
19
20
    // Set frame format: 8data, 2stop bit //
21
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
22
23
    // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) 
24
    do
25
    {
26
        UDR0;
27
    }
28
    while (UCSR0A & (1 << RXC0));
29
30
  DDRB|=(1<<DDB1);
31
   DDRB|=(1<<DDB2);
32
}
33
34
static inline int
35
uart_putc (const uint8_t c)
36
{
37
    // Warten, bis UDR bereit ist für einen neuen Wert 
38
    while (!(UCSR0A & (1 << UDRE0)))
39
        ;
40
41
    // UDR Schreiben startet die Übertragung 
42
    UDR0 = c;
43
44
    return 1;
45
}
46
47
static inline uint8_t
48
uart_getc_wait()
49
{
50
    // Warten, bis etwas empfangen wird 
51
    while (!(UCSR0A & (1 << RXC0)))
52
        ;
53
54
    // Das empfangene Zeichen zurückliefern 
55
    return UDR0;
56
}
57
58
59
int main()
60
{
61
  uint8_t empfangen;
62
63
  uart_init();
64
  
65
  while(1)
66
  {
67
    uart_putc(101);
68
    empfangen = uart_getc_wait();
69
70
    if(empfangen == 101)
71
    {
72
      PORTB |= (1<<PB1);
73
      _delay_ms(500);
74
      PORTB &= ~(1<<PB1);
75
      _delay_ms(500);
76
    }
77
    else 
78
    {
79
      PORTB |= (1<<PB2);
80
      _delay_ms(500);
81
      PORTB &= ~(1<<PB2);
82
      _delay_ms(500);
83
    }
84
    
85
  }
86
87
  return 1;
88
}
hier wäre mein derzeitiger Quellcode
hab mich jetzt für die Variante 8N2 entschieden

Mfg Atmega168

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Atmega 168 wrote:

> hier wäre mein derzeitiger Quellcode
> hab mich jetzt für die Variante 8N2 entschieden

Und, gleicher Fehler wie oben mit der 8N1 Variante?

In dem µC-Programm sehe ich keine offensichtlichen Fehler. Wie sieht es 
auf der PC Seite aus, Terminalprogramm oder selbstgeschriebenes C# 
Programm?

Die Fehlerbeschreibung oben ist für den Übertragungsweg µC => PC, 
richtig? Wie ist es mit dem Übertragungsweg PC => µC:

Wenn du dem Atmega168 vom PC aus aus einem Terminalprogramm heraus, das 
auf 9600/8/N/2 eingestellt ist, das Zeichen 101 ('e') schickst, blinkt 
dann die LED an PB1 oder die LED an PB2?

von Atmega 1. (atmega168)


Lesenswert?

Also mein C#-Programm ist selbst geschrieben. Wäre es sinnvoll den 
Quellcode zu posten?
Sobald ich vom Terminal ein 'e' sende leichtet des LED an PB2. Eben 
deswegen kann ich mir nicht erklären was los ist. Sende ich mit dem PC 
101, bekomme ich 117 zurück. oft auch 'E'. Wenn ich hingegen mit dem µC 
an den PC sende empfange ich dort statt 101 229 oder 197.

µC -> Pc

nie 01100101 = 101   (LED an PB2 blinkt)
oft 11100101 = 229   (LED an PB2 blinkt)
oft 11000101 = 197   (LED an PB2 blinkt)


Pc -> µC -> Pc

oft 01100101 = 101 (LED an PB1 blinkt aber nicht!!!!...LED an PB2 
blinkt)
oft 01110101 = 117 (LED an PB2 blinkt)

Kann mir bitte einer helfen, glaub nähmlich ich mache da was mit dn Bit 
nicht richtig oder so.

C# Serialportinitialisierung:
1
 
2
SerialPort com = new SerialPort("com3", 9600, Parity.None, 8, Stopbit.Two);

MfG Atmega 168

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Kontrolle der Taktrate mit primitiven Mitteln: Kommentiere diese beiden 
Zeilen aus

    uart_putc(101);
    empfangen = uart_getc_wait();

und lasse das Board laufen und zähle 3 Min. lang wie oft es blinkt. Es 
sollte genau 180 mal mit höchstens 3 mal mehr oder weniger sein. Bevor 
du die Mühe mit dem Zählen machst, kontrolliere, dass die Source mit 
Optimierung kompiliert ist, damit die _delay_ms() Zeiten stimmen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wird die Baudrate richtig gerundet?

Beim Baudratenrechner sagt, daß ubrr 0x81 (129) enthalten sollte.

http://gjlay.de/helferlein/avr-uart-rechner.html

Evtl. hilft eine Umformulierung von ubrr?
1
    unsigned short ubrr = -.6 + F_CPU/((16L-8*U2X_BIT)*BAUDRATE);

und U2X_BIT je nach deiner U2X-Einstellung.

von Atmega 1. (atmega168)


Lesenswert?

Johann L. wrote:

> Evtl. hilft eine Umformulierung von ubrr?
>
>
1
>     unsigned short ubrr = -.6 + F_CPU/((16L-8*U2X_BIT)*BAUDRATE);
2
>
>
> und U2X_BIT je nach deiner U2X-Einstellung.

Was ist eine U2X-Einstellung?
Warum ist
1
-.6
 in der ubrr-Rundung?

MfG Atmega168

von Atmega 1. (atmega168)


Lesenswert?

Jawol, es funktioniert endlich. Vielen dank an alle die mir geholfen 
habe.

MfG Atmega 168

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Atmega 168 wrote:
> Johann L. wrote:
>
>> Evtl. hilft eine Umformulierung von ubrr?
>>
>>
1
>>     unsigned short ubrr = -.6 + F_CPU/((16L-8*U2X_BIT)*BAUDRATE);
2
>>
>>
>> und U2X_BIT je nach deiner U2X-Einstellung.
>
> Was ist eine U2X-Einstellung?

Der USRT arbeitet doppelt so schnell, nimmt aber weniger samples. Siehe 
U2X-Bit im Handbuch bei der U(S)ART-Config

> Warum ist
1
-.6
 in der ubrr-Rundung?

Oje, hatte ich mir wohl irgendwann mal überlegt.

Und bitte: F_CPU, U2X_BIT und BAUDRATE müssen Compilerzeit-Konstanten 
sein. Ansonsten wird wie bei util/delay.h die float-Wumme ausgepackt.

Wo war denn der Fehler?

von Atmega 1. (atmega168)


Lesenswert?

Die Baudrate stimp aber immernoch nicht so. Sobald ich Strings einles 
und sie vergleichen will stimp dann wieder nichts. Einzelnen 
Char-Zeichen hingegen kann ich vergleichen.

Was kann hier nicht stimmen. Kann mir einer von euch vielleicht einen 
Quellcode posten der Strings mit Hilfe der Uart einliest und diesen 
String dann vergleicht?

MfG Atmega 168

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Ein Fehler in deinem C#-Code? Geht es auf einem Terminal auch nicht, 
oder zeigt er da die Zeichen korrekt an?

Vielleicht ist der Host durch die eher unübliche Konfiguration 8N2 
überfordert? Also mal 8N1 versuchen auf beiden Seiten.

Der Fehler von 0.2% ist an der Obergrenze des maximal empfohlenen 
Fehlers. Also mal 4800 Baud mit U2X=1 versuchen, da ist der Fehler rein 
rechnerisch 0, d.h. die Baudrate ist exakt.

Wackler in Steckkontakten? fliegender Aufbau? RS232-Umschaltbox in der 
Leitung? Unsaubere Spannungsversorgung? Schlecht bemessene 
MAX232-Kondensatoren?

von Karl H. (kbuchegg)


Lesenswert?

Und die Nr 1 an Debugmöglichkeiten bei derartigen
Problemen:

Den empfangenen String (nicht die Einzelzeichen) gleich mal 
zurückschicken damit man am Terminal kontrollieren kann, ob auch alles 
so angekommen ist, wie man sich das vorstellt. Am besten noch ein 
Sonderzeichen vor und hinter die Ausgabe, damit man auch sieht, ob sich 
nicht irgendwo Leerzeichen, Tabulatoren oder Zeilenumbrüche im String 
versteckt haben.

von Atmega 1. (atmega168)


Lesenswert?

Karl heinz Buchegger wrote:
> Und die Nr 1 an Debugmöglichkeiten bei derartigen
> Problemen:
>
> Den empfangenen String (nicht die Einzelzeichen) gleich mal
> zurückschicken damit man am Terminal kontrollieren kann, ob auch alles
> so angekommen ist, wie man sich das vorstellt. Am besten noch ein
> Sonderzeichen vor und hinter die Ausgabe, damit man auch sieht, ob sich
> nicht irgendwo Leerzeichen, Tabulatoren oder Zeilenumbrüche im String
> versteckt haben.

Das ist ja das Problem, sende ich zum Beispiel "ein" an den µC dann 
bekomm ich oft ei oft in oft e?n usw. zurück. einzelnen zeichen 'e' zB 
sende ich fehlerfrei...

für Baudrate hab ich sowas eingegeben:
1
#define U2X_BIT  0
2
unsigned short ubrr = (-5) + F_CPU/((16L-8*U2X_BIT)*BAUDRATE);

Kann mir vielleicht einer einen Quellcode oder so posten?

MfG Atmega168

von Atmega 1. (atmega168)


Lesenswert?

Johann L. wrote:
> Ein Fehler in deinem C#-Code? Geht es auf einem Terminal auch nicht,
> oder zeigt er da die Zeichen korrekt an?
>
> Wackler in Steckkontakten? fliegender Aufbau? RS232-Umschaltbox in der
> Leitung? Unsaubere Spannungsversorgung? Schlecht bemessene
> MAX232-Kondensatoren?

Also Fehler mit Spannung usw hab ich nicht, C#-Progi müsste auch 
einwandfrei sein...soll ich es mal posten?

MfGAtmega 168

von Karl H. (kbuchegg)


Lesenswert?

Atmega 168 wrote:

> Das ist ja das Problem, sende ich zum Beispiel "ein" an den µC dann
> bekomm ich oft ei oft in oft e?n usw. zurück. einzelnen zeichen 'e' zB
> sende ich fehlerfrei...



Zeig noch mal deinen kompletten µC Code.

von Karl H. (kbuchegg)


Lesenswert?

Atmega 168 wrote:

> Also Fehler mit Spannung usw hab ich nicht, C#-Progi müsste auch
> einwandfrei sein...soll ich es mal posten?

Du kämpfst im Moment einen 2-Fronten Krieg.
Du weisst nicht ob dein Problem im µC oder im C# Teil liegt.
Also musst du einen der beiden Teile durch etwas nachweislich 
funktionierendes austauschen.

Den PC-Teil kannst du zb. durch Hyperterminal oder ein anderes 
Terminalprogramm ersetzen. Die meisten dieser Terminalprogramme können 
auch eine Textdatei über die serielle Leitung verschicken. Da kannst du 
jetzt mal dein Kommando reinschreiben und per 'Dateiversenden' mit 
Full-Speed zum µC schicken (wenn du händisch tippst, hast du ja immer 
Pausen zwischen den Tastenanschlägen)

von Atmega 1. (atmega168)


Lesenswert?

1
#define F_CPU 20000000UL // Clock Speed
2
#define BaudRate 9600UL  // Baud-Rate
3
#define U2X_BIT 0
4
#define STRINGLEN 7
5
6
#include <avr/io.h>
7
#include <util/delay.h>
8
#include <stdlib.h>
9
#include <string.h>
10
11
12
void uart_init()
13
{
14
    unsigned short ubrr = (-5) + F_CPU/((16L-8*U2X_BIT)*BaudRate);
15
 
16
    UBRR0H = (uint8_t) (ubrr>>8);
17
    UBRR0L = (uint8_t) (ubrr);
18
 
19
    // UART Receiver und Transmitter anschalten 
20
    // Data mode 8N1, asynchron 
21
    UCSR0B = (1 << RXEN0) | (1 << TXEN0);
22
23
    // Set frame format: 8data, 2stop bit //
24
    UCSR0C = (1<<USBS0)|(3<<UCSZ00);
25
26
    // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) 
27
    do
28
    {
29
        UDR0;
30
    }
31
    while (UCSR0A & (1 << RXC0));
32
33
   DDRB|=(1<<DDB1);
34
   DDRB|=(1<<DDB2);
35
}
36
37
void uart_putc (uint8_t c)
38
{
39
    // Warten, bis UDR bereit ist für einen neuen Wert 
40
    while (!(UCSR0A & (1 << UDRE0)))
41
        ;
42
43
    // UDR Schreiben startet die Übertragung 
44
    UDR0 = c;
45
46
}
47
48
49
uint8_t uart_getc_wait()
50
{
51
    // Warten, bis etwas empfangen wird 
52
    while (!(UCSR0A & (1 << RXC0)))
53
        ;
54
55
    // Das empfangene Zeichen zurückliefern 
56
    return UDR0;
57
}
58
59
void uart_puts (char *string)
60
{
61
    do
62
    {
63
        uart_putc (*string);
64
    }
65
    while (*string++);
66
}
67
68
int main()
69
{
70
  uint8_t sign;
71
  uint8_t signes[4];
72
  int i = 0;
73
74
  uart_init();
75
  
76
  while(1)
77
  {
78
79
    sign = uart_getc_wait();
80
  while(i<3)
81
  {
82
    signes[i] = sign;
83
    i++;
84
    uart_putc(sign);
85
    sign = uart_getc_wait();
86
  }
87
88
  i = 0;
89
90
  // Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte) 
91
    do
92
    {
93
        UDR0;
94
    }
95
    while (UCSR0A & (1 << RXC0));
96
97
    if(signes[0] == 'e' && signes[1] == 'i' && signes[2] == 'n')
98
    {
99
      PORTB |= (1<<PB1);
100
      _delay_ms(500);
101
      PORTB &= ~(1<<PB1);
102
      _delay_ms(500);
103
    }
104
    else if(sign == 'a')
105
    {
106
      PORTB |= (1<<PB2);
107
      _delay_ms(500);
108
      PORTB &= ~(1<<PB2);
109
      _delay_ms(500);
110
    }
111
  //signes[3] = '\0';
112
  //uart_puts(signes);
113
    
114
  }
115
116
  return 1;
117
}

Das hier wäre der Quellcode. wie gesagt, einzelne Sachen empfange ich 
aber sobald mehrere kommen gibs Chaos.

MfG Atmega168

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

die -5 ist falsch

von Atmega 1. (atmega168)


Lesenswert?

Hab ich auch schon weggemacht, funtkioniert dennoch nicht?

MfG Atmega168

von Atmega 1. (atmega168)


Lesenswert?

Hab keine Ahnung was da falsch sein kann.

MfG Atmega168

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.