Forum: Mikrocontroller und Digitale Elektronik USART Probleme beim atmega324p


von T.A. (Gast)


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)


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)


Lesenswert?

danke

von T.A. (Gast)


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)


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)


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)


Lesenswert?

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

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.