mekatronik är nöjd med hjälpen
mekatronik 143
Postad: 11 dec 2021 10:27

Assembler programmering - 7 segment display

Hej, jag skall konstruera en 7 segment display som skall visa talen 0-9 decimalt och sedan skicka värdet 79 (hexadecimalt) till displayen för att sedan visa ett stort E (error) för tal som är ogiltiga (tal högre än 9).

Jag har lyckats med att skapa sekvensen där displayen visar 0-9 men lyckas inte få till så den också visar error, detta är min kod som jag använt;

Vi får endast lägga till 2 rader till på den här koden så jag kan inte lägga till hur mycket som helst.

Utgår från en FLIS Processor där jag använder dessa koder: http://www.cse.chalmers.se/edu/year/2014/course/EDA216/FlisProcessorHandbok-A4.pdf

Vet någon hur jag bör göra?

Peter_ 103
Postad: 11 dec 2021 11:02

Segmentkoden är siffrorna 0-9 på displayen. Skriv upp respektive tal binärt så kan du klura ut vilken kod som blir E.
Börja med det.

mekatronik 143
Postad: 11 dec 2021 11:06
Peter_ skrev:

Segmentkoden är siffrorna 0-9 på displayen. Skriv upp respektive tal binärt så kan du klura ut vilken kod som blir E.
Börja med det.

Hej,

Den biten är redan färdig, alla tal som du ser är konverterade från binärt till hexadecimalt. Den hexadecimala koden för E är 79 så det vet jag redan. Vet bara inte hur jag skall koda in villkoret i programmet, om jag stoppar in det i tal serien kommer den bara tolka det som att "nästa tal är E" men den skall alltså då förstå att för alla tal högre än 6F hexadecimalt (9 decimalt) skall den visa E.

Programmeraren 2191
Postad: 11 dec 2021 11:17 Redigerad: 11 dec 2021 11:18

Kan du inte bara lägga till SEG_ERROR sist i listan "Segmentkod" och definiera error som kod $0A? Eller ska error visas för alla settings på dip-switchen som inte är 0-9?

CMPA, måste den inte ha ett argument? Eller är det början på din kod för att kontrollera om dip-switchen har värde >9? Verkar i så fall som en bra början, om A är större än 9 sätter du utporten till SEG_ERROR och hoppar över uppslaget i listan "Segmentkod".

mekatronik 143
Postad: 11 dec 2021 11:21
Programmeraren skrev:

Kan du inte bara lägga till SEG_ERROR sist i listan "Segmentkod" och definiera error som kod $0A? Eller ska error visas för alla settings på dip-switchen som inte är 0-9?

CMPA, måste den inte ha ett argument? Eller är det början på din kod för att kontrollera om dip-switchen har värde >9? Verkar i så fall som en bra början, om A är större än 9 sätter du utporten till SEG_ERROR och hoppar över uppslaget i listan "Segmentkod".

Precis, den skall visa error på dipswitchen för alla tal som inte är 0-9, dock kan displayen inte visa tal med tecken, den fungerar såhär: https://tams.informatik.uni-hamburg.de/applets/hades/webdemos/00-intro/05-switches/hexswitch.html

CMPA skall ha ett argument, dock så vet jag inte vad jag skall skriva där men den displayen skall visa precis som du beskrev det, dock vet jag inte vilka koder och vart jag skall skriva in det.

Programmeraren 2191
Postad: 11 dec 2021 11:32 Redigerad: 11 dec 2021 11:32

CMPA sätter flaggorna så om du jämför med 9 eller 10 kan du brancha (BGE kanske) iväg till kod som laddar in SEG_ERROR i A och lagrar på SEGMENT7 och sen hoppar tillbaka till loopen.

Strunta till att börja med om det blir 2 eller 5 rader, du vill ha logiken rätt först sen kan man optimera.

mekatronik 143
Postad: 11 dec 2021 11:41 Redigerad: 11 dec 2021 11:41
Programmeraren skrev:

CMPA sätter flaggorna så om du jämför med 9 eller 10 kan du brancha (BGE kanske) iväg till kod som laddar in SEG_ERROR i A och lagrar på SEGMENT7 och sen hoppar tillbaka till loopen.

Strunta till att börja med om det blir 2 eller 5 rader, du vill ha logiken rätt först sen kan man optimera.

Jag testade att sätta decimalt 10 för att jämföra med tal sekvensen och sedan BGE SEG_ERROR, dock så funkade det inte. 

Jag vet inte riktigt hur man lägger in villkorliga koder, CMPA skall vara 10 då den jämför vilken position sen är i talsekvensen och ifall det är högre än 10 då skall den visa Error, så jag förstår varför BGE skall vara där. Min metod funkade inte, den fastnade på nummer 9 och stannade där.

Programmeraren 2191
Postad: 11 dec 2021 11:46 Redigerad: 11 dec 2021 11:48

Ser ut som du branchar (hoppar) till SEG_ERROR men då lär programmet krascha, den ska ju hoppa till kod som lagrar SEG_ERROR i SEGMENT7

CMPA ser i princip rätt ut:

Z-flaggan sätts om skillnaden är noll men du vill ju veta om A är större än 9.
När jag sa "BGE kanske" menade jag principen för att ta ett beslut baserat på en flagga, du måste undersöka hur du får en flagga att sättas då A >= 10 och vilken branch-instruktion som kan hoppa iväg baserat på den flaggan. C eller V ser mer lovade ut.

mekatronik 143
Postad: 11 dec 2021 11:52 Redigerad: 11 dec 2021 11:58
Programmeraren skrev:

Ser ut som du branchar (hoppar) till SEG_ERROR men då lär programmet krascha, den ska ju hoppa till kod som lagrar SEG_ERROR i SEGMENT7

CMPA ser i princip rätt ut:

Z-flaggan sätts om skillnaden är noll men du vill ju veta om A är större än 9.
När jag sa "BGE kanske" menade jag principen för att ta ett beslut baserat på en flagga, du måste undersöka hur du får en flagga att sättas då A >= 10 och vilken branch-instruktion som kan hoppa iväg baserat på den flaggan. C eller V ser mer lovade ut.

Jag är tyvärr fortfarande lika förvirrad :/, har ingen aning om hur jag skriver in villkoret i koden

edit: C flaggan kommer lysa ifall man har en position under 10, z = 0 ifall själva position blir position 10 (9 decimalt), då skall den hoppa till error ifall c = 0 antar jag. Vet som sagt inte hur jag skall skriva in det bara då

Programmeraren 2191
Postad: 11 dec 2021 12:03 Redigerad: 11 dec 2021 12:05

Processorn har flaggor. De sätts vid en compare.

T ex om A är 5 så kommer
CMPA #5
att sätta flaggan Z=1 (för alla andra A blir Z=0). Den kommer också sätta N=0, V=0 och C=0 om A=5 (om jag tolkade texten rätt).

För att hitta "mindre än" eller "större än" är det flaggorna N eller V du vill använda. Om du har en simulator av FIPS, testa några olika fall:
LDA #10
CMPA #9

LDA #10
CMPA #10

LDA #10
CMPA #11

Och anteckna vilka värden flaggorna får i de olika fallen. Då ser du hur du kan använda dem för att sen brancha iväg om A>=10. I beskrivningen av branch-instruktionerna står det vilka fralgg-värden som gör att den hoppar eller inte.

Flaggorna är:

Edit på din edit:

mekatronik 143
Postad: 11 dec 2021 12:21

Jag kommer snart ge upp på den här uppgiften...

Det här programmet är fel, bland annat för att jag inte skall ladda A med ett värde. Förstår principen som du förklara, om man laddar A med värdet 10 och utför CMPA #9 kommer den utföra 10-9. Men den kommer ju inte gå igenom nummer sekvensen, den stannar ju bara där och kör stop på programmet.

Bransch adressen är också ett mysterium, det enda jag vet är att värdet för error är 01111001 binärt och 79 decimalt, vart programmet skall hoppa tillfälligt är jag helt förvirrad kring

Programmeraren 2191
Postad: 11 dec 2021 12:38 Redigerad: 11 dec 2021 12:44

Du ska inte ladda in en konstant i A. Då försvinner värdet du laddade från dip-switchen. Exemplet ovan var för att du skulle lära dig hur flaggorna sätts.

Logiken är:

LDA från dip-switchen
Jämför med #10
Om större eller lika med, brancha till kod sätter utporten till error-symbolen. Hoppa tillbaka till loopens början.
(Om inte så fortsätter koden med:)
Slå upp rätt sifferkod och sätt utporten till sifferkoden. Hoppa tillbaka till loopens början.

Skapa koden för att sätta error-symbolen på utporten och sätt en label på den, t ex "DisplayError". Det är den adressen som är argumentet till BCC

Visa spoiler

Om CMPA och BCC har rätt logik vilket jag inte kollar:

DisplaySeqE_1:
LDA DIPSWITCH
CMP #10
BCC DisplayError
LDA A,X
STA SEGMENT7
JMP DisplaySeqE_1

DisplayError:
LDA #SEG_ERROR
STA SEGMENT7
JMP DisplaySeqE_1

 

mekatronik 143
Postad: 11 dec 2021 13:42

Väldigt nära att få till den rätt nu, den visar alla siffror men verkar inte hoppa när man når A>9, den fryser på siffran istället nu... Jag testade lite olika bransch instruktioner men det funkade inte heller..

Programmeraren 2191
Postad: 11 dec 2021 13:47 Redigerad: 11 dec 2021 14:05

Borde det inte vara:

LDA #SEG_ERROR

Annars laddar den från minnesadressen SEG_ERROR (vilket av en slump är första adressen efter de 9 symbolerna)

mekatronik 143
Postad: 11 dec 2021 14:13
Programmeraren skrev:

Borde det inte vara:

LDA #SEG_ERROR

Annars laddar den från minnesadressen SEG_ERROR (vilket av en slump är första adressen efter de 9 symbolerna)

Nu funka den... Tack så hemskt mycket för förklaringen och tålamodet, Assembler är väldigt svårt

Programmeraren 2191
Postad: 11 dec 2021 14:17 Redigerad: 11 dec 2021 14:18

Som du ser så finns raderna som lagrar koden i utporten (samt hoppet efter) på två ställen.
För att optimera det kan du utnyttja att flaggan C inte ändras när du gör LDA.
Om du efter CMP men innan BCC laddar in felkoden i A som "default" kan du brancha till en gemensam lagringskod om A >= 10.

Visa spoiler

DisplaySeqE_1:
  LDA DIPSWITCH             : load dip switch value
  CMP #10                   : check if >= 10 --> C=0 if A>=10
  LDA SEG_ERROR             : load error symbol as default symbol
  BCC Store                 : if dipswitch value was >= 10, don't load symbol
  LDA A,X                   : come here if dispswitch < 10, load symbol 0-9
Store:
  STA SEGMENT7              : store symbol
  JMP DisplaySeqE_1         : loop

mekatronik 143
Postad: 11 dec 2021 14:33
Programmeraren skrev:

Som du ser så finns raderna som lagrar koden i utporten (samt hoppet efter) på två ställen.
För att optimera det kan du utnyttja att flaggan C inte ändras när du gör LDA.
Om du efter CMP men innan BCC laddar in felkoden i A som "default" kan du brancha till en gemensam lagringskod om A >= 10.

Visa spoiler

DisplaySeqE_1:
  LDA DIPSWITCH             : load dip switch value
  CMP #10                   : check if >= 10 --> C=0 if A>=10
  LDA SEG_ERROR             : load error symbol as default symbol
  BCC Store                 : if dipswitch value was >= 10, don't load symbol
  LDA A,X                   : come here if dispswitch < 10, load symbol 0-9
Store:
  STA SEGMENT7              : store symbol
  JMP DisplaySeqE_1         : loop

Byter du ut Store då mot DisplayError om man utgår från hela koden då? 

Programmeraren 2191
Postad: 11 dec 2021 14:35 Redigerad: 11 dec 2021 14:40

Ungefär så, kolla i spoilern ...

Man hoppar över laddningen av sifferkoden om A>=10.
För att det ska funka måste man då innan ha laddat in felkoden i A så att den finns där när man kommer till själva lagringen.
  LDA SEG_ERROR             : load error symbol as default symbol


Då behövs inte DisplayError och dess kod.

mekatronik 143
Postad: 12 dec 2021 21:37
Programmeraren skrev:

Ungefär så, kolla i spoilern ...

Man hoppar över laddningen av sifferkoden om A>=10.
För att det ska funka måste man då innan ha laddat in felkoden i A så att den finns där när man kommer till själva lagringen.
  LDA SEG_ERROR             : load error symbol as default symbol


Då behövs inte DisplayError och dess kod.

Då förstår jag, tack så mycket för hjälpen och inputen! Jag förstår assembler bättre nu

Svara Avbryt
Close