mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit UART Ausgabe


Autor: APG Team (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

wir haben ein Problem mit der Aussgabe über die UART. Das Problem ist 
unten genauer Beschrieben hier erstmal der komplette Quellcode, darunter 
dann der Ausschnitt der den Fehler verursacht mit Abmerkungen was schieß 
geht.

Wir verwenden Codevision v2.04.2c und einen ATmega168.

Danke schonmal für die Hilfe und Gruß ;-)
#include <mega168.h>
#include <delay.h>
#include <stdlib.h>
#include <string.h>


//Globale Variablen und Funktionsprototypen
int FileIndex=1000;
int CounterT0=0;
int CounterT2=0;
int iZeitT0=0;
char cIST[5], cSOLL[5], cZeitT0[4];
void USBinit();
void NewFile(int Index, int Typ, int Handle);
void ADConvert();
void USBWrite(int Handle);


// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x05 ;PORTB
#endasm
#include <lcd.h>

// Standard Input/Output functions
#include <stdio.h>

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
CounterT0++;
if(CounterT0==60)
{
iZeitT0++;
ADConvert();
USBWrite(0);
printf("\r\n");
CounterT0=0;
};
}

// Timer2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
// Place your code here


}

#define ADC_VREF_TYPE 0x00

// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTB=0x00;
DDRB=0x00;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=0 State6=0 State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0xC0;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 31,250 kHz
// Mode: Normal top=FFh
// OC2A output: Disconnected
// OC2B output: Disconnected
ASSR=0x00;
TCCR2A=0x00;
TCCR2B=0x06;
TCNT2=0x00;
OCR2A=0x00;
OCR2B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
// Interrupt on any change on pins PCINT8-14: Off
// Interrupt on any change on pins PCINT16-23: Off
EICRA=0x00;
EIMSK=0x00;
PCICR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x01;
// Timer/Counter 1 Interrupt(s) initialization
TIMSK1=0x00;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=0x01;

// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART0 Mode: Asynchronous
// USART Baud Rate: 9600
UCSR0A=0x00;
UCSR0B=0x08;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x17;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
ADCSRB=0x00;

// ADC initialization
// ADC Clock frequency: 1000,000 kHz
// ADC Voltage Reference: AREF pin
// ADC Auto Trigger Source: None
// Digital input buffers on ADC0: On, ADC1: On, ADC2: On, ADC3: On
// ADC4: On, ADC5: On
DIDR0=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x83;

// LCD module initialization
lcd_init(20);

// Global enable interrupts
#asm("sei")


TCCR0B=0x03;

while (1)

      {
      if(PORTD.4==1)
      {
      delay_ms(100);
      USBinit();
      };
      
      if(PORTC.2==1)
      {
      delay_ms(100);
      NewFile(FileIndex,0,0);
      NewFile(FileIndex,1,1);
      ADConvert();
      USBWrite(1);
      TCCR0B=0x03;
      };
      
      
      
      };
}

void USBinit()
{
printf("U\r");
}

void NewFile(int Index, int Typ, int Handle)         // Funktion zum Anlegen einer neuen TXT-Datei
{    
if(Typ==0)
  {
  printf("O %iW>MESS%i.TXT\r",Handle,Index);          // neue TXT-Datei erzeugen -> Tracking
  };
if(Typ==1)
    {
  printf("O %iW>ZUSA%i.TXT\r",Handle,Index);          // neue TXT-Datei erzeugen -> Zusammenfassung
    };
}

void ADConvert()
{
int iIST, iSOLL;
float fIST, fSOLL;
// AD Werte einlesen
iIST=read_adc(0);
iSOLL=read_adc(1);
// Winkel berechnen
fIST=((float)iIST)/1023*90;
fSOLL=((float)iSOLL)/1023*90;
// Winkel in char wandeln
ftoa(fIST,2,cIST);
ftoa(fSOLL,2,cSOLL);
}

void USBWrite(int Handle)
{
int Laenge;
itoa (iZeitT0, cZeitT0);
//Laenge = strlen(cZeitT0) + strlen(cSOLL) + strlen(cIST) + 10;
//printf("W%i>%s\r",Handle, Laenge);
printf("%s;\r",cZeitT0);
printf("\n");
printf("%s;\r",cIST);
printf("\n");
printf("%s\r\n",cSOLL);
//printf("C%i\r",Handle);
}

die Ausgabe erfolgt in diesem Codeabschnitt
void USBWrite(int Handle)
{
int Laenge;
itoa (iZeitT0, cZeitT0);
//Laenge = strlen(cZeitT0) + strlen(cSOLL) + strlen(cIST) + 10;
//printf("W%i>%s\r",Handle, Laenge);
printf("%s;\r",cZeitT0);
printf("\n");
printf("%s;\r",cIST);
printf("\n");
printf("%s\r\n",cSOLL);
//printf("C%i\r",Handle);
}

Erwartet haben wir eine Ausgabe in der Form: (jeweils die Werte der 
Variablen)
cZeitT0;
cIST;
cSOLL

erhalten tun wir allerdings eine wilde Mixture aus allem mit allem 
Kombiniert die dann wie folgt aussieht: (jeweils die Werte der 
Variablen)
cZeitT0;
cISTcISTcZeitT0;
cSOLLcZeitT0

Autor: Billy __ (slowflyer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich bin mir nicht sicher, aber Idee: vermute printf erwartet \0 
terminierte strings, fehlen diese evtl.?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vermutung:

Die Arrays cZeitT0 cIST cSOLL verlieren zur Laufzeit ihre 
abschliessenden Nullbytes durch Bufferoverflows.

Du kannst das testen, in dem du die Arrays größer machst oder gezielt 
das letzte Element jedes Arrays vor dem printf() auf 0 setzt.

Autor: APG Team (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort.
Deine Vermutung hat sich als wahr heraus gestellt wir haben die Array um 
jeweils eine Stelle vergrößert und schon war das Problem gelöst

Vielen herzlichen danke euch beiden und Gruß
APG Team

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
APG Team schrieb:
> Danke für die schnelle Antwort.
> Deine Vermutung hat sich als wahr heraus gestellt wir haben die Array um
> jeweils eine Stelle vergrößert und schon war das Problem gelöst

Legt alle Arrays zusammen und wandelt erst bei der Ausgabe die 
numerischen Werte in die jeweiligen Texte. Kurz vor der Ausgabe.

float fIST, fSOLL;

müssen dann ebenfalls globale Variablen werden, so wie ihr das bei 
iZeitT0 auch gemacht habt.

* dadurch dass der Textbuffer größer wird, läufst du weniger Gefahr bei 
Programmänderungen in dasselbe Problem noch einmal hineinzulaufen.

* in Summe verbrauchst du weniger Speicher

* mit den Winkeln in numerischer Form kann man dann auch rechnen. Mit 
den Texten kannst du ausser ausgeben nicht viel anfangen.

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]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [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.