logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[atmega 32] uruchomienie ADC

KamBys 22 Lip 2009 11:33 3372 10
  • #1 6808643
    KamBys
    Poziom 23  
    mam problem ze skonfigurowaniem przetwornika a/c w atmedze32. pisze w c. jakie wartosci powinny miec rejestry przy inicjalizacji dzialania przetwornika? aref=5V, korzystam z wejścia PA1 (ADC0). wejscie zamierzam uzyc do mierzenia temperatury z LM35

    program, odczytuje raczej glupoty niz poprawne wartosci, ale cos sie dzieje...
    
    #include <avr/io.h> 
    #include <avr/interrupt.h>
    #include <stdlib.h> 
    #include "hd44780.h"
    #include "twi.h" 
    #include "bcd.h"
    #include <avr/delay.h> 
    #include <stdio.h> 
    #include <avr/sleep.h>
    #include <avr/signal.h> 
    #define ADC_VREF_TYPE 0x40
    
    
    unsigned int read_adc(void)/**************************************************/
      {
      ADMUX=0; 					// určí převáděný kanál
      ADCSRA|=0x40; 					// odstartuje převod
      while ((ADCSRA & 0x10)==0);
      ADCSRA|=0x10;
      return ADCW/10;
      }
    
    int main(void)   
    { 
    ACSR=0x80;
      SFIOR=0x00;
      ADMUX=ADC_VREF_TYPE;
      ADCSRA=0x87; 
    while (1) 
    { 
    vysledek = read_adc();
    itoa(vysledek,themp,10);
    
     LCD_GoTo(0,1);
    LCD_WriteText(themp);
    } 
    return (0);            
    }
  • #2 6809250
    Konto nie istnieje
    Konto nie istnieje  
  • #4 6810276
    gothye
    Poziom 33  
    Inicjalizacja ADC :
    #define VREF _BV(REFS0) //napiecie referencyjne podłaczone do vcc
    
    void adc_init()
    {
    	ACSR=0x80;
    	SFIOR=0x00;
    
    	ADMUX=VREF;
    	ADCSRA=0x85;
    }


    odczyt z adc :

    unsigned int read_adc(unsigned char adc_input)
    {
    	ADMUX=adc_input|VREF;				
    	ADCSRA=0x40;												
    	while ((ADCSRA & 0x10)==0);			
    	ADCSRA|=0x10;
    	return ADCW;
    }


    Swoją drogą zapytam ,używał ktoś z was wbudowanego kompaktora w M32 :?:
  • #5 6812899
    KamBys
    Poziom 23  
    _Robak_, probowalem z tamtej strony rowniez przerobki, jednak nie wyszlo mi. byc moze dlatego ze to nie na atmege32 jest pisane (inna nazwa rejestru - ADSR a nie ADSRA).

    gothye, dzieki za kod, wieczorem bede walczyl dalej
  • #6 6813015
    _Robak_
    Poziom 33  
    No jest to dla starej wersji kompilatora, ale mi przerobienie kody na ATmege16 zajelo 5min i poszlo od strzala, wiec skomplikowane nie jest :)
  • #7 6816076
    KamBys
    Poziom 23  
    juz mi rece opadaja, zastosowalem sie do procedur _Robak_'a i program sie wiesza w miejscu while ((ADCSRA & 0x10)==0); warunek nigdy nie jest spełniony...
    przypomne Aref=5V, zegar 11,052 Mhz. zaczalem sie zastanawiac czy nie jest po prostu uszkodzony przetwornik a/c w atmedze (nie mam teraz drugiej na podmiane).

    
    #include <avr/io.h> 
    #include <avr/interrupt.h>
    #include <stdlib.h> 
    #include "hd44780.h"
    #include "twi.h" 
    #include "bcd.h"
    #include <avr/delay.h> 
    #include <stdio.h> 
    #include <avr/sleep.h>
    #include <avr/signal.h> 
    
    #define VREF _BV(REFS0) //napiecie referencyjne podłaczone do vcc
    
    void adc_init() 
    { 
       ACSR=0x80; 
       SFIOR=0x00; 
    
       ADMUX=VREF; 
       ADCSRA=0x85; 
    }
    
    unsigned int read_adc(unsigned char adc_input) 
    { 
       ADMUX=adc_input|VREF;             
       ADCSRA=0x40;                                     
       while ((ADCSRA & 0x10)==0);          
       ADCSRA|=0x10; 
       return ADCW; 
    }
    
    int main(void)    //Program główny 
    { 
    unsigned char sek;
    unsigned char godz;
    unsigned char min;
    unsigned char napis[16];
    unsigned int value;
    unsigned char napis2;
    unsigned int themp;
    
    LCD_Initalize();  
    twiinit();
    adc_init();
    
    while (1) 
    { 
    	twistart();
    	twiwrite(0xA0);
    	twiwrite(0x02);	
    	twistop();
    	twistart();
    	twiwrite(0xA1);
    	sek=twiread(ACK);
    	min=twiread(ACK);
    	godz=twiread(NOACK);
    	twistop();
    
    sek=bcd2bin(sek);
    min=bcd2bin(min);
    godz=bcd2bin(godz);
     LCD_GoTo(0,0);     
    sprintf(napis,"%02d:%02d:%02d ",godz,min,sek);
     LCD_WriteText(napis);
    
      
    value = read_adc(0);
    sprintf(napis2,"%04d ",themp);
    
     LCD_GoTo(0,1);
    
    LCD_WriteText(napis2);
    
    _delay_ms(100);
    
    } 
    
    return (0);            //Powrót do początku programu 
    }
    
  • #8 6816143
    _Robak_
    Poziom 33  
    Kurde, nie czaje kompletnie czemu ludzie pisza caly program po czym im nie dziala i wklejaja caly kod na elektrodzie, i nie chodzi o to zeby wkleic tylko czesc kodu ale zeby zaczac debugowac swoj program od odchudzenia do niedzialajacej czesci. Wywal wszystko z programu i zostaw tylko czesc do ADC i wyswietlania tej wartosci. Oczywiscie wczesniej sprawdz poprawnosc wyswietlania.
  • #9 6817913
    KamBys
    Poziom 23  
    spokojnie, sprawdzalem na "okrojonym" programie:

    #include <avr/io.h> 
    #include <stdlib.h> 
    #include "hd44780.h"
    #include "twi.h" 
    #include "bcd.h"
    #include <avr/delay.h> 
    #include <stdio.h> 
    #include <avr/signal.h> 
    
    #define VREF _BV(REFS0) //napiecie referencyjne podłaczone do vcc
    
    
    void adc_init() 
    { 
       ACSR=0x80; 
       SFIOR=0x00; 
    
       ADMUX=VREF; 
       ADCSRA=0x85; 
    }
    
    unsigned int read_adc(unsigned char adc_input) 
    { 
       ADMUX=adc_input|VREF;             
       ADCSRA=0x40;                                     
       [code]while ((ADCSRA & 0x10)==0);   [/code]       
       ADCSRA|=0x10; 
       return ADCW; 
    }
    
    int main(void)    //Program główny 
    { 
    unsigned int value;
    unsigned char napis2;
    unsigned int themp;
    
    LCD_Initalize();  
    adc_init();
     
    while (1) 
    { 
    value = read_adc(0);
    LCD_WriteText("napis");
    _delay_ms(100);
    } 
    
    return (0);            //Powrót do początku programu 
    }
    
    


    i problem ten sam - przetwornik nie konczy konwersji, program staje w miejscu
    while ((ADCSRA & 0x10)==0);   

    i od poczatku mam z tym problem...
  • #10 6819294
    _Robak_
    Poziom 33  
    Wkleje moj dzialajacy kod

    
    SIGNAL(SIG_ADC)                        // przerwanie z przetwornika ADC
    {
     
      value_adc = ADC;                        // czytaj wartość z przetwornika ADC
      
    }
    
    int main( void )                        
    {	
    	
    	ADCSRA = 0x8D;
                sei();                // włącz obsługę przerwań
    
    
    		/////////////////////////////////////////
    		// sprawdzanie napiecie VPP przy FPGM=0//
    		/////////////////////////////////////////
    		PORTE&=~_BV(PE7);
    		ADMUX&=~_BV(MUX0);
    		_delay_ms(1);
    		check_v[0]=1;
    		ADCSR=0xCD;
    		_delay_ms(10);
    		if ((value_adc>349)&&(value_adc<386)) //349
    		{
    			check_v[0]=1;
    		}else
    		{
    			voltage[0]=((value_adc*0.00488)/(0.35915));
    			check_v[0]=0;
    		}
    }
    
    
    

    Sprawdzane na atmedze 64 i dzialalo bez zarzutu. To sa szczatki programu ale chodzi o idee :) Aha, jesli program skacze ci w miejsce jakies i sei wiesza to niekoniecznie wina programu. Daj na generator RC wewnetrzny, mozesz miec skopana PCB (sciezki pod kwarcem czy kondensatorami).
REKLAMA