Forum: Mikrocontroller und Digitale Elektronik USART Probleme beim atmega324p


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von T.A. (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Hi Leute ich würde gern, dass was ich eingelesen habe auf RXD Wieder auf 
TXD ausgeben als CHAR

Ich steh auf der Leitung,.... gibt nix aus:

/*
 * C2T3_v1.c
 *
 * Created: 28.05.2017 16:13:26
 * Author : Gert
 */

#include <avr/io.h>
#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include <avr/interrupt.h>
#include <util/setbaud.h>
#include <util/delay.h>


#define FOSC 16000000
#define MYUBRR 51


void uart_init(void)
{
 cli();
   //1 = output, 0 = input
   // DDRB = 0b11101111; //PB4 = MISO
   // DDRC = 0b11111110; //
   DDRD = 0b11111110; //PORTD (RX on PD0)

   //USART Baud rate: 56700
   UBRR0H = (MYUBRR >> 8);
   UBRR0L = MYUBRR;
   UCSR0B = (1<<RXEN0)|(1<<TXEN0);//|(1<<RXCIE0);
   /* Set frame format: 8data, 2stop bit */
   UCSR0C = (0<<USBS0)|(3<<UCSZ00);
   UCSR0A = (1<<U2X0);



}


int uart_putc(unsigned char c)
{
   while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
   {
   }
   UDR0 = c;                   /* sende Zeichen */
  return 0;
}


/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s)
{
  while (*s)
  {   /* so lange *s != '\0' also ungleich dem 
"String-Endezeichen(Terminator)" */
    uart_putc(*s);
    s++;
  }
}


/* Zeichen empfangen */
uint8_t uart_getc(void)
{  PORTD |= (1 << PORTD3);
  while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar

  return UDR0;                   // Zeichen aus UDR an Aufrufer 
zurueckgeben
  PORTD &= ~(1 << PORTD3); //PB0 im PORTB löschen
}

void uart_gets( char* Buffer, uint8_t MaxLen )
{
  uint8_t NextChar;
  uint8_t StringLen = 0;

  NextChar = uart_getc();         // Warte auf und empfange das nächste 
Zeichen

  // Sammle solange Zeichen, bis:
  // * entweder das String Ende Zeichen kam
  // * oder das aufnehmende Array voll ist
  while( NextChar != '\n' && StringLen < MaxLen - 1 ) {
    *Buffer++ = NextChar;
    StringLen++;
    NextChar = uart_getc();
  }

  // Noch ein '\0' anhängen um einen Standard
  // C-String daraus zu machen
  *Buffer = '\0';
}



void USART_Flush( void )
{
  unsigned char dummy;
  while ( UCSR0A & (1<<RXC0) ) dummy = UDR0;
}



int main(void)
{
char char_array[] = { "Programm gestartet" };
char char_array2[] = { "A" };
// Pufferspeicher ausreichend groß
// evtl. Vorzeichen + width + Endezeichen:
//char s[8];
float f = -12.345;
// int16_t i = -12345;
uint16_t adcval;
ADC_Init();
uart_init();
PORTD |= (1 << PORTD3);
_delay_ms(5000);
PORTD &= ~(1 << PORTD3); //PB0 im PORTB löschen
uart_puts(char_array);
char str[2];

    /* Replace with your application code */
    while (1)
    {
  char Line[40];      // String mit maximal 39 zeichen

  uart_gets( Line, sizeof( Line ) );
  uart_puts(Line);




  }
  return 0;
}

von Stefan E. (sternst)


Bewertung
0 lesenswert
nicht lesenswert
1
/* Zeichen empfangen */
2
uint8_t uart_getc(void)
3
{  PORTD |= (1 << PORTD3);
4
  while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar
5
6
  return UDR0;                   // Zeichen aus UDR an Aufrufer 
7
zurueckgeben
8
  PORTD &= ~(1 << PORTD3); //PB0 im PORTB löschen
9
}
Entweder Semikolon vergessen, oder verquere Logik (je nachdem wie du dir 
das eigentlich gedacht hattest).


Bitte beim nächsten Mal für den Code entsprechende Tags verwenden. Und 
ein neuer Thread unter neuem Nick wäre jetzt auch nicht unbedingt nötig 
gewesen.

von T.A. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
danke

von T.A. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
du meinst so:
uint8_t uart_getc(void)
{  PORTD |= (1 << PORTD3);
  while (!(UCSR0A & (1<<RXC0)))   // warten bis Zeichen verfuegbar
{ }
  return UDR0;                   // Zeichen aus UDR an Aufrufer
zurueckgeben
  PORTD &= ~(1 << PORTD3); //PB0 im PORTB löschen
}

von T.A. (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,
Kann mir wer helfen stehe vor einem völlig komischenProblem:

Wenn ich dieses Programm ausführe und ich per UART ein M sende Startet 
sich das Programm Neu: von Vorne...

Woran kann das liegen?

/*
 * C2T3_v1.c
 *
 * Created: 28.05.2017 16:13:26
 * Author : Gert
 */

#include <avr/io.h>
#include <avr/io.h>
#include <stdlib.h>
#include <string.h>
#include <avr/interrupt.h>
#include <util/setbaud.h>
#include <util/delay.h>


#define FOSC 16000000
#define MYUBRR 51

// Globale Variablen
int Messung =0;
int Zeitintervall = 1000;


void uart_init(void)
{
 cli();
   //1 = output, 0 = input
   // DDRB = 0b11101111; //PB4 = MISO
   // DDRC = 0b11111110; //
   DDRD = 0b11111110; //PORTD (RX on PD0)

   //USART Baud rate: 56700
   UBRR0H = (MYUBRR >> 8);
   UBRR0L = MYUBRR;
   UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
   /* Set frame format: 8data, 2stop bit */
   UCSR0C = (0<<USBS0)|(3<<UCSZ00);
   UCSR0A = (1<<U2X0);

  // stdout = &mystdout; //Required for printf init

  //  UCSR0B |= (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);  // UART RX, TX und 
RX Interrupt einschalten
  sei();


}

// Serielle Ausgabe:
/* ATmega16 */
int uart_putc(unsigned char c)
{
   while (!(UCSR0A & (1<<UDRE0)))  /* warten bis Senden moeglich */
   {
   }
   UDR0 = c;                   /* sende Zeichen */
  return 0;
}


/* puts ist unabhaengig vom Controllertyp */
void uart_puts (char *s)
{
  while (*s)
  {   /* so lange *s != '\0' also ungleich dem 
"String-Endezeichen(Terminator)" */
    uart_putc(*s);
    s++;
  }
}
volatile char uart_ausgabe[50] = "";


#define UART_MAXSTRLEN 5

volatile uint8_t uart_str_complete = 0;     // 1 .. String komplett 
empfangen
volatile uint8_t uart_str_count = 0;
volatile char uart_string[UART_MAXSTRLEN + 1] = "";
void USART_Flush( void )
{
  unsigned char dummy;
  while ( UCSR0A & (1<<RXC0) ) dummy = UDR0;
}

ISR(USART0_RX_vect)
{   //PB0 im PORTB setzen

  unsigned char nextChar;

  // Daten aus dem Puffer lesen
  nextChar = UDR0;
  if( uart_str_complete == 0 ) {  // wenn uart_string gerade in 
Verwendung, neues Zeichen verwerfen
    PORTD |= (1 << PORTD3);
    // Daten werden erst in uart_string geschrieben, wenn nicht 
String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird
    if( nextChar != '\n' &&
    nextChar != '\r' &&
    uart_str_count < UART_MAXSTRLEN ) {
      uart_string[uart_str_count] = nextChar;
      uart_str_count++;
    }
    else {
      PORTD &= ~(1 << PORTD3); //PB0 im PORTB löschen
      uart_string[uart_str_count] = '\0';
      uart_str_count = 0;
      uart_str_complete = 1;
    }
  }
}


// ADC
void ADC_Init(void)
{
  // die Versorgungsspannung AVcc als Referenz wählen:
  ADMUX = (1<<REFS0);
  // oder interne Referenzspannung als Referenz für den ADC wählen:
  // ADMUX = (1<<REFS1) | (1<<REFS0);

  // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
  // schon auf 0, also single conversion
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren

  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man 
liest
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu 
lassen" */

  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung
  while (ADCSRA & (1<<ADSC) ) {         // auf Abschluss der 
Konvertierung warten
  }
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
     Wandlung nicht übernommen. */
   (void) ADCW;
   }
   uint16_t ADC_Read( uint8_t channel )
   {
     // Kanal waehlen, ohne andere Bits zu beeinflußen
     ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
     ADCSRA |= (1<<ADSC);            // eine Wandlung "single 
conversion"
     while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung 
warten
     }
     return ADCW;                    // ADC auslesen und zurückgeben
   }

   /* ADC Mehrfachmessung mit Mittelwertbbildung */
   /* beachte: Wertebereich der Summenvariablen */
   uint16_t ADC_Read_Avg( uint8_t channel, uint8_t nsamples )
   {
     uint32_t sum = 0;

     for (uint8_t i = 0; i < nsamples; ++i ) {
       sum += ADC_Read( channel );
     }

     return (uint16_t)( sum / nsamples );
   }



   /* Beispielaufrufe: */


int main(void)
{ cli();
char Programm_gestartet[] = { "Programm gestartet" };
char Messungstartstring[] = { "Messung gestartet" };
char Messungstoppstring[] = { "Messung gestoppt" };
char Messungszeit000string[] = "Messung so schnell als möglich";
char Messungszeit100string[] = "Messung alle 100ms";
char Messungszeit500string[] = "Messung alle 500ms";
char Messungszeit1000string[] = "Messung alle 1000ms";
char Messungszeit2000string[] = "Messung alle 2000ms";
char Messungszeit5000string[] = "Messung alle 5000ms";


// Vergleichsstrings
char Messungstart[] = "M";
char Messungstopp[] = "S";
char Messungszeit000[] = "Z000";
char Messungszeit100[] = "Z100";
char Messungszeit500[] = "Z500";
char Messungszeit1000[] = "Z1000";
char Messungszeit2000[] = "Z2000";
char Messungszeit5000[] = "Z5000";


uint16_t adcval;
ADC_Init();
uart_init();
PORTD |= (1 << PORTD3);
_delay_ms(10000);
uart_puts(Programm_gestartet);
PORTD &= ~(1 << PORTD3); //PB0 im PORTB löschen

sei();

    /* Replace with your application code */
    while (1)
    {

  if(uart_str_complete)
  {
  //uart_puts(uart_string);
  USART_Flush();
  if(strcmp(uart_string, Messungstart) == 0)
  {
  uart_puts(Messungstartstring);
  Messung = 1;
  }
  if(strcmp(uart_string, Messungstopp) == 0)
  {
    uart_puts(Messungstoppstring);
    Messung = 0;
  }
  if(strcmp(uart_string, Messungszeit000) == 0)
  {
    uart_puts(Messungszeit000string);
    Zeitintervall = 0;
  }
  if(strcmp(uart_string, Messungszeit100) == 0)
  {
    uart_puts(Messungszeit100string);
    Zeitintervall = 100;
  }
  if(strcmp(uart_string, Messungszeit500) == 0)
  {
    uart_puts(Messungszeit500string);
    Zeitintervall = 500;
  }
  if(strcmp(uart_string, Messungszeit1000) == 0)
  {
    uart_puts(Messungszeit1000string);
    Zeitintervall = 1000;
  }
  if(strcmp(uart_string, Messungszeit2000) == 0)
  {
    uart_puts(Messungszeit2000string);
    Zeitintervall = 2000;
  }
  if(strcmp(uart_string, Messungszeit5000) == 0)
  {
    uart_puts(Messungszeit5000string);
    Zeitintervall = 5000;
  }
  uart_str_complete = 0;
  }


   if (Messung == 1)
   {  USART_Flush();
    adcval = ADC_Read(PORTA0);
     strcat(uart_ausgabe, itoa(adcval,uart_ausgabe,10));
     uart_puts(Messungstartstring);
   }



  }
  return 0;
}

Es muss etwas mit ADC zu tun haben.

von Eric B. (beric)


Bewertung
0 lesenswert
nicht lesenswert
T.A. schrieb:
> Es muss etwas mit ADC zu tun haben.

Dann minimiere dein Code doch mal soweit, dass das Problem noch auftritt 
und alles unnötige rausgelöscht ist, lerne dann wie man Dateianhänge 
benutzt und die [ c ] und [ /c ] Formattierungscodes.

von Stefan E. (sternst)


Bewertung
0 lesenswert
nicht lesenswert
1
     strcat(uart_ausgabe, itoa(adcval,uart_ausgabe,10));
Das ist eine echt kreative Art, das Programm abzuschießen. ;-)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.