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

[Atmega32][ASM] Problem z ADC

Tarkowski01 11 Mar 2010 03:48 2566 10
  • #1 7812840
    Tarkowski01
    Poziom 11  
    Witam,
    mam następujący problem:
    bity mam ustawione tak jak widać, a przerwanie przychodzi tylko raz w debuggerze- dzięki ustawionemu bitowi ADSC. Jednak po wyjściu z obsługi przerwania ADSC jest wyzerowany, a flaga ADIF w ogóle się nie ustawia. program nie wykonuje przerwania ponownie mimo ustawienia następującego:

    ldi R16, (1<<REFS1)|(1<<REFS0)|(1<<ADLAR)

    ldi R16, (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(ADPS1)|(1<<ADPS0)

    Generalnie program ma zczytywać w regularnych odstępach czasu wartość ADC i porównywać ją z 0x0F. W zależności od tej wartości ma zapalać lub gasić diody na porcie D. Tyle.

    I cały kod:
    .INCLUDE "m32def.inc"
    
    .EQU SYS_FREQ =16
    
    .DSEG
    .ORG   0x0060
    moja_zmienna: .BYTE 2
    
    .CSEG
    .ORG 0
    	jmp Reset
    
    .ORG ADCCaddr
    	rjmp ADC_read
    
    .ORG 0x0030
    Reset:
    	ldi R17, high(RAMEND)
    	ldi R16, low(RAMEND)
    	out SPH, R17
    	out SPL, R16
    	clr R16
    	ldi R17, 2
    	ldi XH,high(0x0060)
    	ldi XL, low(0x0060)
    
    Reset_1:
    	st X+,R16
    	dec R17
    	brne Reset_1
    
    	clr R16
    	ldi R16, (1<<REFS1)|(1<<REFS0)|(1<<ADLAR)
    	out ADMUX, R16
    
    	clr R16
    	ldi R16, (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(ADPS1)|(1<<ADPS0)
    	out ADCSR, R16
    
    
    	ldi R16, 0xFF
    	out DDRD, R16
    	out PORTD,R16	
    
    	ldi R16, 0x00
    	out DDRA, R16
    
    	sei
    	
    Main_Loop:
    
    	jmp Main_Loop
    	
    ADC_read:
    	in R16, ADCL
    	in R17, ADCH
    	
    	cpi R17, 0x0F
    	brlo ch_diode
    	
    koniec_adc:	                    
    	reti
    
    ch_diode:
    	in R17, PORTD
    	cpi R17, 0xFF
    	breq dodaj_00
    	ldi R17, 0xFF
    	out PORTD, R17
    	jmp koniec_adc
    dodaj_00:
    	ldi R17, 0x00
    	out PORTD, R17
    	jmp koniec_adc
    
    
  • #2 7813443
    Konto nie istnieje
    Konto nie istnieje  
  • #3 7813652
    Tarkowski01
    Poziom 11  
    ldi R16, (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)

    jak wklejałem kod to musiałem jakoś skasować. Generalenie linia wygląda tak jak powyżej.

    Program nie działa...
  • #4 7814336
    asembler
    Poziom 32  
    tuz przed wyjsciem z przerwania musisz zrobic start konwerje ADC albo tez ustawic free running mode

    Dodano po 3 [minuty]:

    Czujnie popatrz na bit ADFR
    A tak w ogóle to co to jest ADATE według mnie to tyczy sie rejestry adcsra który wystepuje w Atmedze 324 a w atmedze 32 chyba go nie ma w ogóle.
    Sprawdz w pdf-ie
  • #5 7814913
    Konto nie istnieje
    Konto nie istnieje  
  • #6 7815878
    asembler
    Poziom 32  
    Zgadza sie pod nazwa atmega 32 PDF mialem pdf od atmegi 323.
  • #7 7817468
    Tarkowski01
    Poziom 11  
    ADIF w ogóle się nie zapala. Przez cały czas trwania programu jest równy zero.

    W datasheecie jest napisane:
    "ADIF is cleared by hardware when executing the corresponding interrupt handling vector. "

    Czyli ADIF się automatycznie zeruje gdy korzysta się z przerwań.
  • #8 7817593
    Konto nie istnieje
    Konto nie istnieje  
  • #9 7818273
    Tarkowski01
    Poziom 11  
    Wstawiłem ustawianie ADSC prosto prze uaktywnieniem przerwań i nic nie pomogło...

    in R16, ADCSR
    	sbr R16, 1<<ADSC
    	out ADCSR, R16
    	sei


    Może moglibyście sprawdzić ten kod na swoich debuggerach. Ja korzystam z najnowszej wersji AVR-Studio b684. Być może jest to błąd w programie?
    Symuluje dla simulator1:Atmega32.

    EDIT:

    Znalazłem coś co tłumaczy mój problem.

    Cytat:
    By this do you mean debugging in the simulator or with JTAG? If it is in the simulator, then you will never get an interrupt unless you manually set the ADIF flag in ADCSRA.


    Na forum AVR_freaks:
    http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=312952


    Wniosek stąd, że avr studio jest może i dobre, ale nie do końca. Mam ustalone stałe czasy przy których przychodzi przerwanie- a muszę je sam wywoływać. Trochę bez sensu. Gdybym chciał na przykład zrobić tak, żeby przerwanie to było wywoływane w konkretnym miejscu kodu, to nie mógłbym go przesymulować.

    Wiecie jaki debugger może poradzić sobie z tym problemem?
  • #10 7820033
    asembler
    Poziom 32  
    To ty sprawdzasz na sucho?
  • #11 7828399
    Tarkowski01
    Poziom 11  
    Cytat:
    bity mam ustawione tak jak widać, a przerwanie przychodzi tylko raz w debuggerze- dzięki ustawionemu bitowi ADSC.


    Tak napisałem w pierwszym poście. Pisałem o debuggerze.

    Tak swoją drogą uważam, że po to jest debugger. Żeby sprawdzić czy wszystko działa tak jak planowaliśmy. Nie stosuje debuggera tylko do wyszukiwania błędów krytycznych- widocznych na pierwszy rzut oka obserwując pracę uC. Uważam, że podejście: "napisałem program- działa, więc spoko" jest błędne, gdyż może się okazać, że program działa przypadkiem, albo nie do końca tak jak należy.

    Ale tak czy owak, nie jest to miejsce na dyskusję nad metodami wykorzystywania debuggerów.
REKLAMA