Forum: Mikrocontroller und Digitale Elektronik Bitte um Hilfe bei Problem mit ADC des at89c51ac3


von Markus B. (lordnoxx) Benutzerseite


Lesenswert?

Guten Morgen,

ich möchte den integrierten AD-Wandler des AT89C51AC3 nutzen.
Habe mir das Datenblatt des Controllers genau angesehen und auch den 
Beispiel-Code zum Betrieb der ON-Chip-ADCs von Atmel zur Hilfe genommen.
Dennoch möchte der AD-Wandler nicht so richtig laufen. Mein Compiler ist 
der sdcc. Hier mal mein Code in C:
1
#include <at89c51ac3.h>
2
#include <stdio.h>
3
#include <stdlib.h>
4
#include <string.h>
5
6
__bit conversion_in_progress=0;    /* software flag */
7
//*************************ADC**************************************+
8
void adc_interrupt() __interrupt(8) __using(2);
9
10
void main(void)
11
{
12
  CKCON0 = 0x01;   //X2 Bit setzen und T1X2 auf FOSC/6
13
  spi_init();
14
  EA=1;    // enable interrupts 
15
  EADC = 1;  /* enable ADC interrupt */
16
17
  ADCF |= 0x01;    //define P1.0 as analog input
18
  ADCLK = 0x00;     //Fadsc = XTAL/64 = 22,1184MHz/64=345.6 kHz
19
  ADCON = 0x20;    /* Enable the ADC */
20
  ADCON &= ~0x07;    // Clear the channel field ADCON[2:0]-->[000]  and thus select channel 0
21
  //ADCON |= 0x01;  /* Select channel 1 */
22
  ADCON &= ~0x40;    //stanard 8Bit, no idle mode
23
  
24
  if(!conversion_in_progress)
25
  {    
26
    conversion_in_progress=1;
27
    SPI_send_display_data("conversion not started\r\n");    //das erscheint noch auf dem Display
28
    ADCON |= 0x08;              //start conversion
29
    SPI_send_display_data("conversion started\r\n");    //das erscheint nicht mehr, hier "hängt"
30
                    //also das Programm  
31
  }
32
    
33
  while(conversion_in_progress);
34
    
35
  SPI_send_display_data(int2string(value_converted));
36
        
37
  
38
}
39
  
40
void adc_interrupt() __interrupt(8) __using(2)
41
{
42
  SPI_send_display_data("in interrupt\r\n");
43
  ADCON &= ~0x10;        //clear ADEOC flag
44
  value_converted = ADDH;  
45
  conversion_in_progress=0;  //set software flag
46
}

Durch Textausgabe auf einem Display konnte ich nachverfolgen bis wohin 
das Programm noch läuft. Wie bereits in den Quelltextkommentaren 
vermerkt,
läuft das Programm bis zu der Zeile in welcher das Konvertieren 
gestartet wird. Also bis zum Befehl "ADCON |= 0x08;" und bleibt dann 
hängen.
Lasst euch nicht von den Zeilen mit "SPI_send_display_data();" 
irritieren. Diese sind Teil meiner Debugging Versuche.
Nach mehrstündiger Fehlersuche wende ich mich nun an Euch, mit der Bitte 
um Hilfe in diesem Fall.
Kurzum: Was mach ich falsch, was habe ich nicht bedacht?

Grüße und noch eine Gute Nacht

Markus

von katastrophenheinz (Gast)


Lesenswert?

Ohne dein gesamtes Programm zu kennen, tippe ich auf einen klassischen 
Deadlock: Aus dem Interrupt heraus (also bei weiteren Interrupts 
gesperrt ) rufst du irgendwelche SPI-Routinen auf, die bestimmt auch 
wieder auf Interrupts reagieren müssen aber wg. Interrupts gesperrt nie 
drankommen. - Wie gesagt, das ist mein Schuß ins Blaue

von Markus B. (lordnoxx) Benutzerseite


Lesenswert?

Danke für den Hinweis. Werde so bald wie möglich dem nachgehen und mich 
dann wieder melden. Für weitere Ideen bin ich bis dahin sehr dankbar.

von katastrophenheinz (Gast)


Lesenswert?

Entferne mal die Zeile
> SPI_send_display_data("in interrupt\r\n");
aus der InterruptServiceRoutine

von Markus B. (lordnoxx) Benutzerseite


Lesenswert?

katastrophenheinz schrieb:
> Entferne mal die Zeile
>> SPI_send_display_data("in interrupt\r\n");
> aus der InterruptServiceRoutine

Hey :-)
ich danke dir...das wars...daran hats gelegen. Hab mir also durch das 
Debugging selbst ein Bein gestellt.

Ich wünsch dir nen guten Rutsch.

Viele Grüße
Markus

von Markus B. (lordnoxx) Benutzerseite


Lesenswert?

Hallo, ich hole nochmal meinen alten Thread raus, damit ich für diese 
kleine Frage kein eigenes Thema beginnen muss.


Im Datenblatt des at89c51ac3 steht in Tabelle 72 auf Seite 123 
geschrieben, dass während der AD-Wandlung der Eingangswiderstand am 
Analog-Pin 400 Ohm beträgt.

Ist das wirklich als Widerstand gegen Masse gemeint? Oder ist das der 
Serienwiderstand vor dem Sample&Hold-Kondensator welcher über diese 400 
Ohm
geladen wird?

Mir kommen diese 400 Ohm halt etwas gering vor, wenn man bedenkt dass 
400 Ohm für so manchen OpAmp, welcher als Puffer vorgeschaltet wird, 
doch schon eine recht knackige Last darstellen.

von krumeltee (Gast)


Lesenswert?

Das kann gut sein, du darfst bei den on-chip ADCs keine wunderwerke der 
Technik erwarten. Sie funktionieren und fertig. Umso geringer der 
Widerstand, umso höher der Strom, umso einfacher einen Rauscharmen ADCs 
zu bauen.

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.