Forum: Mikrocontroller und Digitale Elektronik Attiny 45 kleines? ADC Problem


von Bernd P. (bernte)


Lesenswert?

Hallo liebes Forum

Bei mir auf dem Schreibtisch passieren grade merkwürdige Dinge.

Ich bastel als Weihnachtsgeschenk einen LED Dimmer. Ein analoges 
SPannungssignal an ADC1 soll die PWM OC0A steuern.

Ich habe die Schaltung auf dem Steckbrett aufgebaut und es funktionierte 
alles tadellos. Nun habe ich eine Platine geätzt und musste aus 
Layoutgründen einen anderen AD Eingang nutzen, statt ADC2 wollt ich ADC1 
nutzen und in den MUX einfach die entsprechenden Bits setzen. Es geht 
aber auf einmal nicht mehr :-( Hier mal der Quellcode, vielleicht sieht 
jemand den Fehler?

Ich hoffe ihr könnt mir helfen, vielleicht habe ich vergessen noch etwas 
umzustellen?

Viele liebe Grüße und ein gesegnetes Weihnachtsfest

Bernd

#include <inttypes.h>
#include <avr/io.h>

void
ioinit (void)
{

    TCCR0A |=
        (1 << WGM00) |
        (0 << WGM01) |
        (0 << COM0B0) |
        (0 << COM0A0) |
        (1 << COM0B1) |
        (1 << COM0A1);

    TCCR0B |= (0 << CS02) |
              (1 << CS01) |
              (0 << CS00) |//
              (0 << WGM02);

    OCR0A = 0;
    OCR0B = 255; //anders genutztes PWM Signal

    /* IO */
    DDRB = (1 << PB1) | (1 << PB0);
    DDRB &= 0b11111011;

    /* Enable timer 1 overflow interrupt. */
    TIMSK |= (1 << TOIE0);

    ADMUX |= (0 << ADLAR)|
             (1 << MUX0) | // hier habe ich den anderen Eingang genutzt
             (0 << MUX1) |
             (0 << MUX2) |
             (0 << MUX3) |
             (0 << REFS0)| // interne 2.56V reference
             (1 << REFS1)|
             (1 << REFS2);

    ADCSRA |= (1 << ADEN)| // Analog-Digital enable bit
              (0 << ADPS2)|
              (1 << ADPS1)| // set prescaler to 8 (clock / 8)
              (1 << ADPS0)|
              (1 << ADSC);

}

uint16_t adc_read(void)
{
  uint16_t temp;
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung
    while (ADCSRA & (1<<ADSC) );          // auf Abschluss der 
Konvertierung warten

    temp = ADCL;       // mit uint16_t
    temp += (ADCH<<8);

    return temp;
}

uint16_t adc_read_avg(uint8_t average )
{
  uint16_t temp = 0;
  uint8_t i;

  for (i = 0; i < average; ++i )
    temp += adc_read();

  return (temp / average);
}

int
main (void)
{

    ioinit ();

    while (1)
      {
      OCR0A = (adc_read() && 0xFF);
      }

    return (0);
}

von Sascha W. (sascha_w)


Lesenswert?

1
   /* Enable timer 1 overflow interrupt. */
2
    TIMSK |= (1 << TOIE0);
wo ist die dazugehörige ISR ??
1
    /* IO */
2
    DDRB = (1 << PB1) | (1 << PB0);
3
    DDRB &= 0b11111011;
beeinflusst zwar die Funktion in diesem Fall nicht, aber was soll die 2. 
Zeile?

Sascha

von Bernte (Gast)


Lesenswert?

Hey

Die ISR ist leer und wird nicht genutzt. Ist noch ein Relikt. Mit der 
zweiten Zeile wollte ich den Pin als Eingang maskieren.

Mittlerweile tut der DAC es. Musste die richtigen fuses setzen für den 
int. Oszillator. Jetzt quält mich allerdings ein andauerndes resetten 
des µC wenn ich irgendeine delay Funktion nutze. Stichwort: Watchdog?

Naja das Problem oben hat sich wie gesagt durch die Fuses erledigt.

Viele Grüße
Bernd

von Sascha W. (sascha_w)


Lesenswert?

Bernte schrieb:
> Hey
>
> Die ISR ist leer und wird nicht genutzt. Ist noch ein Relikt. Mit der
> zweiten Zeile wollte ich den Pin als Eingang maskieren.
1
   DDRB = (1 << PB1) | (1 << PB0);
danach ist DDRB=0b00000011
was soll
1
    DDRB &= 0b11111011;
daran noch ändern?
> Mittlerweile tut der DAC es. Musste die richtigen fuses setzen für den
> int. Oszillator.
ja die Fuses

> Jetzt quält mich allerdings ein andauerndes resetten
> des µC wenn ich irgendeine delay Funktion nutze. Stichwort: Watchdog?
immer noch die Fuses "WDTON" sollte aber default aus sein.

Sascha

von Bernd P. (bernte)


Lesenswert?

Ja du hast recht mit dem PIN Aus und Eingang.

Kannst du mir das Problem mal näher erklären? Warum muss ich den 
Oscillator fusen damit das ganze funktioniert?

WDTON ist disabled. Allerdings gibt es trotzdem dauernd resets. Muss ich 
noch irgendwas mit BrownOut-Detect machen? Den Resetpin selbst kann ich 
ausschließen, dort scheint alles in Ordnung.

Viele Grüße und danke, dass dus dir angeguckt hast

Bernd

von Sascha W. (sascha_w)


Lesenswert?

Bernd P. schrieb:
> Kannst du mir das Problem mal näher erklären? Warum muss ich den
> Oscillator fusen damit das ganze funktioniert?
wie hast du den den OSC jetzt eingestellt, und was was vorher 
eingestellt?
war die Taktfrequenz für den ADC evl. zu hoch?
und überlege mal:
* dein ADC läuft mit 1/8 Clock die Wandlung dauert 13 Zyklen - nach 
jeder Wandlung machst du ein Update von OCR0A
* deine PWM läuft mit 1/8 Clock und ein Durchlauf braucht 512 Zyklen
das häufige Update von OCR0A macht zwar nicht's ist aber sinnlos, nimm 
z.B. den TOIE0 um die AD-Wandlung zu starten

> WDTON ist disabled. Allerdings gibt es trotzdem dauernd resets. Muss ich
> noch irgendwas mit BrownOut-Detect machen? Den Resetpin selbst kann ich
> ausschließen, dort scheint alles in Ordnung.
100nF zwischen Ub und Masse AM µC? Testweise mal BO ausschalten.

Sascha

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Bernd P. schrieb:

> WDTON ist disabled. Allerdings gibt es trotzdem dauernd resets. Muss ich
> noch irgendwas mit BrownOut-Detect machen? Den Resetpin selbst kann ich
> ausschließen, dort scheint alles in Ordnung.

Wenn die WDTON Fuse mal programmiert war und jetzt auf disabled gesetzt 
wurde: 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Watchdog#WDTON_Fuse_zur.C3.BCcksetzen

von Bernd P. (bernte)


Lesenswert?

Den 100 nF C habe ich nicht vorgesehen. Allerdings wird die Schaltung 
durch einen Schaltregler mit konstanten, sauberen 5 V betrieben (sagt 
auch das Oszilloskop)

Der Int. 8MhZ 6/14+0 kam zur Nutzung.

Naja bin leider etwas ratlos :-(

Trotzdem danke für die Mühen
Bernd

von Sascha W. (sascha_w)


Lesenswert?

Bernd P. schrieb:
> Den 100 nF C habe ich nicht vorgesehen.
den sollte man immer vorsehen egal wie gut die Spannungsversorgung 
ist. Die BOD ist da sehr eigen. Mal ausgeschaltet?

> Der Int. 8MhZ 6/14+0 kam zur Nutzung.
naja 1MHz für den ADC ist schon etwas hoch - oder nicht!?

Wie hast du ihn den jetzt eingestellt.


Sascha

von Bernd P. (bernte)


Lesenswert?

Ne der AD zischt ordentlich durch und macht jetzt seine Arbeit, auch bei 
dieser Frequenz. Nur dieses Reset ist mir einfach unerklärlich.

BOD ist disabled.
Reset Pin konstant auf 5 Volt.
Watchdog mittels

  wdt_reset();
  wdt_disable();

ausgeschaltet.

Ach jeh, woran könnte es denn noch liegen?

Noch einen schönen Abend euch.
Bernd

von Floh (Gast)


Lesenswert?

Bernd P. schrieb:
> Ach jeh, woran könnte es denn noch liegen?

- du hast immer noch keinen Abblockkondensator dran?
- du hast im Programm noch irgendwo einen Interrupt ohne Routine?

btw, wie stellst du eigentlich fest, dass der uC sich resettet?

von Bernd P. (bernte)


Lesenswert?

Ich habe eine Initialisierungsroutine in main vor der Endlosschleife. In 
dieser habe ich eine Wartezeit und da sie wegen des resets immer wieder 
ausgeführt wird habe ich ein Blinken.

Den Abblock kann ich nur schwerstens nachrüsten, aber wie gesagt 
Spannung ist mit dem oszilloskop überprüft und sehr sauber.

Viele Grüße
Bernd

von Bernd P. (bernte)


Lesenswert?

Mittlerweile habe ich herausgefunden, dass die eine PWM zusammenbricht, 
wenn ich Last (logic-fet) an die andere PWM anschließe. Das war auf dem 
Steckbrett nicht der Fall. Was für Ursachen könnte dies haben?

Grüße
Bernd

von Nn N. (jaytharevo)


Lesenswert?

Bernd P. schrieb:
> Mittlerweile habe ich herausgefunden, dass die eine PWM zusammenbricht,
> wenn ich Last (logic-fet) an die andere PWM anschließe.

Was bedeutet die PWM bricht zusammen? Die Amplitude der PWM oder was?
Wie viel Strom fließt denn?^^


Außerdem wie schnell kommt der Reset? Immer gleich oder auch mal 
unterschiedlich?

MfG

von Bernd P. (bernte)


Lesenswert?

Ein spätes Hi an alle Mitleser

Mittlerweile funktioniert alles.

Habe HochleistungsLEDs an der PWM und hatte doch ernsthaft vergessen, 
den Vorwiderstand reinzupacken. Scheinbar hatte das zur Folge, dass der 
Ausgang des µC trotz LogicFet zu hoch beansprucht wurde und nicht mehr 
Strom liefern konnte. Ob das im Endeffekt die mögliche Ursache für den 
Reset sein könnte?

Außerdem habe ich den Abblockkondensator noch reingefummelt. Danke an 
alle, ihr seid die besten und mein Weihnachtsgeschenk gerettet =)

Viele Grüße
Bernd

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.