Bitshifta 16-bit tal i 8-bit PIC
Bitshifta 16-bit tal i 8-bit PIC
Hur gör man om man har ett värde som är 16-bit stor så det är uppdelat i två byte och vill bitshifta hela 16-bit talet åt vänster 4 steg?
Re: Bitshifta 16-bit tal i 8-bit PIC
u16 = ((uint16_t) (u8msb <<4))*0x100 + ((uint16_t)(u8lsb)) << 4);
eller?
eller?
Re: Bitshifta 16-bit tal i 8-bit PIC
Man kan använda sig av swapning och maskning eller rotering vänster 4 steg.
Här är kod för den första metoden, som jag googlade fram:
Den förutsätter att resultatet blir max 16 bitar. Om resultatet ska bli 24 bitar behövs några fler instruktioner.
Här är kod för den första metoden, som jag googlade fram:
Den förutsätter att resultatet blir max 16 bitar. Om resultatet ska bli 24 bitar behövs några fler instruktioner.
Kod: Markera allt
;shift accumulator left 4 times
swapf ACC1, f
swapf ACC0, f
movf ACC0, w
andlw 0x0F
xorwf ACC0, f
iorwf ACC1, f
Re: Bitshifta 16-bit tal i 8-bit PIC
Glömde nämna att det är pic asm.TomasL skrev:Vilket språk?
Re: Bitshifta 16-bit tal i 8-bit PIC
Ja det är viktigt att veta, eftersom assemblern skiljer sig så mellan olika prollar, så en rutin skriven för en processor-typ funkar inte för en annan.
Vilken Processor är det? och specifikt vilken assembler, då det finns ett antal olika.
Vilken Processor är det? och specifikt vilken assembler, då det finns ett antal olika.
Re: Bitshifta 16-bit tal i 8-bit PIC
Det beror också på hur hårt optimerad kod man vill ha.
Just när det gäller *4* bitar (eller 8, så klart), så finns
det ett par genvägar att ta, så som bearing visade.
Gäller det ett mer generellt fall så får man göra mer
"som vanligt", d.v.s shifta varje bit genom C-biten.
> ...Vilken Processor är det? och specifikt vilken assembler, då det finns ett antal olika.
"8-bit PIC" ger ju inte *så* många alternativ.
Jag tror att bearings kod fungerar på både PIC16F, PIC16F1xxx och PIC18F.
Just när det gäller *4* bitar (eller 8, så klart), så finns
det ett par genvägar att ta, så som bearing visade.
Gäller det ett mer generellt fall så får man göra mer
"som vanligt", d.v.s shifta varje bit genom C-biten.
> ...Vilken Processor är det? och specifikt vilken assembler, då det finns ett antal olika.
"8-bit PIC" ger ju inte *så* många alternativ.

Jag tror att bearings kod fungerar på både PIC16F, PIC16F1xxx och PIC18F.
Re: Bitshifta 16-bit tal i 8-bit PIC
Om det är exakt 4 bitar som skall skiftas funkar det bra med swap-funktionen ihop med lite maskning och move.
Vill man skifta annat antal kan man använda rotering via carry-flaggan ett skift-steg åtgången och med hjälp av carry-flaggan flytta över eller kasta bort en bit åt gången.
Och göra en subrutin av detta som anropas önskat antal gånger.
Vill man skifta annat antal kan man använda rotering via carry-flaggan ett skift-steg åtgången och med hjälp av carry-flaggan flytta över eller kasta bort en bit åt gången.
Och göra en subrutin av detta som anropas önskat antal gånger.
Re: Bitshifta 16-bit tal i 8-bit PIC
Om processorn har nån snabb 8x8=>16 bitars hårdvarumultiplikation så kanske det går snabbast att bara multiplicera med 16.
Har inte så bra koll på PIC:ar men har för mig det fanns en två-cyklers multiplikationsinstruktion på AVR:erna iaf.
Har inte så bra koll på PIC:ar men har för mig det fanns en två-cyklers multiplikationsinstruktion på AVR:erna iaf.
Re: Bitshifta 16-bit tal i 8-bit PIC
Om det är till esic_clonen och stödet för DS1820 så har jag en fungerande version.
Det är en bitshift med 3 bitar vänster du ska göra.
Jag gör så här,
Det är en bitshift med 3 bitar vänster du ska göra.
Jag gör så här,
Kod: Markera allt
movlw .3 ; Rotate left
movwf counter
rlf TemperatureLo,f
rlf TemperatureHi,f
decfsz counter,f
goto $-3
Re: Bitshifta 16-bit tal i 8-bit PIC
Notera att en "rotate" kommer att "rotera" in de högsta bitarna
från TemperatureHi till de lägsta bitarna i TemperatureLo.
Det kanske inte spelar någon roll, men annars kan man göra:
LSLF shiftar alltid in en "0" i lägsta biten och den högsta biten till "C".
Notrera att LSLF kom med den nya PIC16F1xxx, men det bör ju vara
de som man använder idag i alla fall.
Sens så, om det nu är en fast shift på 3 bitar så fungerar ju även:
Det tar 6 cykler istället för 16 cykler för lösningen med loopen.
från TemperatureHi till de lägsta bitarna i TemperatureLo.
Det kanske inte spelar någon roll, men annars kan man göra:
Kod: Markera allt
movlw .3 ; Number of bits to rotate.
movwf counter
shift_loop
lslf TemperatureLo, f
rlf TemperatureHi, f
decfsz counter, f
goto shift_loop
Notrera att LSLF kom med den nya PIC16F1xxx, men det bör ju vara
de som man använder idag i alla fall.
Sens så, om det nu är en fast shift på 3 bitar så fungerar ju även:
Kod: Markera allt
lslf TemperatureLo, f
rlf TemperatureHi, f
lslf TemperatureLo, f
rlf TemperatureHi, f
lslf TemperatureLo, f
rlf TemperatureHi, f
Re: Bitshifta 16-bit tal i 8-bit PIC
Tack sodjan.
Men OM det nu är till esic_clone som är anledningen till ankans fråga, så är pic:en en pic12f675. Där finns inte den instruktionen.
Jag ska väl också tillägga att jag gör en add 0xf8 för att nolla de inshiftade msb:arna i lägsta byten.
ankan: Ds1820 kom med posten idag. Kodade igår kväll och kunde verifiera nu innan läggning. Jag ger mig rn klapp på axeln för att det fungerade direkt
Lägger ut den ikväll om jag hinner. Du kanske löser det själv innan jag fått ut den.
Men OM det nu är till esic_clone som är anledningen till ankans fråga, så är pic:en en pic12f675. Där finns inte den instruktionen.
Jag ska väl också tillägga att jag gör en add 0xf8 för att nolla de inshiftade msb:arna i lägsta byten.
ankan: Ds1820 kom med posten idag. Kodade igår kväll och kunde verifiera nu innan läggning. Jag ger mig rn klapp på axeln för att det fungerade direkt

Lägger ut den ikväll om jag hinner. Du kanske löser det själv innan jag fått ut den.
Re: Bitshifta 16-bit tal i 8-bit PIC
Visst är det så. Blev sugen på att försöka själv också.ecenier skrev:Om det är till esic_clonen och stödet för DS1820 så har jag en fungerande version.
Det är en bitshift med 3 bitar vänster du ska göra.
Jag gör så här,Kod: Markera allt
movlw .3 ; Rotate left movwf counter rlf TemperatureLo,f rlf TemperatureHi,f decfsz counter,f goto $-3
Gjorde en switch case sats där familjekoden för 1wire enheten kollas för att sedan hoppa till enhetsspecifik kod som sedan anropar vissa gemensamma kodsnuttar och fixar temp innan sen hoppar tillbaka.
Om jag får ds1820 att funka så ska jag kolla på 1wire räknaren tänkte jag. Dock hade jag föredragit uC men känns dumt att skriva om allt.
Re: Bitshifta 16-bit tal i 8-bit PIC
Kul att det funkade.. Asm känns onödigt bökigt men vad gör man inte när koden är skrivet i det från början.ecenier skrev:Tack sodjan.
Men OM det nu är till esic_clone som är anledningen till ankans fråga, så är pic:en en pic12f675. Där finns inte den instruktionen.
Jag ska väl också tillägga att jag gör en add 0xf8 för att nolla de inshiftade msb:arna i lägsta byten.
ankan: Ds1820 kom med posten idag. Kodade igår kväll och kunde verifiera nu innan läggning. Jag ger mig rn klapp på axeln för att det fungerade direkt
Lägger ut den ikväll om jag hinner. Du kanske löser det själv innan jag fått ut den.
Men om jag bara orkar sätta in mig tillräckligt i koden så kanske jag kan porta den till uC och utveckla vidare koden för räknare tex.
Re: Bitshifta 16-bit tal i 8-bit PIC
Vad är "uC", den är ju redan skriven för en Micro-Controller (uC), bättre än att portera gammal asm, är att skriva ned en funktionsbeskrivning, och skriva det hela i C.Men om jag bara orkar sätta in mig tillräckligt i koden så kanske jag kan porta den till uC och utveckla vidare koden för räknare tex.