I alla fall. Jag har kopplat upp en PIC16F84A med 2 st dioder på utgångarna RA1 och RA2. På RA3 har jag kopplat ena fasen från en optisk resolver som ger 400 pulser per varv. En kristall på 6 Mhz med vidhängande kondingar hittade på en gammal skrivare fick bli oscillator. Driver både resolver och µC gemensamt med 5 V från ett gammalt nätaggregat från en skrotad PC . Övriga pinnar hänger löst.
Att det blev en resolver (optisk givare med 2 fasförskjutna utgångar) som input beror på att den ska ingå i mitt styrsystem till rodermaskineriet på båten, tids nog.
Ja, jag vet. 16F84 är en antikvitet och det finns MYYYCKET bättre och billigare alternativ. Men jag fick ett ryck att komma igång snabbt, hade ett par sådana liggande från något skrotat stuff. Jag fick ett par modernare µC av en hygglig person här på forumet som jag senare ska ta mig an, men dom passar inte i min Willem programmerare utan en adapter och den har jag inte tillverkat ännu. En annan fördel med 16F84 är att databladet är ganska tunt och det är ingen nackdel så här i börja vill jag tro.
Nu till programmeringen. Jag har först gjort ett pytteprogram för att se att upplägget funkar. När jag vrider på resolvern sakta så vill jag att dioderna ska blinka omväxlande i samma takt som insignalen växlar. Voila! Det funkar utan problem.
Ja vet att ni som kan detta undrar varför jag gör det hela med sampling i stället för att använda avbrottshanteringen. Min orsak är att jag vill ta det där med avbrottshantering lite senare, när jag blivit varmare i kläderna. Kanske hade varit lättare att lösa med avbrott, men nu får jag tillfälle att nöta in alla kommandon och använda debuggern ganska intensivt. Det är med avbrott jag tänker lösa det hela i slutändan.
Nu när jag vet att det funkar rent elektriskt så har jag ökat på med att försöka få till det så att en diod tänds och förblir tänd i 255 pulser för att sedan släckas och förbli släckt i 255 pulser. I verkligheten ska det vara tvärs om på den skarpa versionen, en puls in ska ge ett antal fler pulser ut, men jag testar så här för i det andra fallet blir det svårt att vrida resolvern så sakta att pulserna syns.
Problemet är att detta program funkar inte alls som jag tänkt. Det fungerar i debuggern precs som jag vill, men när jag provar i skarpt läge så händer följande:
Trots att jag överhuvudtaget inte manipulerar RA2 (tro jag) så tänds den dioden ibland direkt vid spänningspåslag. Ibland tänds RA1 och RA2 unisont och ibland bara RA1. I det läget kan jag snurra på resolvern hur mycket som helst, inget händer. I vissa enstaka fall när ingen diod tänds vid spänningspåslag kan jag tända Ra1 om jag snurra på resolvern uppskattningsvis 255 pulser (precis som tänkt) men den släcks därefter aldrig. Ibland kan båda dioderna vara släckta och inget reagerar på resolverpulserna.
När jag kör i debuggern så togglar jag RA0 med stimulus som får agera resolver och det funkar perfekt. Laddar jag in det första programmet som växelvis blinkar så funkar allt normalt igen.
Programmet jag totat ihop kan med all säkerhet göras oändligt mycket smartare med mindre kommandon, men som sagt det är bra med mycket kommandon för att nöta in dom snabbt. Att det inte är särskilt smart programmerat betyder ju inte att det inte ska funka i verkligheten om det funkar i debuggern (tycker jag) Men förmodligen så finns det något kardinalfel i själva tänket. Det är där själva tröskeln ligger.

Här kommer det lilla program som funkar:
Kod: Markera allt
processor 16F84A
include p16F84.inc
__config _XT_OSC & _WDT_OFF & _PWRTE_ON
;******** set port A0 till input A1 till out******
bsf STATUS,5 ;Gå till Bank 1
movlw 01h ;flytta in till arbesregistret
movwf TRISA ; set portarna
bcf STATUS,5 ;Gå tillbaka till Bank 0
;**********här börjar programmet *****************
start
btfsc PORTA,0 ;kolla om port A1 är noll
call ledOn ;om inte, tänd led
btfss PORTA,0 ;kolla om port A1 är ett
call ledOff ;om inte, släck led
goto start ;börja om
;*************** subrutiner *******************
ledOn
movlw b'0100' ;TÄND LED2
movwf PORTA
return
ledOff
movlw b'0010' ;TÄND LED2
movwf PORTA
return
end
Kod: Markera allt
processor 16F84A
include p16F84.inc
__config _HS_OSC & _WDT_OFF & _PWRTE_ON
;********* konstanter********
COUNT equ 08h
OLDINP equ 0Ah
LOCK equ 0Bh
;******** set port A1 till input resten till out******
bsf STATUS,5 ;gå till Bank 1
movlw 01h ;
movwf TRISA ;set port A0 till input och A1 till output
bcf STATUS,5 ;gå tillbaka till Bank 0
bcf OLDINP,1 ;sätt OLDINP,1 till noll från start reolver=1
bcf OLDINP,0 ;sätt OLDINP,0 till noll från start resolver=0
movlw b'11111111'
movwf COUNT
;**********här börjar programmet *****************
start
btfss PORTA,0 ;resolver =1 ?
goto kollaInp0 ;resolverslinga 0
;**********här körs slinga för resolver=1*****************
bcf OLDINP,0 ;släpp slinga 0 ett varv (den låser sig själv)
btfsc LOCK,1 ;kolla om slingan resolver=1 är låst
goto start ;Skip if clear
bsf LOCK,0 ;lås slinga 0 (nu kör vi bara slingan resolver=1)
btfsc OLDINP,1 ;kolla om OLDINP=1 (väntar på en resolvernolla)
goto start ;om OLDINP=1, börja om från start
bsf OLDINP,1 ;sätt OLDINP till 1
decfsz COUNT,1 ;minska COUNT med 1
goto start ;om COUNT är större än 1, börja om från början
call ledOn ;om COUNT är 0 hoppa till ledOn
;********** här är slingan för resolver=0**************
kollaInp0
bcf OLDINP,1 ;släpp slinga 1 ett varv (den låser sig själv)
btfsc LOCK,0 ;kolla om slingan resolver=0 är låst
goto start ;Skip if clear
bsf LOCK,1 ;lås slinga 1 (nu kör vi bara slingan resolver=0)
btfsc OLDINP,0 ;kolla om OLDINP2=0
goto start ;om OLDINP=1, börja om från start
bsf OLDINP,0 ;sätt OLDINP till 1
decfsz COUNT,1 ;minska COUNT med 1
goto start ;om COUNT är större än 1, börja om från början
call ledOff ;om COUNT är 0 hoppa till ledOff
;********** Nästa varv ********************
goto start ;börja om
;*************** subrutiner *******************
ledOn
movlw b'0010'
movwf PORTA ;sätt port A1 hög
bsf LOCK,1 ;lås slinga resolver=1
bcf LOCK,0 ;lås upp slinga resolver=0
return
ledOff
movlw b'0000'
movwf PORTA ;sätt port A1 låg
bcf LOCK,1 ;lås upp slinga resolver=1
bsf LOCK,0 ;lås slinga resolver=0
return
end