Atmega32 A/D-C (AVR)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sagittarius83
Inlägg: 9
Blev medlem: 22 december 2008, 23:52:31
Ort: Södertälje
Kontakt:

Atmega32 A/D-C (AVR)

Inlägg av sagittarius83 »

Hej!

Sitter här vid min utrustning och tänker på det här med AD-omvandlingen... Hur fungerar det igentligen... Om jag tex ger 2v så ska 3 dioder lysa, men om jag matar in lite mer vad ska hända...? hur ska jag reglera så att jag får det visuellt på dioderna? Vad ska jag tänka på...?

Tack för hjälpen
Senast redigerad av sagittarius83 21 januari 2009, 15:25:40, redigerad totalt 4 gånger.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: Atmega32 A/D-C (AVR)

Inlägg av jesse »

Jag förstår inte frågan?

>men om jag matar in lite mer vad ska hända...?
Förslagsvis så tänds fyra lysdioder :idea:

Jag antar att det är du som gör programmet - alltså bestämmer du vad som ska hända, så varför frågar du oss ?

Vad tänker du använda för spänningsreferens på ADC:n? Det verkar som om Mega-32:an har 2.56 volt och matningsspänningen som alternativ att välja mellan.
SvenW
Inlägg: 1156
Blev medlem: 24 april 2007, 16:23:10
Ort: Göteborg

Re: Atmega32 A/D-C (AVR)

Inlägg av SvenW »

Fråga är lite kortfattad!
Här ett exempel på hur man gör: (Om det var det som var frågan?)
Med reservation, exemplet testat på ATMega48!

Kod: Markera allt


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

#define  WAIT_ADC(void)  { while( ( ADCSRA  & (1 << ADSC)) ) asm("nop") ; }
#define  START_CONVERSION(void)   { ADCSRA |= (1 << ADSC); }
#define  ADMUX_HIGHBITS ((0 << REFS1) | (1 << REFS0) | (0 << ADLAR))

void
setup_adc (void)
{
/* 
 * ADC Multiplexer
 * Selection Register ­ Bit             7     6     5   4  3    2    1    0
 * ADMUX                              REFS1 REFS0 ADLAR ­ MUX3 MUX2 MUX1 MUX0
 *                      Read/Write     R/W   R/W   R/W  R R/W  R/W  R/W  R/W
 *                      Initial Value   0     0     0   0  0    0    0    0
 * 
 * 
 * ADC Control and
 * Status Register A ­ Bit             7    6    5   4    3     2     1     0
 * ADCSRA                            ADEN ADSC ADFR ADIF ADIE ADPS2 ADPS1 ADPS0
 *                     Read/Write     R/W  R/W  R/W R/W  R/W   R/W   R/W   R/W
 *                     Initial Value   0    0    0   0    0     0     0     0
 * 
 */

  ADMUX = ADMUX_HIGHBITS + 0;   /* channel */
    /* channel 0..7, or 0xE(Vbg) 0xF(GND) */

  ADCSRA = (1 << ADEN) | 0x5;   /* Division factor 32, ADC runs on 0.625MHz @ 20 MHz */
}

int
main (void)
{
    static int16_t qa, qb;

    cli ();
    wdt_reset ();
        
    DDRC = 0x00;                /* bit 3..0, pin 28..23 */
    setup_adc ();

  {
      ADMUX = ADMUX_HIGHBITS | 0x01;    /* channel */
      START_CONVERSION ();
      WAIT_ADC ();              /* wait until ADC ready; takes 8*13 = 104 cycles */
    
       qa = (uint8_t) ADCL;
       qa += (((uint8_t) ADCH) - 2) << 8;
  }      
}



sagittarius83
Inlägg: 9
Blev medlem: 22 december 2008, 23:52:31
Ort: Södertälje
Kontakt:

Re: Atmega32 A/D-C (AVR)

Inlägg av sagittarius83 »

SvenW skrev:Fråga är lite kortfattad!
Här ett exempel på hur man gör: (Om det var det som var frågan?)
Med reservation, exemplet testat på ATMega48!
Ok SvenW... tack..
Jag provade din kod, men den verkar inte fungera.... Men så hade jag tänkt:

Jag vill skriva en kod så att:
om man skickar in 2.5Volt från en spänningskälla så ska man få 00001111, (alltså bara 4 dioder lyser), och om man skickar in 5Volt så ska man få 00000000, alltså alla dioder lyser. Dioderna ska motsvara spänningen man skickar in. '
Värdet som du får ut efter en AD-omvandling kommer i standardfallet variera mellan 0 (0x000, binärt 00 0000 0000) och 1024 (0x3FF, binärt 11 1111 1111) när spänningen varierar mellan 0 och +5V. Gör sedan en CASE- eller IF-sats som tänder lämpligt antal dioder vid olika värden.

t.ex

Kod: Markera allt

if(!ad_result)
    PORTB = ~0x00;
elseif(ad_result > 0 && ad_result < (1024/8))
    PORTB = ~0x03;
elseif(ad_result >= (1024/8) && ad_result < (1024/7))
    PORTB = ~0x07;
SvenW
Inlägg: 1156
Blev medlem: 24 april 2007, 16:23:10
Ort: Göteborg

Re: Atmega32 A/D-C (AVR)

Inlägg av SvenW »

Det kan tänkas att några av mina beteckningar är specifika för ATMega48.
Kanske inte fungerar direkt på Atmega32.
Jag är osäker på om man kan gå ända upp till 5V som referensspännnig.
I min konfiguration är den något lägre, minns inte exakt, ca 4,5V.
Om man ändå tänker sig att det går, så blir koden

5V och högre: 11 1111 1111
2.5V: 10 0000 0000
2.4951: 01 1111 1111
0V: 00 0000 0000

Man kan också få det vänsterjusterat direkt med en annan konfigurering.
Kolla med databladet att du får med alla tio bitarna, och att de avläses i rätt ordning, dvs så här:

Kod: Markera allt

       qa = (uint8_t) ADCL;
       qa += (((uint8_t) ADCH) - 2) << 8;
Man läser in låga delen först, sedan den höga.
I exemplet ovan får man det i int16_t centrerat kring mitten.
Behövs inte i ditt fall.

Din kod ser ut att vara OK.

Edit:
Nja, förresten, det där 1024/7 får du se över!
Det finns också en risk att man får med en onödig generell divisionsalgoritm. Säkrast att göra divisionerna för hand eller som
förberänkade konstanter.
Senast redigerad av SvenW 21 januari 2009, 18:32:45, redigerad totalt 1 gång.
bearing
Inlägg: 11677
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Atmega32 A/D-C (AVR)

Inlägg av bearing »

Mindre kod, längre exekveringstid.

Kod: Markera allt

static int16_t i;

...
qa = (uint8_t) ADCL + 1;
qa += ((uint8_t) ADCH) << 8;
qa >>= 2;

PORTB=0;
for ( i=1; i<=qa; i<<=1)
{
    PORTB|=i;
}
...
sagittarius83
Inlägg: 9
Blev medlem: 22 december 2008, 23:52:31
Ort: Södertälje
Kontakt:

Re: Atmega32 A/D-C (AVR)

Inlägg av sagittarius83 »

Tack grabbar! :D Ni har varit till stor hjälp för mig...
Ha en fortsatt trevlig dag :bravo:
Skriv svar