IS1200 Exempelsamling till övning CE_O6, 2015 CE_O6. Parallell in/utmatning (I/O). Förberedelser till laboration nios2io. 6.1. Läs in data från IN-port (skjutomkopplare TOGGLES18) Skriv en subrutin, Get_Data som läser av aktuellt värde från de 18 skjutbara knapparna TOGGLES18 och levererar dem som returvärde i de minst signifikanta bitarna 17 00 i register r2. De mest signifikanta bitarna 31 18 ska vid returen vara nollställda. De skjutbara knapparna TOGGLES18 är Memory-Mapped till adressen 0x850 i de 18 minst signifikanta bitarna. a) Skriv subrutinen Get_Data i Nios-II-assemblerkod. b) Skriv funktionen Get_Data i C. c) Förklara innebörden av det reserverade ordet volatile i C. d) Fundera vad som kan hända om programmet skriver till in-porten. e) Fundera vad som händer med övriga bitar 6.2. Skriv ut data till UT-port. (lysdioder GREENLED9) Skriv en subrutin, Put_Green_Light, som skriver ut data till de 9 lysdioderna GREENLED9, som betecknas LEDG8 till LEDG0. Det värde som ska skrivas ut levereras i register r4. Vid retur ska samma värde levereras i register r2. Du ska förutsätta att en etta i register r4 tänder motsvarade lysdiod och en nolla släcker dioden. De 9 gröna lysdioderna GREENLED9 är Memory-Mapped till adressen 0xA10 i de 9 minst signifikanta bitarna. a) Skriv subrutinen Put_Green_Light i Nios-II-assemblerkod. b) Skriv funktionen Put_Green_Light i C. c) Fundera vad som händer om programmet läser från ut-porten. d) Fundera vad som händer med övriga bitar Uppgifter till övning CE_O6, sida 1 (av 5) 2015-02-06
6.3. Översätt binärt till 7-segment Skriv en subrutin hex7seg som omvandlar från 4 lsbits i r4 till 7 lsbits i r2. Av figur nedan framgår vilka bitar i r2 som svarar mot vilka segment i displayen. Detta val av segment ger utskrift för värden 0-9 samt A-F (A b c d E F) Hur man skiljer man mellan 6 och b framgår av figurerna nedan. bit index 0 5 6 1 a) Skriv subrutinen hex7seg i Nios-II-assemblerkod. 4 3 2 b) Skriv funktionen hex7seg i C. c) Jämför med subrutinen hexasc i laboration niop2time 6.4. Skriv ut ett nummer på 7-segment Display Skriv en subrutin, PutLoSegVal, som skriver ut data till de 4 högra 7-segment displayerna. Inparameter i register r4 är det värde som ska skrivas ut. Vid retur ska samma värde levereras som returparameter i register r2. Du ska förutsätta att en etta i register r4 tänder motsvarade segment och en nolla släcker segmentet. De 4 högra 7-segmentdisplayerna, HEX_LOW28, är Memory-Mapped till adressen 0x9F0 och finns där i 4 grupper om vardera 7 bitar i de minst signifikanta bitarna. a) Skriv subrutinen PutLoSegVal i Nios-II-assemblerkod. b) Skriv funktionen PutLoSegVal i C. 6.5. Skriv ut olika nummer på 7-segment Display Skriv ett program som läser av indata på skjutomkopplarna TOGGLES18 och som tänder/släcker 9 gröna lysdioder GREENLED9 samt skriver ut 4 siffror på 7-segmentsdisplayen HEX_LOW28. De 16 minst signifikanta bitarna på skjutomkopplarna ska styra utsignaler på dioder och 7-segmentsdisplay. Använd de subrutiner som finns i tidigare uppgifter. a) Skriv programmet i Nios-II-assemblerkod. b) Skriv programmet i C. Uppgifter till övning CE_O6, sida 2 (av 5) 2015-02-06
6.6. Timer I DE2-kortet "finns" en kristallstyrd TimerKrets timer_1. Den finns på adress 0x920 och framåt enligt figur på nästa sida. Skriv följande 3 subrutiner som använder denna Timer. Varje subrutin ska skrivas två gånger: en gång i Nios-II-assembler, och en gång i C. a) Den första rutinen, inittimer, ska initiera Timer-1 så att den kör Run och Continous med Time-Out exakt en gång per millisekund. Timerns klocksignal har frekvensen 50 Mhz. b) Den andra rutinen, checktimer, ska undersöka om Timer-1 har gjort Time-Out sedan förra gången checktimer anropades. Om Time-Out har inträffat ska Time-Out-biten återställas, och checktimer ska returnera värdet 0. Om ingen Time-Out har inträffat sedan förra gången checktimer anropades, ska checktimer returnera värdet -1. c) Skriv koden för en subrutin delayt, som ska användas för fördröjning så att man i register r4 anger hur många millisekunder fördröjningen ska vara. Subrutinen delayt ska anropa checktimer, för att undersöka om Timer-1 har gjort Time-Out. Förutsätt att inittimer har anropats innan checktimer anropas Mer information om adresser och innehåll för timerkretsen: 0x920: Läsning ger följande information: (ICKE-MINNESLIKNANDE) bit med index 0 är Time-Out biten som ett-ställs vid Time-Out. bit med index 1 är Run-biten som visar om Countern räknar eller ej. När Run = 1 så räknar timern. När Run = 0 står timerns stilla. Skrivning till adress 0x920 återställer Time-Out-biten till 0, oavsett vilket värde som skrivs. Inga andra bitar på adress 0x920 kan påverkas av skrivningen. 0x924: Läsning och skrivning fungerar "som vanligt", det vill säga det bitmönster som skrivs går att läsa från samma adress (0x924). (DELVIS MINNESLIKNANDE) bit 0 är InterruptEnable on Time-Out (används inte på övning 4 och 5). bit 1 är cont (inous) dvs 1 medför upprepad räkning. bit 2 är start. Skrivning av en etta till denna bit startar timern (Run blir 1). bit 3 är stopp. Skrivning av en etta till denna bit stoppar timern (Run blir 0). 0x928: periodl, det vill säga 16 bitar (LSB) av det värde som finns i Period 0x92C: periodh, det vill säga 16 bitar (MSB) av det värde som finns i Period Observera att man alltid läser/skriver 32 bitar men bara utnyttjar 16! 0x930: snapl, det vill säga Snap Shot av räknaren (Counter), 16 LSB 0x934: snaph, det vill säga Snap Shot av räknaren, 16 MSB Uppgifter till övning CE_O6, sida 3 (av 5) 2015-02-06
När man skriver (vad som helst) till något Snap-Shot-register så kopieras aktuellt värde i räknaren och skkrivs till Snap-Shot-registren, vars innehåll sedan kan läsas med program. (ICKE MINNESLIKNANDE) När man skriver (vad som helst) till något Period-Register så STOPpas nedräkningen av counter och innehållet i Period-Registren, 32 bitar, kopieras till Counter. När Counter, som räknar neråt, kommer ner till 0 blir det Time-Out. Om continousbiten är ett-ställd så kopieras värdet i Period till Counter och nedräkningen börjar om från detta värde. Period-värdet styr antal cykler, det vill säga tiden, mellan varje Time-Out. Kopiering från Period till Counter tar en cykel. Om Period innehåller 17 så blir det 18 klockcykler mellan varje TimeOut. 6.7. Läs in data från IN-port ( KEYS4 ) Skriv nios2-kod för en subrutin, Get_Button som läser av aktuellt värde från de fyra återfjädrande knapparna KEYS4: KEY3 till KEY0, och levererar som returvärde i bitar med index 03 00 i register r2. Bitarna 31 04 ska vid returen vara nollställda. De fyra återfjädrande knapparna KEYS4 finns på adress 0x840, i de 4 minst signifikanta bitarna. Uppsläppt knapp ger värdet 1, och nedtryckt knapp ger värdet 0. a) Skriv kod för subrutinen i Nios-II-assembler. b) Skriv kod för samma subrutin i C. 6.8. Subrutinen TACK Tick back (överkurs) Skriv C-kod för en funktion tickback, som räknar baklänges. Rutinen anropas med en parameter som pekar ut den minnesplats, vars innehåll ska minskas med 1. Innehållet i minnescellen ska betraktas som en sekundräknare som ska slå om från 00 till 59, nästa gång till 58, och så vidare. De två siffrorna lagras i NBCD-kod på samma sätt som för funktionen TICK i laborationskursen. Denna rutin liknar alltså rutinen TICK, men räknar baklänges. Uppgifter till övning CE_O6, sida 4 (av 5) 2015-02-06
6.9. Ett helt stort program (överkurs) Rita ett flödesschema för nedanstående program och skriv programmet Skriv ut 2 siffror på 7-segment varje sekund. Använd en NON-blocking delay för att uppnå detta Dessutom ska knapparna KEYS4 kännas av och leda till följande. Nedtryckning av KEY1 ska nollställa tiden. Nedtryckning av KEY2 ökar tiden ett steg (med TICK) Nedtryckning av KEY3 minskar tiden ett steg (med TACK som är Tick back) Programmet ska avvakta tills man släpper knappen (och tappar då tidräkningen). Vad som sker när fler än en knapp trycks ner är inte specificerat, välj något bra. 6.10. En separat timer, timer_2 (överkurs) I DE2-kortet "finns" en kristallstyrd TimerKrets timer_2, som är precis likadan som timer_1 utom att timer_2 använder andra adresser. Timerkretsen timer_2 finns på adress 0x940 och framåt. Skriv följande subrutiner som använder Timer-2. Varje subrutin ska skrivas två gånger: en gång i Nios-II-assembler, och en gång i C. Markera tydligt de rader som skiljer jämfört med motsvarande subrutin för Timer-1. a) Den första rutinen, inittimer2, ska initiera Timer-2 så att den kör Run och Continous med Time-Out exakt en gång per millisekund. Timerns klocksignal har frekvensen 50 Mhz. b) Den andra rutinen, checktimer2, ska undersöka om Timer-2 har gjort Time-Out sedan förra gången checktimer2 anropades. Om Time-Out har inträffat ska Time-Out-biten återställas, och checktimer2 ska returnera värdet 0. Om ingen Time-Out har inträffat sedan förra gången checktimer2 anropades, ska checktimer2 returnera värdet -1. c) Skriv koden för en subrutin delayt2, som ska användas för fördröjning så att man i register r4 anger hur många millisekunder fördröjningen ska vara. Subrutinen delayt2 ska anropa checktimer2, för att undersöka om Timer-2 har gjort Time-Out. d) Skriv koden för en subrutin restart_timer2 som kan användas om man vill att timern ska starta om från sitt värde enligt innehåll i period-registren. När man skriver (vad som helst) till något Period-Register så STOPpas nedräkningen av counter och innehållet i Period-Registren, 32 bitar, kopieras till Counter. Uppgifter till övning CE_O6, sida 5 (av 5) 2015-02-06