Forum: Mikrocontroller und Digitale Elektronik ADC-Interrupt und UART keine Übertragung


von Marko (Gast)


Lesenswert?

Guten leute,

Ich habe ein Fehler im Code komme aber nicht drauf habe schon gesucht 
aber beim vergleichen ist mir kein Fehler aufgefallen, denke es liegt am 
Interrupt vom ADC.
Kurz zum Code & Hardware, ATmega8L mit Ext. 4MHz Quarz und gebrannt wird 
er mit stk500 auf einem Steckbrett.
Das Programm soll später in 2 Versionen laufen
1)Einmal den ADC wert lesen und am PC schicken.
z.B:
Spannung = 1.1V
2)Wenn PB0 auf masse ist, dauer haft messen und an PC schicken.
z.B:
Spannung = 1.1V
Spannung = 1.9V
Spannung = 2.1V usw.

Hoffe ist verständlich genug :)

Ob die Übertragung richtig ist, weis ich nicht da am terminal nichts an 
kommt denke es liegt am ADC-Interrupt.
1
#ifndef F_CPU
2
#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
3
#define F_CPU 4000000UL  
4
#endif
5
#define BAUD 9600UL      // Baudrate
6
 
7
// Berechnungen
8
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
9
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
10
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
11
 
12
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
13
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
14
#endif 
15
16
#include <avr/io.h> 
17
#include <util/setbaud.h>
18
#include <avr/interrupt.h>
19
#include <stdlib.h>
20
21
volatile uint8_t Faktor = 27;
22
volatile uint16_t Teiler = 10240;
23
24
float Volt_val = 0;
25
 
26
27
void uart_init(void)
28
{
29
  UBRRH = UBRR_VAL >> 8;
30
  UBRRL = UBRR_VAL & 0xFF;
31
 
32
  UCSRB |= (1<<TXEN);  // UART TX einschalten
33
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
34
}
35
int uart_putc(unsigned char c)
36
{
37
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
38
    {
39
    }                             
40
 
41
    UDR = c;                      /* sende Zeichen */
42
    return 0;
43
}
44
 
45
 
46
/* puts ist unabhaengig vom Controllertyp */
47
void uart_puts (char *s)
48
{
49
    while (*s)
50
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
51
        uart_putc(*s);
52
        s++;
53
    }
54
}
55
int main()
56
{
57
/*Analog-Digital-Wandler-Init*/
58
ADMUX  = (1<<REFS0);//ReferenzSpannung AVcc | Kanal 0 ADC0(PC0)
59
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);//ADC enable| Singel Mode| Adc Interrupt | Frequenzvorteiler F_CPU/64
60
61
cli();
62
ADCSRA |= (1<<ADSC);//Dummy-wert ohne Interrupt auslösen 
63
while (ADCSRA & (1<<ADSC) ) {}        
64
65
sei(); //Interrupt Erlauben
66
67
  if(!(PINB & (1<<PINB0)))//wenn auf masse dann ADC-dauerhaft einsetzten und jedes mal Interrupt auslösen
68
  {
69
    while(1)
70
    {
71
      ADCSRA |= (1<<ADSC);
72
      while (ADCSRA & (1<<ADSC) )
73
      {}
74
  ADCSRA =(1<<ADIF);//Interrupt auslösen
75
    }//Ende while
76
  }//Ende if
77
78
  else //Einmal Messung durch führen und Interrupt auslösen
79
  {
80
    
81
    ADCSRA |= (1<<ADSC);
82
    while (ADCSRA & (1<<ADSC) ) //warte bis messung fertig ist
83
    {}
84
    ADCSRA =(1<<ADIF);//Interrupt auslösen 
85
  }//Ende else
86
87
return 0;
88
89
}//Ende main
90
91
ISR(ADC_vect)
92
{
93
uart_init();
94
char Wert [] = "Spannung = ";
95
Volt_val = ((ADCW * Faktor)/ Teiler);
96
97
dtostrf(Volt_val,1,2,Wert);
98
99
itoa(ADCW,Wert,2);
100
uart_puts(Wert);
101
102
}

Danke für die Hilfe und Tipps.

MfG Marko

von Karl H. (kbuchegg)


Lesenswert?

Ich sehe in deinem Code keine Stelle an der die UART jemals 
initialisiert werden würde.

von Karl H. (kbuchegg)


Lesenswert?

> Danke für die Hilfe und Tipps.

* In einer ISR werden keine UART Ausgaben gemacht.
  Die dauern viel zu lange

* Für den ADC brauchst du eigentlich überhaupt keinen Interrupt
  Der macht das ganze System nur unnötig kompliziert.

* Ähm. Deine 'Interrupt-Steuerung', wozu soll die überhaupt gut sein?

* Für die ADC Funktionalität wären ein paar Funktionen angebracht,
  damit du die Hauptschleife möglichst sauber und klein bekommst.
  Das würde deiner Programmübersicht gut tun.

* Codeformatierung!
  Nicht irgendwann, sondern jetzt!

* Anforderungen überprüfen!
> 1)Einmal den ADC wert lesen und am PC schicken.
  Das ist keine sehr sinnvolle Anforderung. Was soll 'einmal' messen
  bedeuten? Wie wird diese Einmalmessung angestossen.
  Nach dem Anlegen der Versorgungsspannung soll der ADC einmal messen
  ist normalerweise keine sinnvolle Anforderung. Das solltest du nochmal
  überprüfen, ob das wirklich das ist, was du willst.

* Du willst dein Programm auf keinen Fall aus main() rauslassen. Selbst
  wenn die Aufgabe darin besteht eine Einmalmessung zu machen, musst du
  das Programm innerhalb mein() halten.

* Schmeiss dein Programm weg und schreib es neu.
  Geht schneller, als da jetzt alles zurechtzurücken.
  Aber schreib es diesmal vernünftig! Deine main() könnte so aussehen.
  Das ist leicht zu überblicken und Fehler sind leichter zu sehen, als
  wie wenn du da einen haufen Code unstrukturiert aufstapelst. Was
  rauskommt, wenn du die Dinge unübersichtlich schreibst hast du ja
  jetzt gesehen. Also mach es nicht.

1
...
2
3
void PerformMeasurement()
4
{
5
  uint16_t adc_Value;
6
  float    Volt;
7
  char     Buffer[20];
8
9
  adc_Value = adc_read();
10
  Volt = ((adc_Value * Faktor)/ Teiler);
11
12
  sprintf( Buffer, "%d %.2f\n", adc_Value, Volt );
13
  uart_puts( Buffer );
14
}
15
16
int main()
17
{
18
  uart_init();
19
  adc_init();
20
21
  DDRB &= ( 1 << PB0 );   // PB0 auf Eingang
22
  PORTB |= ( 1 << PB0 );  // Pullup an PB0 einschalten
23
24
  if( PINB & ( 1 << PB0 ) ) {
25
    PerformMeasurement();
26
    while( 1 )
27
      ;
28
  }
29
30
  else {
31
    while( 1 )
32
      PerformMeasurement();
33
  }
34
}

von Marko (Gast)


Lesenswert?

Danke für die Tipps habe es geändert/neu geschrieben.
sieht auch übersichtlicher aus, habe aber probleme mit der sprintf().
in deinem Beispiel wird
sprintf( Buffer, "%d %.2f\n\r", adc_Value, Volt );
bekomme ich den richtigen decimal wert aber der float zeigt nur die 
Vorkommastelle an und Nachkommastelle bleiben 00
999 2.00
999 2.00
999 2.00
sollte aber 2.63 sein.
Habe häufig an sprintf rum experimentiert kam aber oft nur misst bei 
rum,
ich kam zu dem Ergebnis

sprintf( Buffer, "\n\rSpannung= %.2f V",Volt);

Spannung=2î
Spannung=2î
Spannung=2î
Spannung=1î
Spannung=1î
Spannung=1î
Spannung=0®
Spannung=0®
Spannung=0®
Spannung=0®
Den Buffer habe ich groß genug gewählt wunder mich warum er bei dem 
String so ein murks darstellt(Ich weis der Programmierer macht Fehler, 
nicht das Programm).

den bin ich auch im avr simulator durch gegangen und da läuft er. Es 
werden zwar auch die Nachkommastellen als nullen dargestellt, aber läuft 
nur einmal durch und stoppt. Die Realität sieht immer anders aus.



Habe die Baud Berechnung raus gelassen, ist noch die Selbe wie oben.
1
#include <avr/io.h> 
2
#include <util/setbaud.h>
3
#include <avr/interrupt.h>
4
#include <stdlib.h>
5
#include <stdio.h>
6
7
volatile uint8_t Faktor = 27;
8
volatile uint16_t Teiler = 10240;
9
10
11
void adc_init(void)
12
{
13
uint16_t result;
14
/*Analog-Digital-Wandler-Init*/
15
ADMUX  = (1<<REFS0);//ReferenzSpannung AVcc | Kanal 0 ADC0(PC0)
16
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1);
17
//ADC enable| Singel Mode|  Frequenzvorteiler F_CPU/64 
18
19
ADCSRA |= (1<<ADSC);                  // eine Dummy-Wandlung 
20
while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
21
22
 result = ADCW;
23
}
24
25
void uart_init(void)
26
{
27
  UBRRH = UBRR_VAL >> 8;
28
  UBRRL = UBRR_VAL & 0xFF;
29
 
30
  UCSRB |= (1<<TXEN);  // UART TX einschalten
31
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
32
}
33
34
int uart_putc(unsigned char c)
35
{
36
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
37
    {
38
    }                             
39
 
40
    UDR = c;                      /* sende Zeichen */
41
    return 0;
42
}
43
 
44
 
45
/* puts ist unabhaengig vom Controllertyp */
46
void uart_puts (char *s)
47
{
48
    while (*s)
49
    {   /* so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" */
50
        uart_putc(*s);
51
        s++;
52
    }
53
}
54
55
uint16_t ADC_Read( uint8_t channel )
56
{
57
  // Kanal waehlen, ohne andere Bits zu beeinflußen
58
  ADMUX = (ADMUX & ~(0b00001111)) | (channel & 0b00001111);
59
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
60
  while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
61
  return ADCW;                    // ADC auslesen und zurückgeben
62
}
63
64
void PerformMeasurement()
65
{
66
  uint16_t adc_Value;
67
  double    Volt;
68
  char     Buffer[25];
69
70
  
71
72
  adc_Value = ADC_Read(0);
73
  Volt = ((adc_Value * Faktor)/ Teiler);
74
  
75
  sprintf( Buffer, "\n\rSpannung=%.2f V",Volt );
76
  uart_puts( Buffer );
77
}
78
79
80
int main()
81
{
82
83
adc_init();
84
uart_init();
85
86
DDRB &= ( 1 << PB0 );   // PB0 auf Eingang
87
PORTB |= ( 1 << PB0 );  // Pullup an PB0 einschalten
88
89
90
91
 if( PINB & ( 1 << PB0 ) ) {
92
    while( 1 )
93
      PerformMeasurement();
94
  }
95
96
  else {
97
    PerformMeasurement();
98
  while( 1 )
99
      ;
100
  }
101
102
103
return 0;
104
105
}//Ende main

@ Karl Heinz
danke für die Tipps und für die Funktion PerformMeasurement()
hat mir sehr geholfen.

von Karl H. (kbuchegg)


Lesenswert?

Marko schrieb:

> sieht auch übersichtlicher aus, habe aber probleme mit der sprintf().
> in deinem Beispiel wird
> sprintf( Buffer, "%d %.2f\n\r", adc_Value, Volt );
> bekomme ich den richtigen decimal wert aber der float zeigt nur die
> Vorkommastelle an und Nachkommastelle bleiben 00

Siehe
http://www.mikrocontroller.net/articles/FAQ#Datentypen_in_Operationen

und wenn du gleich dabei bist
http://www.mikrocontroller.net/articles/FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio

von Marko (Gast)


Lesenswert?

Danke für die hinweiße den zweiten link hatte ich schon gefunden danach 
lief erst float mit Nachkommastellen, dern erstenlink wollte ich gerade 
testen aber ich kann kein Projekt mehr builden, kommt die error
1
rm -rf main.o  adc-uart.elf dep/* adc-uart.hex adc-uart.eep adc-uart.lss adc-uart.map
2
Build succeeded with 0 Warnings...
3
avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
4
../main.c:2:2: warning: #warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 4000000"
5
avr-gcc -mmcu=atmega8 -Wl,-Map=adc-uart.map main.o     -o adc-uart.elf
6
avr-gcc: CreateProcess: No such file or directory
7
make: *** [adc-uart.elf] Error 1
8
Build failed with 1 errors and 1 warnings...

es kommt immer der selbe Fehler ich habe alte Projekte versucht, das 
gleiche problem

von Nn N. (jaytharevo)


Lesenswert?

Hast du irgendwas beim Projekt verändert?

Der Error "avr-gcc: CreateProcess: No such file or directory" deutet 
darauf hin das eine Datei fehlt.

Sonst einfach mal Fehlermeldungen Googeln, dass hilft meistens ;)!

www.google.at/search?q=avr-gcc%3A+CreateProcess%3A+No+such+file+or+direc 
tory

von Marko (Gast)


Lesenswert?

viel gesucht nichts gefunden zu mindestens nicht brauchbares.
hat jemand ein Rat für mich?

von Marko (Gast)


Lesenswert?

Nah dem ich avr Studio neu installiert hatte lief es habe mir bei links 
durch gelesen. das habe dann eingesetzt und eine neue Variable erstellt 
des typs double mit 0.00263671 (Faktor/Teiler). Bekomme aber den 
Übertragungsfehler wie oben? dann wird auch
sprintf( Buffer, "%d %.4f\n\r", adc_Value, Volt );
nicht richtig Übertragen es kommt dann,
3ð32 0.0844
3õ37 0.0976
3ù40 0.1055
4ò42 0.1107
4ó44 0.1160
4ô45 0.1187

Habe da noch eine Verständnis frage zu Strings
wenn ich "Hallo Welt" habe wird das doch so definiert
char Buffer[10] = "Hallo\n\r";
                   123456789+1 für \0

oder liege ich da falsch?

von Karl H. (kbuchegg)


Lesenswert?

\n ist 1 Zeichen. Genauso wie \r

von Marko (Gast)


Lesenswert?

ok also char buffer [8] würde es dann heißen, denn ich habe mal mit dem 
Buffer rum gespielt und gelesen (finde die Seite aber nicht) das wenn 
ich
char buffer[2] = "hallo" würde dann Ha ausgeben.
Habe dann mal in den code Buffer [1]
sprintf( Buffer, "Spannung=%.2f V",Volt );
Eingeben was dann eigentlich zu einem S führt?
bekam aber trotzdem Spannung=2î
Spannung=1î
Spannung=1î
Spannung=1î

von Karl H. (kbuchegg)


Lesenswert?

Marko schrieb:
> ok also char buffer [8] würde es dann heißen,


lass doch den Compiler die Buchsataben zählen.

  char Buffer[] = "Hallo\n\r";

> denn ich habe mal mit dem
> Buffer rum gespielt und gelesen (finde die Seite aber nicht) das wenn
> ich
> char buffer[2] = "hallo" würde dann Ha ausgeben.

Nö. Das ist undefiniert. Alles mögliche kann passieren.

> Habe dann mal in den code Buffer [1]
> sprintf( Buffer, "Spannung=%.2f V",Volt );
> Eingeben was dann eigentlich zu einem S führt?

Zähl die Buchstaben. Wieviele brauchst du?

Hinweis: Es lohnt momentan noch nicht, da zu sparen!
Mach den Buffer 20 oder 30 Zeichen groß, so dass der Text auf jeden Fall 
reinpasst. Zu groß ist (bis auf den Speicherverbrauch) kein Problem, zu 
klein aber schon.

von Marko (Gast)


Lesenswert?

klar habe die buchstaben gezählt und komme auf 18+1 habe den buffer dann 
auf 20 gestellt, aber egal was ich eingebe es kommt immer das selbe raus 
ob 30, 25 oder 100.

von Marko (Gast)


Lesenswert?

Weiss langsam nicht mehr weiter, bin nochmal alles durch gegangen.

Die Ausgabe am terminal Passt nicht wird nicht richtig dargestellt.
Die Übertragung läuft auch dauerhaft, was eigentlich nicht seit sollte.

von Karl H. (kbuchegg)


Lesenswert?

Programm?

Irgendwo müssen die Zeichen ja herkommen. Sieht so aus, als ob du 
irgendwo einen Buffer-Overflow oder einen fehlenden \0 hast.

von Marko (Gast)


Lesenswert?

1
#include <avr/io.h> 
2
#include <util/setbaud.h>
3
#include <avr/interrupt.h>
4
#include <string.h>
5
#include <stdlib.h>
6
#include <stdio.h>
7
#include <util/delay.h>
8
9
10
11
void adc_init(void)
12
{
13
uint16_t result;
14
/*Analog-Digital-Wandler-Init*/
15
ADMUX  = (1<<REFS0);//ReferenzSpannung AVcc | Kanal 0 ADC0(PC0)
16
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);//ADC enable| Singel Mode| Adc Interrupt | Frequenzvorteiler F_CPU/64 // (1<<ADIF)| gelöscht
17
18
ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
19
while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
20
21
 result = ADCW;
22
}
23
24
void uart_init(void)
25
{
26
  UBRRH = UBRR_VAL >> 8;
27
  UBRRL = UBRR_VAL & 0xFF;
28
 
29
  UCSRB |= (1<<TXEN);  // UART TX einschalten
30
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);  // Asynchron 8N1 
31
}
32
33
int uart_putc(unsigned char c)
34
{
35
  UCSRA |= (1<<UDRE);
36
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
37
    {
38
    }                             
39
 
40
    UDR = c;                      /* sende Zeichen */
41
    return 0;
42
}
43
 
44
 
45
/* puts ist unabhaengig vom Controllertyp */
46
void uart_puts (char *s)
47
{
48
  while(*s)
49
    {   // so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" 
50
        uart_putc(*s);
51
        s++;
52
    }
53
}
54
55
uint16_t ADC_Read( uint8_t channel )
56
{
57
  
58
  
59
  // Kanal waehlen, ohne andere Bits zu beeinflußen
60
  ADMUX = (ADMUX & ~(0b00001111)) | (channel & 0b00001111);
61
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
62
  while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
63
  
64
  return ADCW;                    // ADC auslesen und zurückgeben
65
}
66
67
void PerformMeasurement()
68
{
69
uint8_t Faktor = 27;
70
double Teiler = 10240.00;
71
 
72
  uint16_t adc_Value;
73
  double    Volt;
74
  char     Buffer[20];
75
  
76
  
77
  adc_Value = ADC_Read(0);
78
  Volt = ((adc_Value  * Faktor) / Teiler);
79
  
80
81
  sprintf( Buffer, "\n\rSpannung= %.2f"Volt );
82
 
83
  
84
  uart_puts( Buffer );
85
86
}
87
88
89
int main()
90
{
91
92
adc_init();
93
uart_init();
94
95
DDRB &= ( 1 << PB0 );   // PB0 auf Eingang
96
PORTB |= ( 1 << PB0 );  // Pullup an PB0 einschalten
97
98
99
100
101
 if( PINB & ( 1 << PB0 ) ) {
102
    while( 1 )
103
      PerformMeasurement();
104
  }
105
106
  else {
107
    
108
  PerformMeasurement();
109
  while( 1 )
110
     ;
111
  }
112
113
114
115
return 0;
116
117
}//Ende main

Hatte den code nicht eingefügt weil er sich nicht groß ändert.
hatte mit unterschiedlichen string funktionen experementiert (dtostrf 
strcat usw.) kam aber immer zum selben prolem

von Karl H. (kbuchegg)


Lesenswert?

Wie hast du das

  sprintf( Buffer, "\n\rSpannung= %.2f"Volt );

durch den Compiler gekriegt? Da fehlt ein ,

von Marko (Gast)


Lesenswert?

das war mein fehler beim kopieren und habe beim Korrigieren übersehen.

von Karl H. (kbuchegg)


Lesenswert?

Marko schrieb:
> das war mein fehler beim kopieren und habe beim Korrigieren übersehen.

Welches Korrigieren?

Häng doch bitte dein File so an, wie du es compilierst!
Das ist wichtig. Denn mit diesem Fehler ist es unmöglich, dass du ein 
HEX-File bekommst, welches du in den µC brennen kannst. D.h. du kannst 
schon ein HEX-File brennen, nur entspricht das eben nicht dem, was du 
jetzt programmiert hast.

Auf dieser Seite des Monitors kann ich nicht entscheiden, was da jetzt 
Sache ist. Im Zweifelsfall gehe ich davon aus, dass der gezeigte Code 
dann eben nicht der Code ist, der tatsächlich im µC läuft, womit deine 
ganze Fehlerbeschreibung hinfällig ist.

von Marko (Gast)


Angehängte Dateien:

Lesenswert?

Habe das ganze Projekt habe ich angehängt.

Und mit korrigieren meine ich, ich lese mir den post durch(LRS).

Ich kann den µC brennen, gehe den Code im AVR Simulator und da läuft die 
UART-Übertragen nur einmal durch. Nur auf dem µC läuft er in einer dauer 
schleife.

von Karl H. (kbuchegg)


Lesenswert?

Da wird dann eben der Schalter nicht so schalten, wie du dir das 
vorstellst.

Ist das ein Schalter oder ein Taster?
Wie ist er angeschlossen?
Annahme: Taster, und der schaltet sie wie es üblich ist, nach Masse 
durch.
-> Dir ist klar, dass du noch vor dem Programmstart den Taster drücken 
und gedrückt halten musst, bis die erste Messung da ist?

von Karl H. (kbuchegg)


Lesenswert?

1
int uart_putc(unsigned char c)
2
{
3
  UCSRA |= (1<<UDRE);
4
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
5
    {
6
    }

was macht die Oder-Zuweisung an UCSRA da an dieser Stelle?
Damit hebelst du schon mal den Schutz gegen 'Überfahren' des UART aus, 
was dein Problem erklären würde.

von Karl H. (kbuchegg)


Lesenswert?

"\n\rSpannung= %.2f\0"


Du brauchst den String nicht mit \0 abschliessen. Das macht schon der 
Compiler für dich. Jetzt hat dein String 2 Stück \0 Bytes am Ende :-)

von Karl H. (kbuchegg)


Lesenswert?

>  DDRB &= ( 1 << PB0 );   // PB0 auf Eingang

Da fehlt ein ~

(Wirkt sich bei dir jetzt nicht grossartig aus. Ist aber trotzdem ein 
Fehler)

von Karl H. (kbuchegg)


Lesenswert?

Ich denke mal, die UCSRA Sache könnte es gewesen sein. Schmeiss das raus 
und teste nochmal.

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> was macht die Oder-Zuweisung an UCSRA da an dieser Stelle?
> Damit hebelst du schon mal den Schutz gegen 'Überfahren' des UART aus,
> was dein Problem erklären würde.

Wie das? Man kann UDRE nicht manuell setzen.

von Marko (Gast)


Lesenswert?

1
int uart_putc(unsigned char c)
2
{
3
4
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
5
    {
6
    }                             
7
 
8
    UDR = c;                      /* sende Zeichen */
9
    return 0;
10
}
war eine kleine Hilfe für den Avr Simulator damit ich in I/O View nicht 
immer
das bit setzten muss.

Ich gehe davon das die Taster auf masse sind (STK500), der µC ist auf 
dem steckbrett aufgebaut.

von spess53 (Gast)


Lesenswert?

Hi

>war eine kleine Hilfe für den Avr Simulator damit ich in I/O View nicht
>immer das bit setzten muss.

Im wirlichen Leben wird UDRE so gelöscht .

MfG Spess

von Stefan E. (sternst)


Lesenswert?

spess53 schrieb:
> Im wirlichen Leben wird UDRE so gelöscht .

Nein, auch nicht.
Das ist ein reines Read-Only-Bit.

von Karl H. (kbuchegg)


Lesenswert?

spess53 schrieb:
> Hi
>
>>war eine kleine Hilfe für den Avr Simulator damit ich in I/O View nicht
>>immer das bit setzten muss.
>
> Im wirlichen Leben wird UDRE so gelöscht .

Wobei man der Fairness halber sagen muss, dass das so von Atmel nicht 
dokumentiert ist, da hat Stefan Ernst schon recht. (Und ich habs auch 
erst jetzt nachgeschlagen).

D.h. keine Ahnung ob und wenn ja, was da wirklich passiert. Auf jeden 
Fall aber gehört das da nicht hin.

von spess53 (Gast)


Lesenswert?

Hi

Entschuldigung. Verwechslung mit TXC.

MfG Spess

von Marko (Gast)


Lesenswert?

Ich hatte mal alles aus der main gelöscht damit die
PerformMeasurement();
auch einaml durchlaufen wird aber, im terminal wird es immer als 
schleife ausgegeben
1
int main()
2
{
3
4
adc_init();
5
uart_init();
6
7
DDRB &= ~( 1 << PB0 );   // PB0 auf Eingang
8
PORTB |= ( 1 << PB0 );  // Pullup an PB0 einschalten
9
    
10
  PerformMeasurement();
11
12
return 0;
13
14
}//Ende main

von Stefan E. (sternst)


Lesenswert?

1
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
2
                             ^^^^^^^^^

von Karl H. (kbuchegg)


Lesenswert?

Oh Shit.

Und ich hab mir die ADC Sachen nicht mehr angesehen.

von Marko (Gast)


Lesenswert?

Die ADC interrupt erlauben hat doch nichts mit dem UART zu tuhen oder 
sehe ich das falsch?

von Karl H. (kbuchegg)


Lesenswert?

Marko schrieb:
> Die ADC interrupt erlauben hat doch nichts mit dem UART zu tuhen oder
> sehe ich das falsch?

Ein erlaubter INterrupt, zusammen mit einem sei()

UND

einer nicht implementierten ISR

führt zu einem reset des µC.

(Da kommen dann auch deine scheinbaren Dauermessungen her)

von Marko (Gast)


Lesenswert?

Das wusste ich nicht, hatte es auch raus genommen weil ich es ja nicht 
brauche.
Es Wird aber immer noch eine dauer übertragung durchgeführt.
kann es sein das es ander uart_puts() Liegen? weil es ja eine schleife 
ist
1
int uart_putc(unsigned char c)
2
{
3
4
    while (!(UCSRA & (1<<UDRE)))  /* warten bis Senden moeglich */
5
    {
6
    }                             
7
 
8
    UDR = c;                      /* sende Zeichen */
9
    return 0;
10
}
11
 
12
 
13
/* puts ist unabhaengig vom Controllertyp */
14
void uart_puts (char *s)
15
{
16
  while(*s)
17
    {   // so lange *s != '\0' also ungleich dem "String-Endezeichen(Terminator)" 
18
        uart_putc(*s);
19
        s++;
20
    }
21
}

von Karl H. (kbuchegg)


Lesenswert?

Marko schrieb:
> Es Wird aber immer noch eine dauer übertragung durchgeführt.
> kann es sein das es ander uart_puts() Liegen? weil es ja eine schleife
> ist


Nein
Ist der Text jetzt richtig?

von Marko (Gast)


Lesenswert?

Nein immer noch der selbe Fehler.
habe auch schon den Pfad überprüft ob der überhaupt der Richtige ist.
Ja ist der Richtige

von Karl H. (kbuchegg)


Lesenswert?

OK.
Nur um sicher zu gehen:

Kannst du mal wo eine LED anschliessen?

Und dann dein Programm so umändern (ich hab jetzt mal eine LED an B-3 
angenommen:
1
int main()
2
{
3
  DDRB |= ( 1 << PB3 );     // LED
4
5
  PORTB |= ( 1 << PB3 );
6
  _delay_ms( 500 );
7
  PORTB &= ~( 1 << PB3 );
8
  _delay_ms( 500 );
9
10
  adc_init();
11
  uart_init();
12
13
  ....

Die LED darf/muss einmal beim Programmstart kurz aufleuchten. Und danach 
nie wieder. Wenn du sie danach wieder aufleuchten siehst, dann hast du 
noch andere Dinge, die zum Reset führen.

von Marko (Gast)


Lesenswert?

Ja das macht sie, Sie Flackert.
Das heist Irgend wo wird das Programm neu gestart?

von Karl H. (kbuchegg)


Lesenswert?

Marko schrieb:
> Ja das macht sie, Sie Flackert.
> Das heist Irgend wo wird das Programm neu gestart?

genau.
Also alles noch mal durchsuchen, wo du einen Interrupt freigegeben hast, 
für den du keine ISR hast.

(Oder du nimmst einfach mal alle sei() raus. Für einen kurzen Test ist 
das ok. Ansonsten finde ich persönlich das unbefriedigend, wenn man 
einen Fehler im Programm hat, den man im Grunde 'nur abschaltet' ohne zu 
wissen, wo der Fehler liegt.)

von Karl H. (kbuchegg)


Lesenswert?

Du hast aber nicht zufällig den Watchdog per Fuse eingeschaltet?

von Marko (Gast)


Lesenswert?

Nein Das einzige was drin gewessen ist war avr/interrupt.h die habe ich 
raus genommen ändert sich aber nichts.(um sicher zu sein habe ich den 
avr studio nach folgenden sachen suchen lassen sei, cli, isr und sind 
nicht im code vorhanden)
Mir ist aber noch was aufgefallen wenn ich die Delay änder die Frequenz 
beleibt die selbe, was eigendlich nicht sein sollte.

von Marko (Gast)


Lesenswert?

Der WDTON war gesetzt, danke noch mal für die Hilfe.

von Mathias O. (m-obi)


Lesenswert?

Könntest du bitte mal das aktuelle Studio-Projekt (*.aps) posten?

von Marko (Gast)


Angehängte Dateien:

Lesenswert?

Ja klar, Bitte.

von m-obi (Gast)


Lesenswert?

Deine main sieht ja immernoch so seltsam. Und bei dem While-Schleifen 
fehlen die geschweiften Klammern. Läuft es denn bei dir so wie es soll?

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.