Dela upp en byte?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
JimmyAndersson
Inlägg: 26611
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Jag testade med din kod sodjan, men jag fick samma fel som när jag testade swap:

110:11 3 Identifier 'swap' was not declared nataggregat1.pbas
158:1 3 Identifier 'end' was not declared nataggregat1.pbas
158:1 4 Syntax error: Expected 'end' but '.' found nataggregat1.pbas
158:1 4 Syntax error: Expected 'sub' but '' found nataggregat1.pbas
158:1 4 Syntax error: Expected 'end' but '' found nataggregat1.pbas
158:1 4 Syntax error: Expected '.' but '' found nataggregat1.pbas

På rad 110 finns:
value = value and $0F

På rad 158 finns ..inget eftersom .end liggger på rad 157.

MikroBasic stödjer swap, men det verkar inte fungera i själva koden. :?

I Hjälpen står det såhär:

Kod: Markera allt

Swap

Prototype   -    sub function Swap(dim byref input as byte) as byte

Returns     -    Returns byte consisting of swapped nibbles.

Description    -     Swaps higher nibble (bits <7..4>) and lower nibble (bits 
<3..0>) of byte-size parameter input.

Example:
PORTB = $F0
PORTA = Swap(PORTB)  ' PORTA = PORTB = $0F

Med min kod som använde shift får jag inga felmeddelanden, men det fungerar inte. Skickar jag:

Kod: Markera allt

  lcd_skriv(86) 'V
  lcd_skriv(79) 'O
  lcd_skriv(76) 'L
  lcd_skriv(84) 'T
  lcd_skriv(58) ':
  lcd_skriv(32) 'Mellanslag
Så är displayen tom, syns ingen blinkande markör. Om jag skickar lcd_skriv(66) så syns det inget B men markören blinkar på teckenposition nr3 på andra raden.

LCD'n är inkopplad såhär:
PORTC.0 - D4 (LCD)
PORTC.1 - D5 (LCD)
PORTC.2 - D6 (LCD)
PORTC.3 - D7 (LCD)
PORTC.4 - RS (LCD)
PORTC.5 - E (LCD)

Vad kan kan se i debuggern så hamnar bitarna på rätt ställe i PORTC.
Senast redigerad av JimmyAndersson 12 augusti 2006, 16:08:29, redigerad totalt 1 gång.
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Är displayen initierad korrekt? Är RS-pinnen satt i rätt läge?

sodjan: Givetvis är swap eller bitshift den bästa lösningen. MEN, problemet går ju även att lösa genom att dividera med 16! I det fallet har man ju löst det matematiskt, genom heltalsdivision :!:

Edit: Råkade skriva R/W men jag menade RS...
Användarvisningsbild
JimmyAndersson
Inlägg: 26611
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Jodå, displayen är rätt initierad. Om jag struntar i skriv_lcd-grejjen och bara skriver:

PORTC.3 = 0 'D7
PORTC.2 = 1 'D6
PORTC.1 = 0 'D5
PORTC.0 = 0 'D4
lcd_vanta
PORTC.3 = 0
PORTC.2 = 0
PORTC.1 = 0
PORTC.0 = 1
lcd_vanta

så visas ett A.

rutinen för lcd_vanta ser förresten ut såhär:

Kod: Markera allt

sub procedure lcd_vanta
  delay_us(1000)
  E = 1
  delay_us(1000)
  E = 0
  delay_us(1000)
end sub
Användarvisningsbild
lgrfbs
Inlägg: 7350
Blev medlem: 28 januari 2005, 15:48:53
Ort: X-län
Kontakt:

mikroBasic Ver: 5.0.0.0

Inlägg av lgrfbs »

* Gå till: MikroBasic
* Titta under "Download" / "Current version" eller "Updates and Patches"
* Vid problem se "Support" & Forumet om du lägger ut ditt problem
där kan du få riktiga svar på varför mikroBasic beter sig konstigt eller
vad det nu rör sig om
Användarvisningsbild
JimmyAndersson
Inlägg: 26611
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Tack!

Upptäckte just en grejj:
Om jag skickar lcd_skriv(66) så visas inget B. Men däremot ställer sig som sagt markören i rad 2, position 3. Dvs 42 hexadecimalt.

66 (decimalt) är ju 42 i hex!

Hm... RS är hög i koden.

edit: Äh, jag kom på det. Det var nästan pinsamt lätt. RS blir ju 0 när jag skickar till hela PORTC.

edit 2: Jag måste hitta på något som bara skickar till PORTC.3 - 0. Annars kommer det aldrig gå.

Ska komma på någon lösning för det, men ni får hemskt gärna ge förslag.


Funderar på om jag försöker lösa detta på fel sätt. Vad tycker ni?
Det jag försöker göra är att hitta ett enkelt sätt att kunna skriva text och innehållet i variabler till LCD'n.
Användarvisningsbild
Xyzzy
Inlägg: 1278
Blev medlem: 30 januari 2004, 22:31:07
Ort: Uppsala, Sweden

Inlägg av Xyzzy »

Ett vanligt sätt är något liknande (pseudokod):

Portx = Portx & bx11110000 + data

denna kod lägger till värdet i 'data' (som måste vara <16, dvs bara de fyra minst signifikanta bitarna) till vad som finns på porten
Användarvisningsbild
JimmyAndersson
Inlägg: 26611
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Sådärja, jag OR'ade in 16 i det som skickas. Nu fungerar det fint!

Tyvärr kommer jag att få problem ändå senare, eftersom jag ska använda RX och TX som ligger på samma port. (PORTC.6 och PORTC.7)

*Ungefär* såhär har jag planerat hittils:
PIC18LF2320:
' PORTC.0 - D4 (LCD)
' PORTC.1 - D5 (LCD)
' PORTC.2 - D6 (LCD)
' PORTC.3 - D7 (LCD)
' PORTC.4 - RS (LCD)
' PORTC.5 - E (LCD)
' PORTC.6 - TX (RS232)
' PORTC.7 - RX (RS232)

' PORTB.0 - Spänning-styrning
' PORTB.1 - Ström-styrning
' PORTB.2 - Encoder 1a (Ben A på encoder nr1.)
' PORTB.3 - Encoder 1b (Ben B på encoder nr1.)
' PORTB.4 - Encoder 2a (Ben A på encoder nr2.)
' PORTB.5 - Encoder 2b (Ben B på encoder nr2.)
' PORTB.6 - Knapp 1 (T.ex bläddra i menyn eller nåt..)
' PORTB.7 - Knapp 2 (T.ex bläddra i menyn eller nåt..)

' PORTA.0 - Spänning-mätning (analog in)
' PORTA.1 - Ström-mätning (analog in)
' PORTA 2 till 7 - Lysdioder mm



Det skulle bli lite trångt att möblera om, men det kanske går om jag sätter LCD'n på PORTB. (Har lyckligtvis bara hunnit programmera LCD-delarna.)
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Så här enkelt är det om man inte tar "omvägen" genom basic. :)

Kod: Markera allt

	movf	Value,w
	andlw	b'00001111'
	iorwf	LATC
	iorlw	b'11110000'
	andwf	LATC

	swapf	Value,w
	andlw	b'00001111'
	iorwf	LATC
	iorlw	b'11110000'
	andwf	LATC
Användarvisningsbild
JimmyAndersson
Inlägg: 26611
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Det ser väldigt smidigt ut. Jag tror att jag förstår allt.

Allt eftersom mina projekt blivit större och större så har jag alltid upptäckt samma sak: MikroBasic känns begränsat och 28-pinnarna räcker nästan inte. (Det senare är enkelt att lösa.)

Jag har börjat kika lite mer på assembler, vilket kommer bli språket jag ska satsa på för (åtminstone) större projekt. Tyvärr kan jag inte särskillt många instruktioner, men troligen tillräckligt för att börja från början med blinkande lysdioder och sådant. Sedan är ju databladet en bra hjälp för att lära sig mer.

Men troligen så fortsätter jag med MikroBasic i detta projekt ett tag till. Som ni kanske gissat så håller jag på att bygga ett digitalt nätagg. Om/när det visar sig att MikroBasic gör lite för klumpig asm-kod för att det ska fungera så byter jag programmeringspråk och då blir detta mitt första asm-kodade projekt. :)


edit: Jag tänkte flytta LCD'n från PORTC till PORTB, men det går nog inte. Jag behöver läsa av interrupt på några pinnar och vad jag sett i databladet så finns de möjligheterna bara på RB0 - RB2. Hm, det får bli PORTA för LCD'n.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Som du säkert redan har sett av andras (och dina egna verkar det som)
inlägg, så är problemet alltså att även när du kör LCD'n i 4-bitars mode,
så skriver till alltid 8 bitar till porten.

Lösningen är att först *läsa* porten och sedan se till att enbart de 4
LCD-data pinnarna ändras (använd AND och OR på lämpligt sätt).

Om de övriga 4 bitarna i porten bl.a är RX/TX, så kanske man får
tänka till lite extra. Jag tror dock att de styrs helt från USART modulen,
så det borde inte bli någon konflikt.

Ett annat läge där det kan bli struligt, är om någon av de andra 4 bitarna
ändras i en ISR. Då kan du råka ut för följande :

- Din LCD rutin läser porten.
- Medan din LCD rutin gör sina AND/OR så inträffar ett interrupt
- ISR'en ändrar läge på en av de övriga 4 pinnarna och gör "return from interrupt".
- Din LCD rutin kör klart och skriver tillbaka till porten, och ändrar *tillbaka* det som ISR'en ändrade !

Mycket lurigt. Lösningen är att stänga av interrupt (GIE=0) med LCD rutinen kör sin känsliga del.
Det fördröjer ISR'en med 4-5 Tcy (instruktionscykler) men det är oftast helt OK.

> LCD'n är inkopplad såhär:
> PORTC.0 - D4 (LCD)
> PORTC.1 - D5 (LCD)
> PORTC.2 - D6 (LCD)
> PORTC.3 - D7 (LCD)
> PORTC.4 - RS (LCD)
> PORTC.5 - E (LCD)

Som du kanske har märkt så är det upplagt för trubbel !!
Om du inte hanterar porten rätt, så kommer RS och E att "fladdra" lite
hur som helst...
Användarvisningsbild
JimmyAndersson
Inlägg: 26611
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Inlägg av JimmyAndersson »

Det var bra och värdefulla lösningar! :)

Då verkar det alltså inte vara en urdålig idé att överhuvudtaget använda sig av kod som skriver till hela porten, trots att den delas av t.ex en LCD och RX/TX. Men det är förstås lättast/bäst om man kan undvika det. :)


Hm, nu är nog alla frågetecken uträtade för den här gången. Då återstår bara lite programmering...
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Finessen med 4-bitars mode är ju just att man kan använda
de andra 4-bitarna till något annat. Och hur som helst, dessa
finare detaljer fixar man normalt en gång, sedan ligger de dolda
i en subrutin så i *nästa* applikation har man mycket mindre jobb... :-)
Skriv svar