Atmega8L8 geht mal, mal nicht

Gast #2750012
Lesenswert?

Hallo,
ich habe mir mit einem Atmega8L8 und 2 temp-abhängigen Widerstänen, 
sowie einem MAX323 eine Schaltung aufgebaut, mit der ich den ADC-Wert 
von PC0 und PC1 an den PC sende.
Das ganze betreibe ich mit einem externen 4MHZ Quartz, soweit 
funktioniert auch alles - odch ich denke die Schaltung macht was sie 
will, mal geht Sie, mal nicht. Heute Mittag funktionierte noch alles, 
heute Abend geht nichts mehr, erst als in den AVR neu gebrannt habe (mit 
der gleichen Software) läuft er wieder los, für ein paar Sekunden, dann 
ist wieder schluss, wieder brennen, geht wiederlos..... Kann mir jemand 
sagen, an was das liegt? Spannung hab ich mal auf 7,5 V hochgesetzt, 
doch das bringt auch nichts.

Gruß
Pfeiffy
Gast #2750079
Lesenswert?

ok, die Schaltung ist die hier aus dem Forum, ich kann Sie nun nicht so 
schnell nachzeichnen:

Schaltung: 
http://www.mikrocontroller.net/articles/Datei:Mega8_Tutorial.png
Uart: http://www.mikrocontroller.net/articles/Datei:AVR-RS232.png

Der temp-ahängige Widerstand ist mit 4,7 K am PC0 angeschlossen.

Ich habe nun bemerkt, dass ich im laufenden betrieb der Schaltung 
zwischen Plus und Minus nur ca. 3.9 Volt habe -> kann das das Problem 
sein, ist der 7805 hinüber.

Hier mein programm:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdlib.h>
4
#include <avr/interrupt.h>
5
#define F_CPU 4000000UL  // Systemtakt in Hz - Definition als unsigned long beachten 
6
#define BAUD 9600UL      // Baudrate
7
 
8
// Berechnungen
9
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
10
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
11
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
12
 
13
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
14
  #error Systematischer Fehler der Baudrate grösser 1% und damit zu hoch! 
15
#endif 
16

17

18
#define CR "\r\nS
19

20

21
#define UART_MAXSTRLEN 10
22
 
23
volatile char uart_string[UART_MAXSTRLEN + 1] = "";
24
char textx[32];
25

26
int channel=1;
27
int channels=2;
28
int adcKanal = 0;
29
int plex = 0;
30
int uart_str_count=0;
31

32

33

34
//Interrupt zur Kanalansteuerung
35
//*******************************
36
ISR(USART_RXC_vect)
37
{
38
  unsigned char nextChar;
39
  // Daten aus dem Puffer lesen 
40
  nextChar = UDR;
41
  uart_string[uart_str_count] = nextChar;
42
  uart_str_count++;
43
  send_string("ooo");//100
44

45
     //Interrupt wirs so lange gelesen, bis ein "Z" kommt, dann wird er verarbeitet
46
  if( nextChar =='Z')
47
  {
48
   channels = 0;
49
   send_string("dddd");//100
50
     //send_string(uart_string);
51
   //annel= atoi(uart_string[1]);
52
   channels= atoi(&uart_string[1]);
53
   send_char(uart_string[1]);
54
     sprintf (textx, "%u", channels);        
55
     send_string(textx);
56
   uart_str_count=0;
57
  
58
  }
59

60

61
}
62

63

64

65
//****************************
66
//---------------------------------
67
void init_uart(unsigned int ubrr)
68
//---------------------------------
69
 {
70
        UBRRH = (unsigned char)(ubrr>>8);
71
        UBRRL = (unsigned char)(ubrr);
72
        //UCSRB |= (1<<RXEN);
73
        //UCSRB |= (1<<TXEN);
74
        //UCSRB |= (1<<RXCIE);
75
        //UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);
76

77

78

79
      UBRRH = UBRR_VAL >> 8;
80
      UBRRL = UBRR_VAL & 0xFF;
81
      UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0); // Asynchron 8N1 
82
      UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);  // UART RX, TX und RX Interrupt einschalten
83
    
84
    sei();
85

86

87
}
88

89
//---------------------------------
90
void init_adc(void) 
91
//---------------------------------
92
{
93
 
94
  uint16_t result;
95
 
96
  ADMUX = (0<<REFS1) | (1<<REFS0);      // AVcc als Referenz benutzen
97
//  ADMUX = (1<<REFS1) | (1<<REFS0);      // interne Referenzspannung nutzen
98
  // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
99
  // schon auf 0, also single conversion
100
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
101
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren
102
 
103
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
104
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
105
 
106
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
107
  while (ADCSRA & (1<<ADSC) ) {}        // auf Abschluss der Konvertierung warten
108
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
109
     Wandlung nicht übernommen. */
110
  result = ADCW;
111
}
112

113
//---------------------------------
114
uint16_t ADC_Read( int channel )/* ADC Einzelmessung */
115
//---------------------------------
116

117
{
118
  // Kanal waehlen, ohne andere Bits zu beeinflußen
119
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
120
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
121
  while (ADCSRA & (1<<ADSC) ) {}  // auf Abschluss der Konvertierung warten
122
  return ADCW;                    // ADC auslesen und zurückgeben
123
}
124

125
//---------------------------------
126
void send_char(unsigned char data) 
127
//---------------------------------
128
{
129
        while (!(UCSRA & (1<<UDRE)));
130
        UDR = data;
131
}
132

133
//---------------------------------
134
void send_string(char *data) 
135
//---------------------------------
136
{
137
        while (*data) {
138
                send_char(*data);
139
                data++;
140
        }
141
}
142

143

144

145
//************
146
int main(void)
147
//************
148
 {
149
        
150
    
151
    init_uart(UBRR_VAL);
152
    init_adc(); 
153
        uint16_t adcval;
154
    while (1) {
155
      int x = 0;
156
          //Kanal 1
157
       cli();//interrupts ausschalten
158
       //hiereine Schleife, in der die ADCs aufgerufen werden
159
       //for(int x = 0;x<sizeArray;x++)
160
       for(int x = 0;x<channels;x++)
161
       {
162
           char text[32];
163
         char kanal[100]; 
164

165
       
166
         
167
         channel = x%6;
168
            
169
         //Schalten Multiplexer abhängig vom channel
170
         plex = x/6;//d.h. 0-5 sind Plex 0;6-11 sind Plex 1.........
171
         //Kanal ist dann der Rest der Rechnung
172
         channel = x%6;
173

174
         DDRB  = 0xFF;             // (3)
175
               PORTB = plex;             // (4)
176

177
         adcval = ADC_Read(channel);
178
             sprintf(kanal, "%d" ,channel);
179
           send_string("c");//99
180
           send_string("X");//88
181
         send_string(kanal);//0=48  1=49
182
         send_string("Y");//89
183
           sprintf (text, "%u", adcval);        
184
         send_string(text);
185
         send_string("Z");//90
186
         send_string("E");//69
187
       //send_string(CR);
188
       //--> ende while......
189
         }    
190

191

192

193
       sei();//interrupts einschalten
194

195

196

197
        _delay_ms(2000);
198

199
        }
200
        return 1;
201
}
Gast #2750100
Lesenswert?

Pfeiffy schrieb:
> Ich habe nun bemerkt, dass ich im laufenden betrieb der Schaltung
> zwischen Plus und Minus nur ca. 3.9 Volt habe -> kann das das Problem
> sein, ist der 7805 hinüber.

Hat der 7805 Blockkondensatoren ?
Was heist du hast den Tra*f*o auf 7,5V hoch gedeht ? Du gibst doch keine 
Wechselspannung auf den 7805, oder ? Oder meinst du so eine Wandwarze 
mit Schalter ? Dann dreh den mal auf 9V.
In der Schaltung von hier ist ein Quarzoszillator eingezeichnet. 
verwendest Du einen Quarzoszillator oder einen Quarz ? Stimmen die 
Fuse-Settings dann auch ?
#2750121
Lesenswert?

Pfeiffy schrieb:
> ok, die Schaltung ist die hier aus dem Forum,

Das haben wir schon oft gehört.
Und ab und an erwischt es wieder jemanden: Wir bitten ihn ein Photo 
seiner Platine zu machen und siehe da, die Blockkondensatoren hat er 
nicht verbaut.

Die neuralgischen Punkte in der Schaltung sind
* Blockkondensatoren
* die 10k am Reset sind zwar nicht unbedingt notwendig, sind aber nicht
  schlecht. Wenn eine µC-Schaltung sporadisch ausfällt, würde ich ihn
  auf jeden Fall verbauen.
Gast #2750129
Lesenswert?

>Die neuralgischen Punkte in der Schaltung sind

Ergänzung: Die neuralgischen Punkte in der Software sind

  send_string("ooo");//100
  send_string("dddd");//100
  channels= atoi(&uart_string[1]);
  send_char(uart_string[1]);
  sprintf (textx, "%u", channels);
  send_string(textx);

So einen Schrott macht man nicht in einem Interrupt.
Gast #2750515
Lesenswert?

holger schrieb:
> Ergänzung: Die neuralgischen Punkte in der Software sind
>
>   send_string("ooo");//100
>   send_string("dddd");//100
>   channels= atoi(&uart_string[1]);
>   send_char(uart_string[1]);
>   sprintf (textx, "%u", channels);
>   send_string(textx);
>
> So einen Schrott macht man nicht in einem Interrupt.

Hallo,

ok, die Ausgaben sind bzw. waren, um zu sehen ob der Interrupt 
funktioniert,
1
"channels= atoi(&uart_string[1]);"
 ist das einzige was ich hier benötige, das andere fliegt nach dem Test 
raus.

Blockkondensatoren-> ? hab ich genau so verbaut wie im Schaltbild 
angegeben: http://www.mikrocontroller.net/articles/Datei:V_Regler.gif 
(war bisher garnicht dabei)
-> ist es aber so, dass die zu nirdrige Spannung mein Problem ist?

Gruß
Pfeiffy
#2750542
Lesenswert?

> Ich habe nun bemerkt, dass ich im laufenden betrieb der Schaltung
> zwischen Plus und Minus nur ca. 3.9 Volt habe -> kann das das
> Problem sein, ist der 7805 hinüber.

Bei welcher Eingangsspannung vom 7805?

Alles was eingangsseitig unter 8V ist, ist problematisch. Der 7805 
braucht mindestens 8V um daraus 5V zu machen. Wenn du mit 9V 
Gleichspannung in den 7805 reinfährst und da kommen nur 4V raus, dann 
ist er hinüber. Mit deinen 7.4V Eingangsspannung ist allerdings nicht zu 
erwarten, dass da 5V rauskommen werden.
#2750564
Lesenswert?

Pfeiffy schrieb:
> -> ist es aber so, dass die zu nirdrige Spannung mein Problem ist?

Wenn am 7805-Ausgang etwas wesentlich anderes als +5V rauskommt, ist 
richtig was faul:
1. Eingangsspannung zu klein
2. Ausgangsstrom zu groß
3. 7805 kaputt
4. Regler schwingt
5. Einbrüche durch hohe Lastspitzen, z.B. vom Programm verursacht + 
Schaltungsfehler
Da man mit dem Multimeter schnelle Änderungen nicht sieht bzw. dann Mist 
messen kann, brauchst Du zum Messen bei 4. und 5. einen Oszi.

Wenn die Spannung kleiner und konstant wäre (und noch in den 
Spezifikationen der verwendeten Bauteile), müsste es zwar gehen, aber 
ein 7805 kann im Normalfall keine stabile kleinere Spannung liefern. 
Daher müssen die Ursachen zuerst gefunden werden.

Gruß Dietrich
#2750591
Lesenswert?

Pfeiffy schrieb:
> ok, ich wechlse heute Abend mal den 7805 aus - ich bekomme auch mit 12V
> nur 4,2 V in der Schaltung

Mess doch mindestens mal den Strom am Eingang, ob der im grünen Bereich 
ist!
Wird der Regler warm?
Dieses "mal wechseln" ist nur beschränkt erleuchtend, wenn es vorher 
noch einfache Möglichkeiten zur Eingrenzung der Ursache gibt... (bei 
gesockelten Bauteilen ist das Wechseln ja noch OK).

Gruß Dietrich

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren