list p=16f84
include "P16f84.inc"

;********* Beginnen ****************
org 0x00
;****** Poort A instellen **********
BSF 03,5
CLRW
MOVLW B'00010000'
MOVWF 85h
BCF 03,5

;****** Poort B instellen **********
BSF 03,5
CLRW
MOVLW B'11111111'
MOVWF 86h
BCF 03,5

begin:
BTFSS 05h,04h ;Lees bit 4 uit adres 05h
GOTO LeastSignNibbles
GOTO MostSignNibbles
ReturnFromNibbles:
GOTO begin

LeastSignNibbles:
MOVLW 06h
ANDLW 0Fh
MOVWF 05h
GOTO ReturnFromNibbles

MostSignNibbles:
MOVLW 06h
ANDLW B'11110000' ;0F0h
MOVWF 0Ch
SWAPF 0Ch,0
MOVWF 05h
GOTO ReturnFromNibbles

END

Bedoeling is om met een vlaggetje (bit 5 van poort A) de linker of rechter nibble van PoortB uit te lezen. Echter het werkt niet...

Ik ben geen computer die bij het zien van 0x03, 0x85 of 0x0C direct weet over welk register het gaat.
Of te wel, het is een stuk handiger als je labels aan je registers verbindt.

Maar goed, na enig kijken:

Als je portA.4 = 1 maakt, springt de routine naar MSN.
Daar aangekomen laad je w met 0x06. (waarom?)
Dan maak je een AND-functie tussen deze 0x06 en b'11110000'
Uhhh..
Dat schrijf je vervolgens weg naar een adres (0x0C)

Ik denk dat je de eerste instructie in MSN moet vervangen van "MOVLW 0x06" naar "MOVF 0x06,w". Ik neem aan dat je portB wilt lezen (die zich in 0x06 bevindt..) in plaats van het getal 0x06 wilt hebben.

Hetzelfde geldt voor de eerste instructie van LSN.

Nogmaals, geef je registers LABELS!!
Dan zie je dit soort fouten volgens mij een stuk sneller.

Dank je, ik zal morgen even kijken of het wel werkt. :)

groeten,

Sindala

list p=16f84
include "P16f84.inc"

MyFavouritePortA EQU 0x05
MyFavouritePortB EQU 0x06

;********* Beginnen ****************

org 0x00

;****** Poort A instellen **********
BSF 03,5
CLRW
MOVLW B'00010000'
MOVWF 85h
BCF 03,5

;****** Poort B instellen **********
BSF 03,5
CLRW
MOVLW B'11111111'
MOVWF 86h
BCF 03,5

begin:
BTFSS 05h,04h ;Lees bit 4 uit adres 05h
GOTO LeastSignNibbles
GOTO MostSignNibbles
ReturnFromNibbles:
GOTO begin

LeastSignNibbles:
MOVF MyFavouritePortB ,w
;MOVLW MyFavouritePortB
ANDLW 0Fh
MOVWF MyFavouritePortA
GOTO ReturnFromNibbles

MostSignNibbles:
MOVF MyFavouritePortB ,w
;MOVLW MyFavouritePortB
ANDLW B'11110000' ;0F0h
MOVWF 0Ch
SWAPF 0Ch,0
MOVWF MyFavouritePortA
GOTO ReturnFromNibbles

END

Wanneer wij dit testen zien wij onafhankelijk van RA4 en RB0:RB7 op RA0:RA3 een 1. De bedoeling is dat RB0:RB3 op RA0:RA3 wordt geplaatst wanneer RA4 een 0 is. In het andere geval (RA4 = 1) dient RB4:RB7 op RA0:RA3 gezet te worden.
Ik hoop dat jullie eens naar de code willen kijken, wellicht zien jullie de fout :-).

bij voorbaat dank,

Roderik

Het is voorelkaar.

Het lag aan de pulldown weerstandjes.

Ik zie wel je fout zitten.

Je doet het volgende:
BTFSS 05h,04h ;Lees bit 4 uit adres 05h

oftwel zoals je commentaar juist aangeeft, je checkt bit 4.
Maar bij het instellen van de poortA zeg je:
MOVLW B'00010000'
MOVWF 85h

Je maakt dus van bit 5 een input en niet van bit 4. Het programma zal dus checken op een outputpin ipv een inputpin. Verder werkt je programma helemaal correct.

Dan nog een paar opmerkingen over je programma.
*Kies inderdaad labels, dit voorkomt fouten bij het schrijven, het maakt het voor jezelf overzichtelijker en het is makkelijker mocht bijvoorbeeld een waarde moeten wijzigen (dit hoef je dan alleen maar bij de equ bovenin te doen :)
Je gebruikt in je 2e geplaatste programma labels maar deze zijn wel erg lang. Labels zijn er om snel mee te kunnen werken en overzichtelijk te zijn. Een label als MyFavouritePortA is wat lang. Bij je LeastSignNibbles heb je gelukkig wel het Significant afgekort anders was die ook erg lang.
Het is maar een tip, wat jij ermee doet moet je zelf weten.
*Als je label gebruikt moet je het wel overal toepassen. Bij je BTDSS staat nog 05h ipv het label ervoor. Wees consequent!
*Voor het instellen van je poorten moet je van bank wisselen, dat doe je allemaal goed. Het is alleen onnodig om dit 2x te doen terwijl het ook in 1 routine kan.

Ik heb hieronder een aangepaste versie gezet van hoe ik de code zou maken. En de fout meteen eruit gehaald, dus als het goed is kan je dit er zo instoppen en dan werkt het wel ;)

list p=16f84
include "P16f84.inc"

PortA EQU 0x05
PortB EQU 0x06
PortAinstel EQU 0x85
PortBinstel EQU 0x86

;********* Beginnen ****************

org 0x00

;****** Poort A & B instellen **********
BSF 03,5
CLRW
MOVLW B'00001000' ;Pin RA3 (bit4) is input, rest output
MOVWF PortAinstel
MOVLW B'11111111' ;hele RB is input
MOVWF PortBinstel
BCF 03,5

begin:
BTFSS PortA, 4 ;Check bit4 van PortA
GOTO LeastSignNibbles
GOTO MostSignNibbles
ReturnFromNibbles:
GOTO begin

LeastSignNibbles:
MOVF PortB ,w
ANDLW 0Fh
MOVWF PortA
GOTO ReturnFromNibbles

MostSignNibbles:
MOVF PortB ,w
ANDLW F0h
MOVWF 0Ch
SWAPF 0Ch,0
MOVWF PortA
GOTO ReturnFromNibbles

END

[Bericht gewijzigd door Bastiaan op ]

Maar bedankt :) het werkt helemaal goed.

Ik begrijp dat het al werkt, maar ik kan het niet laten. NB voor wie dit niet weet: dit is Jal, en de Jal compiler is gratis.


include 16F84_10
port_a_direction = 0b_0000_1000
forever loop
   if pin_a4 then
      port_a = port_b & 0x0F
   else
      port_a = port_b >> 4
   end if
end loop

[Bericht gewijzigd door Wouter van Ooijen op ]

Wouter;
Voor deze toepassing is dat JAL volgens mij een perfecte oplossing om het snel foutloos te schrijven.
Ik zie 1 probleem aan compilers met een 'hogere' programmeertaal: tijd.
Kan de gebruiker van JAL ook precies zien hoe lang bepaalde stukken code duren?

De C-compiler die door Microchip wordt geleverd is geniaal, maar ook daar kun je niet zien hoeveel tijd in beslag genomen wordt door routines.
Ik blijf dus gewoon bij MPASM..

Op 12 juli 2003 15:02:04 schreef DIY:
Kan de gebruiker van JAL ook precies zien hoe lang bepaalde stukken code duren?

Nee, als je dat echt wilt zal je assembler moeten gebruiken. Maar aangezien je dit meestal maar wilt weten voor een klein deel van je code is het dan nog erg handig om de assembler statements gewoon in de Jal source te zetten. (Alle C compilers die ik ken voor PICs kunnen dat trouwens ook).

Vaak wil je trouwens niet zo zeer precies weten hoe lang een stuk code duurt. Je wilt bv een vertraging van *ten minste* een bepaalde tijd invoegen, bv voor HD44780 aansturing. Daar zijn library calls (delay) voor (die trouwens met in-line assembly zijn gerealiseerd!).

Of je wilt dat een statement precies zoveel tijd na een ander statement wordt uitgevoerd, bv voor asynch seriele communicatie. Daar zijn weer andere library calls (interval_delay) voor (geimplemnteerd mbv de timers).

Ik zeg niet dat een HLL *altijd* de oplossing is hoor, maar in mijn ervaring toch wel meestal. Heb je een tegenvoorbeeld?

Ik snap effe niet wat een HLL is, maar ik denk dat ik je vraag wel begrijp.

Stel: Ik heb een 32 kanaals 16bitA/D-kaart, met aansturing door een PIC.

Op de kaart zitten twee 16-kanaals-multiplexers, 2 DAC's en een AD-converter.
Deze hardware moet per geselecteerd kanaal ingesteld worden.(load DAC's en select een kanaal op 1 van de multiplexers)
Vervolgens wordt het geselecteerde kanaal geconverteerd.
De cyclus gaat zo door tot alle kanalen geconverteerd zijn en dan weer terug bij het eerste kanaal beginnen.

Wat is nu mijn samplefrequentie?
Juist, die is afhankelijk van mijn code-snelheid, dus moet ik van alle functies die in mijn code zitten de exacte tijd weten.
(assembly ruled!!)

Ik vereenvoudig een beetje, neem 1 16-kanaals mux voor 1 A/D. Ik wil een sample tijd van 7 ms per kanaal (7 * 16 voor alle kanalen).


   -- eenmalige instellingen
   -- stel 1e kanaal in
   init_interval_ms( 7 )
   forever loop
      await_next_interval
      -- neem sample
      -- stel volgende kanaal in
   end loop

De magie zit in de await_next_interval call, die wacht tot precies de volgende 7ms time-tick (de ingestelde tijd).

Je hebt gelijk, dit is een manier.
Maar wat ik bedoel is toch een beetje anders.

Ik wil geen vastgelegde 7ms - snelheidslimiet. (De toepassing die ik als voorbeeld noemde is zowiezo een realtime-toepassing, dus vergeet die 7ms maar..)
Verder:
Dat zou voor voor 32 kanalen op z'n minst op 7x32 = 224ms neerkomen wat een maximale samplefrequentie van 4 Hz zou betekenen.

Wat ik bedoel is: Ik schrijf mijn code voor optimale snelheid (assembly dus) en simuleer vervolgens om daar uit mijn samplefrequentie te berekenen. En juist dat laatste, daar gaat het mij om: ik wil kunnen zien hoe lang een routine duurt.
Als nu blijkt dat de samplefrequentie te laag is, zal mijn code slimmer moeten schrijven.

Verder absoluut no offense naar JAL, maar tijd is voor mij een belangrijk iets en daar wil ik controle over hebben.

Verder: ik geloof dat we een beetje Off-topic gaan..

Op 15 juli 2003 12:20:00 schreef DIY:
Wat ik bedoel is: Ik schrijf mijn code voor optimale snelheid (assembly dus) en simuleer vervolgens om daar uit mijn samplefrequentie te berekenen.

Dat lijkt me prima voor de (kleine) delen die de snelheid bepalen, maar dan zou ik dat in in-line assembly doen, en de rest van het programma gewoon in HLL.