hello.
bij gebrek aan fatsoenlijke onderdelen deze vakantie, ben ik gaan dummy-proggen. ( TNT wil niet bezorgen bij ons)
iets bedenken, wat je niet gaat bouwen maar zo bedenken dat je iets nieuws moet leren. in dit geval A.D en interrupts.
en het was ook behoorlijk leerzaam, moet ik toegeven.

het bedachte project is zo:

men neme een PIC12F675 ( A/d is cruciaal)

het project zit zo:
op pin 4, GPio.3, zit een signaalbron. als deze hoog is, moet de PIC geactiveerd worden, iets uitvoeren zolang de poot hoog is.
wordt hij laag, gaat ie in sleep mode.
( want daarna staat ie iets van 12 uur uit.)

het uitgevoerde programma ziet er zo uit:

interrupts worden uitgeschakeld. pin 3 ( GPio.4) wordt hoog gemaakt, waana de spanning op pin 6 ( AN1/ GPio.1) langzaam oploopt tot 5V.
als hij er bijna is, dat hoeft niet precies te zijn ofzo, moet GPio.4 uitgeschakeld worden. GPio.5 wordt aan geschakeld, waardoor de spanning op AN.0 stijgt. ondertussen, daalt de spanning op AN1, door het uitzetten van GPio.4.

als de spanning op AN0 bijna bij 5V is, gaan GPio.4 en GPio.2 aan en blijft GPio.5 aan.
de spanning op AN1 neemt toe omdat GPio.4 aan staat.
de spanning op AN0 blijft gelijk want GPio.5 gaat niet uit.

als de spanning op AN1 bijna 5V is, gaan GPio.4 en GPio.5 uit. GPio.2 bijft aan.
als de spanningen op AN1 en AN0 laag zijn geworden, gaan ook GPio.2 uit en begint het boeltje overnieuw.

als dan het activeringssignaal uit gaan op GPio.3, moet de PIC weer in sleep mode schieten.

hele lap text, nu het progje.

DEVICE 12F675                 ; picje
CONFIG INTRC_OSC_NOCLKOUT,_   ;Interne RC Oscillator van de PIC gebruiken
       WDT_OFF,_              ;Watch Dog Timer uitgeschakeld
       PWRTE_ON,_             ;PoWeR up Timer Enable ingeschakeld
       BODEN_OFF,_            ;Brown Out Detection ENable uitgeschakeld (minder stroomopname)
       MCLRE_OFF              ;Master CLeaR Enable uitgeschakeld (pin GPIO.3)

Ansel        %01110111        ; interne osc- alleen AN3 buiten gebruik
trisio       %00001011        ; GP 3,1,0 zijn input
WPU          %00000000        ;geen pullups intern
IOC          %00000000        ; alle interrupts uit
CMCON = 7                     ; Comparators uit 
adcon0.6 = 0                   ; AD reference is Vdd
adcon0.7 = 0                   ; left justified
                               ; 10 bits resultaat


DIM ValueG as word             ; variabele voor ADIN van pin AN1
DIM ValueB as word              ; variabele van ADIN van pin AN0


intcon.7 = 0                   ; disable alle interrupts

routine:                      ; dit gebeurt nadat de boel wakker is en zolang gpio.3 hoog is
While GPio.3 = 1
    high gpio.4                ; opstarten groen-rood soms nog aan
         while valueG < 950    ; zolang AN1 onder de 4.65 volt blijft
               delayms 500
                Valueg = adin 1  ; kijken of dat nog zo is
                delayms 500
         wend                 ;einde delayroutine  --[VANAF HIER ONGEVEER HETZELFDE]--

    low gpio.4                 ; uit groen
        valueG = 0             ; lege variabelen
        valueB = 0
    high gpio.5                   ;startup blauw
         while valuegB < 950
              delayms 500
              ValueB = adin 0
              delayms 600
         wend
    high gpio.4                   ; startup groen
         valueG = 0                    ; lege variabelen
         valueB = 0
    high gpio.2                   ; startup rood
         while valuegG < 950
               delayms 500
               Valueg = adin 1
               Delayms 600
         wend                      ;wachten groen 100%
     
     low gpio.4
     low gpio.5
         while valuegG < 950 and valueB < 950
               delayms 500
               Valueg = adin 1
               Delayms 600
         wend  
     low gpio.2

clear
wend                          ; einde routine: Gpio.3 is laag geworden. 

Intcon.0 = 0                  ;GPIF nu laag: moet gecleard
intcon.7 = 1                  ; algemene interrupts toegestaan
ioc.3 = 1                     ; nu mag alleen GPio.3 interrupten
sleep                         ; slaap lekker

End                           ; voor de vorm

met alle commentaar, dit is vast een hele lange post :)

dus de vraag is:

-werkt het?
- heb ik de interrupts en A/D 's goed gedaan?

-Waar is ADIN?
-Wat is nu eigenlijk je IRQ routine?
-HIGH en LOW afleren, die instructies vreten veel te veel tijd.

de ADIN's staan meestal weergeven als [variabele] = ADIN[poort]

uit dat iu vraagt waar de interrupt routine zit blijkt al dat ik hem niet goed gedaan heb...

dit is hem


-- hier begint het programma na aansluiting van V+ (en sleep?)

prog:

intcon.7 = 0                   ; disable alle interrupts

while 
[ rest van het programa  ] 

wend                          ; einde routine: Gpio.3 is laag geworden. 
 
Intcon.0 = 0                  ; GPIF nu laag: moet gecleard
intcon.7 = 1                  ; algemene interrupts toegestaan
ioc.3 = 1                     ; nu mag alleen GPio.3 interrupten
sleep                         ; naar sleep
goto Prog                     ; terug naar af

Op 4 mei 2010 20:00:51 schreef Henry S.:
-HIGH en LOW afleren, die instructies vreten veel te veel tijd.

Huh? Dat snap ik niet. Wat ik nog van de PIC architectuur weet is dat deze een set-bit/clear-bit instructie hebben. dus dit zou toch naar een 2 cycles kostende instructie vertaald moeten worden?

High, Low en Toggle doen meer dan dat.
Voorbeeldje met een 16F628A:


High PortA.1

Bsf STATUS,5
Bcf TRISA,1
Bcf STATUS,5
Bsf PORTA,1

En nu eens met


PortA.1=1

Bcf STATUS,5
Bsf PORTA,1

HIGH, LOW en TOGGLE werken lekker makkelijk voor beginners, je hoeft je niet druk te maken of de poort al is ingesteld als in- of uitgang, het gebeurt automatisch.

Toch zitten er nadelen aan het gebruik van deze 3 commando's.
Iedere keer als je in je programma weer een HIGH, LOW of TOGGLE commando plaatst, wordt de poort steeds weer omgezet naar uitgang, ook als deze al eerder als uitgang was ingesteld.

http://www.picbasic.nl/beginners3.htm

@TS:

Ik heb de ADin's gevonden, maar normaal lees je eerst een analoge waarde in, niet halverwege. Bij je eerste test is ValueG (wat een naam... net als de rest, maakt het eens leesbaar met duidelijke namen, ook je poorten) onbepaald (in principe 0 maar ga daar niet van uit).
Dan de Delays rond ADin, veel te lang, waarom?

De IRQ, ook deze staat op een onlogische plaats. Nu past het in in stroomlijn maar maak er geen gewoonte van het zo te doen!

Programmastructuur in het algemeen, onduidelijk. Je beschrijving helpt een beetje maar niet veel omdat je programma te abstract is.

Verder is het handiger, en hier ook wenselijk, om beide analoge ingangen continue te pollen.

while valuegG < 950 and valueB < 950
               delayms 500
               Valueg = adin 1
               Delayms 600

Deze while zal oneindig duren als valeuB < 950 is.
ADIN is zelf al een korte delay omdat de functie pas klaar is als de AD converter klaar is. HEt is me niet duidelijk waarom er 2 delays zijn. 1 is eigenlijk al onnodig.
JE wilt hier de CPU net zo lang laten wachten todat er extern iets gebeurt waardoor je boven de 950 komt maar eigenlijk ook niet langer dan dat. Als dat signaal er 320mS overdoet dan nog laat je de cpu 1100ms wachten toraal. Als je een bepaalde vertraging verwacht kan je die beter voor de while zetten.

[Bericht gewijzigd door benleentje op (55%)]

het programma is heel traag. van 4.5V naar 4.6V zal iets van 4 seconden duren.

en omdat het met licht werkt ( geen accurate sturingen iod.)
zal het verschil van 1s geen groot verschil laten merken denk ik zo..

verder klopt de interrupt cyclus wel?

[ tweede bijkomende vraag... is er een taal waarbij je rechtstreeks die registers kunt aanspreken, dat vond ik wel zo lekker gaan.
dat je gewoon typt

[adres] 10011011
[adres2]01100101

dat zij wel mooi zijn.]

Op 7 mei 2010 11:11:40 schreef TechnOoB12:
[ tweede bijkomende vraag... is er een taal waarbij je rechtstreeks die registers kunt aanspreken, dat vond ik wel zo lekker gaan.
dat je gewoon typt

Uiteraard, met assembler kan je direct de instructies ingeven die hij zo zal uitvoeren. Zie hiervoor de code van henry s. bijvoorbeeld.

En dat kan je ook direkt in Picbasic doen, en onbewust doe je dat vaak al een beetje.


TRISB = %00001111

Dit is een registerinstelling. In assembly (16F628A) wordt dat:


Movlw 15
Bsf STATUS,5
Movwf TRISB

Je zit dus al heel dicht bij de assembly, alleen hoef je je niet druk te maken over eventuele banken (zoals in dit 16F628A voorbeeld).

Maar je mag dit ook rechtstreeks als assemblyregels in Picbasic plaatsen, inline assembly wordt direkt overgenomen.

Dit is handig bij routines die je precies wilt timen zonder elke keer weer de compiler output te bekijken.

hm.
dan houdt ik het nu nog even bij picbasic, totdat ik assembly tutorials gedaan heb.
registerinstellingen doe ik dan nu in picbasic op deze manier.

de interrupt is dus wel goed geplaatst.
dan begrijp ik dat in ieder geval..

over die onlogische plaats, wat is een betere plaats voor de irq routine?

IRQ's zet je buiten je hoofdprogramma, het liefst tussen alle definities en je hoofdprogramma.

ok, bedankt. ik zal ervolgende keer op letten.