Ik ben hier (nog steeds) met een project bezig voor school, hierbij moeten we een MMPT regelaar bouwen.

Ik heb het programma in ieder geval al zover, dat ik de 4 ADC waardes die we gebruiken, in kunnen lezen, en wegschrijven naar een geheugenplaats.
echter krijg ik deze message:
"Warning[202] C:\MPPT PROJECT\MPPT PIC16F877A.ASM 61 : Argument out of range. Least significant bits used."

ik weet dat dit komt omdat de ADC 10-bits is, en de memory plaatsen maar 8-bits.

het stukje code is dit:

BANKSEL OPTION_REG ;
movlw B'10000000' ;TMR0 prescaler, 1:2
movwf OPTION_REG ;
movlw B'00000000' ;Left justify, 8 analog channel (only need 4 tough. )
movwf ADCON1 ;VDD and VSS references

BANKSEL PORTB ;Switch to Bank0
Main bcf INTCON,T0IF ;

Loop btfss INTCON,T0IF ;Wait for Timer0 to timeout
goto Loop ;

;A/D Channel 0

movlw B'00000000' ;Focs/2, A?D enabled, Sample channel 0
bsf ADCON0,GO ;Start A/D conversion for channel 0

Wait btfss PIR1,ADIF ;Wait for conversion to complete
goto Wait

;A/D result needs to be written away to a memory space.
movf ADRESH,Iin ;Write A/D result to 22h

movwf PORTD ;LEDs
bcf PIR1,ADIF ;Clear the completion flag

Als iemand mij zou kunnen vertellen hoe ik de ADC kan instellen voor 8-bits, zou ik dit erg op prijs stellen. ik heb in de datasheet gezocht, maar kan het niet vinden. (het moet wel kunnen voor zover ik kan zien, maar kan nergens vinden hoe ik dit zou moeten programmeren)

Ik meen dat het met de avr (mega88 in dit geval) wél kan. Heb er wel eens iemand over gehoord, zou ik de datasheet moeten staan.
Heb er zelf geen ervaring mee, maar misschien kun je iets met de mega88?
edit:
Ik moet eerlijk toegeven dat het van mijn kant een beetje een klok/klepel verhaal is, maar misschien helpt het je wat op weg

Als je geen hoge preciesie nodig hebt, kan je de 2 least significant bits verwaarlozen, dan past het wel.

De adc kan niet in 8bits mode bij een 877a.

Je moet er gewoon voor 2 lsb's laten verdwijnen. Dus delen door 4 of bitshiften.

Anders opslaan in 2 geheugen plaatsen.

Een tip voor het adc gebruik. Het is verstandig om altijd 10 metingen te doen en daar het gemiddelde van te nemen. Dat heb je minder last van ruis in je metingen >> hogere precisie. Precisie lijkt mij in dit geval niet al te belangrijk omdat je maar 8bits wilt gebruiken.

Niet te moeilijk denken. Gebruik "justify left", zie datasheet, en laat de 2 minst significante bits (die er toch al automatisch af vallen) gewoon in het ADRESL register staan. Je 8 bit resultaat staat in ADRESH

Precisie is inderdaad niet zo'n heel groot punt. (in ieder geval, nog niet) willen eerst dat het ding werkt, daarna kan het altijd nog mooier gemaakt worden.

War ik er nu van begrijp, verdwijnen op de mannier waarop het nu staan gewoon de 2 lsb's. en zou het dus moeten werken zo?

Ok, sinds vanmorgen gebruiken we een andere Microcontroller voor ons project. een 18F4550 (ipv de 16F877A) omdat deze een hardware multiplier heeft.
het programma blijft voor zover ik kan zien hetzelfde, alleen hoeft ik nu niet meer te bankswitchen. (zelfs de pootjes die we in gebruik hebben zitten op dezelfde plaatsen. )

anyways, Ik zit nu nog met 1 probleem. Ik heb het ingangs vermogen gemeten, en opgeslagen in een memory space. (er van uit gaande dat het werkt)
bij de volgende cycle, meot de microcontroller weer een waarde berekeken. en moet hij deze vergelijken met de waarde van de vorige cycle (kijken, is het groter of kleiner geworden)
Ik zit er nu dus mee, hoe kan ik een
if( argument1 > argument2 )
{
doe dit
}
else
{
doe dat
}

in assembler zetten?

Ik heb mijn hele programma al in assembler staan. en ben zelf nog totaal niet handig met microcontroller (of programmeren in het algemeen) dus 'even' alles opnieuw doen in C is nog geen oplossing. (ik heb gehoord dat deze microcontroller C aan kan, en de 16F's kunnen dat volgens mij niet)

Gr.
Tim

hmm wat ik me afvraag: in de atmel kun je volgens mij zelf bepalen hoe je de 10 bit waarde uitgelijnd wilt hebben

je had dan ook alleen de hoogste byte uit kunnen lijnen, als je alleen de eerste 8 bits nodig had.

van ASM heb ik weinig verstand, maar een uC kan nooit C aan,a lelen een hex code. Alleen om die hex code te geenreren heb je compilers.

dat kan een ASM compiler zijn, een C compiler, een JAL compiler of een basic compiler of whatever voor compiler.

Die compiler moet wel bij je processor passen

zoals ik al zei, heb er (nog) niet veel verstand van.
Ik gebruik MPLab, daarmee kan ik dus in asm programmeren. maar blijkbaar ook in C18 (of hoe doe compiler ook heet) wat dus C was voor zover ik tot nu toe begrepen heb. anyways, als iemand mij kan vertellen hoe ik groter dan (etc) statements kan programmeren in asm, zou ik dit erg op prijs stellen. :)

Op 18 december 2008 14:18:15 schreef Klamath:Ik zit er nu dus mee, hoe kan ik een
if( argument1 > argument2 )
{
doe dit
}
else
{
doe dat
}

in assembler zetten?

De 18F heeft daarvoor de instructie CPFSEQ/GT/LT.


    movf  arg1, W
    CPFSGT arg2
    bra not_greater
;greater
;
    bra _klaar
not_greater
;
;
_klaar

misschien heb ik het gemist, maar welke PIC gebruik je?

C18 werkt alleen met PIC18xxxxx chips, niet met bijvoorbeeld een 16F88, daarvoor meot je idd in assembler schrijven of een andere IDE+compiler gebruiken (sourceboost/HITECH-C) om maar eventjes wat te noemen, er is uiteraard ook nog altijd BASIC, maar daar heb ik geen ervaring mee :-)

Wat betreft je probleem, kan ik niet heel erg veel nuttigs aan toevoegen (16-bit core assembler is HEEL erg anders dan de 8bitters :P >_<

We hadden eerst een PIC16F877A in gebruik. maar deze kon niet vermenigvuldigen. (volgens de leerar. het kon wel, via een algoritme, maar dit was redelijk moeilijk, en erg sloom ) dus zijn hebben we nu voor ons project een PIC18F4550. maar gezien ik het hele programma al in assembler heb staan, zou ik graag de rest ook in assembler willen doen. mocht dit niet kunnen/lukken moet ik maar overstappen op C.

Moeilijk algoritme?


    movf Variabele, W       // waarde X
loop:
    addwf Variabele,W       // Tel op met X
    btfsc STATUS,C          // waarde > 8 bits, overflow
    incf  VariabeleH        // Overflow register verhogen
    decfsz Multiplier,f     // Doe dit Y aantal keer
    goto loop

Beetje zoals, tel de variabele (multiplier) keer met elkaar op.

Uiteindelijk beland de MSB in VariabeleH en de LSB in Variabele.

Maar goed, het kost je wsl wel een pak meer tijd dan een hardware multiplier :)

kunt u mij mischien een if/else statement met een groter dan op deze mannier geven? (of alleen zeggen hoe ik het zou kunnen maken? )

met het vermenigvuldigen ging het er ook om, dat we de PWM output op 150kHz hebben lopen. dus de berekening mag niet te lang duren, want dan redden we dat niet.

Volgens mij had ik je dat gegeven.
Maar misschien is het slim om eerst eens de instructieset van de 18F door te lezen en je te verdiepen in wat die allemaal meer kan dan de 16F.

sorry! zie nu inderdaad dan MOVF commando.. Ik dacht dat dat voor C was. bedankt, Ik zal dit proberen. :)

lang geleden dat ik assembler las en dacht dat het C was...;)