1/1

Příklady zdrojových kódů

Na této stránce najdete příklady jak v assembleru, tak v jazyce C. Jazyk C se sice na naší škole (stále ještě -- už zase) nevyučuje. Nic ale nebrání vašemu samostudiu.

MCU 8051 IDE

Jako vývojové prostředí jsem si oblíbil program MCU 8051 IDE. Umí toho pravdu hodně. Neznáte-li -- vyzkoušejte! Pokud nejste závislí na vašem oblíbeném editoru typu Vim nebo Emacs budete jistě spokojeni. Lze jej použít pro přehlednou a pohodlnou práci nebo jen jako překladač nebo ladící nástroj.

Jako překladač jazyka C používám SDCC. V MCU 8051 IDE je integrována podpora pro tento kompilátor, ale kompilátor jako takový si musíte nainstalovat zvlášť.

LED, 7-segment, repro, tlačítka

Následující příklady se opírají o toto zapojení:

schéma

Možná se budou hodit i následující odkazy:

Zde si můžete si stáhnou kompletní zdrojové kódy. Pro kompilaci používám program make. Najdete zde tedy i příslušné Makefile.

Abych neustále neopisoval jednu a tu stejnou část kódu používám v některých příkladech knihovny:

Blik, Blik.

Jednoduchý příklad pro blikání led.

Assembler:

bli-blik-1.asm
   1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   2 ; Soubor:  bli-blik-1.asm
   3 ; Datum:   19.12.2011
   4 ; Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5 ; Licence: GNU/GPL 
   6 ; Úloha:   jednoduché blikání
   7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   8 
   9 start:
  10     mov P0,#0F0H ; 4 LED nesvítí, 4 LED svítí
  11     call del200m ; čekej 200ms 
  12     mov P0,#00FH ; 4 LED svítí, 4 LED nesvítí
  13     call del800m ; čekej 800ms 
  14     jmp start    ; skok na začátek
  15     jmp start
  16 
  17 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  18 ;    podprogramy pro zpoždění       
  19 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  20 del800m: CALL del400m
  21 del400m: CALL del200m
  22 del200m:    ; 200 ms
  23     MOV    R6, #254d        ; 1CS
  24         MOV R7, #196d    ; 1CS
  25             NOP          ; 1CS
  26             NOP          ;1 SC
  27             DJNZ R7, $-2 ; 196x4 = 784 SC
  28         DJNZ R6, $-6     ; 787x254 =  199898 SC
  29     ; chybí ještě 97 SC
  30     MOV    R7, #48d
  31         DJNZ R7, $
  32     RET                  ; 2CS    
  33 
  34 END
`--> stáhnout

Céčko:

blikBlik.c
   1 /* Soubor:  blik-blik-1.c
   2  * Datum:   19.12.2011
   3  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   4  * Licence: GNU/GPL 
   5  * Úloha:   jednoduché blikání LED na P0.
   6  ****************************************************/
   7 #include <at89x52.h>
   8 
   9 
  10 /** Funkce pro časové zpoždění 10 ms až 2550 ms.
  11  * (Pro OSC 12.0 MHz) Časové zpoždění je vždy násobkem 10 ms.
  12  * Režije spojená s voláním funkce k zadanému zpoždění
  13  * přidává ještě dalších 8 us.
  14  *
  15  * @param koef Celkové zpoždění = koef x 10ms. */
  16 void delay_10m_x(unsigned char koef)
  17 {
  18     koef; //pouze prázdný výraz, abych nedostával warning při kompilaci
  19     __asm
  20     MOV R5,DPL
  21         ; 10ms    
  22 00001$: MOV    R6, #49
  23 00002$:     MOV R7, #100
  24             NOP
  25 00003$:         DJNZ R7, 00003$
  26             DJNZ R6, 00002$
  27         DJNZ R5, 00001$
  28     __endasm;
  29 }
  30 
  31 /* **************************************************
  32  *               Hlavní program.
  33  ****************************************************/
  34 
  35 void main(void)
  36 {
  37     while (1) {                 // nekonečná smyčka
  38         P0 = 0x0F;              // 4 LED svítí, 4 LED nesvítí
  39         delay_10m_x(20);        // čekám 200 ms
  40         P0 = 0xF0;              // 4 LED nesvítí, 4 LED svítí
  41         delay_10m_x(80);        // čekám 800 ms
  42     }
  43     
  44 }
`--> stáhnout

Tú, tú

V tomto příkladu budeme generovat 3 krátké tóny. ÓÓÓvčááácíííí.

tuu-tuu.asm
   1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   2 ; Soubor:  tuu-tuu.asm
   3 ; Datum:   20.12.2011 09:33
   4 ; Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5 ; Licence: GNU/GPL 
   6 ; Úloha:   3 pípnutí reproduktoru
   7 ; Popis:   Akord C-dur
   8 ; C1     262   <-  T = 3816 us; T/2 = 1908 us
   9 ; D1b    277
  10 ; D1     294
  11 ; E1b    311
  12 ; E1     330   <-  T = 3030 us; T/2 = 1515 us
  13 ; F1     349
  14 ; G1b    370
  15 ; G1     392   <-  T = 2551 us; T/2 = 1275 us
  16 ; A1b    416
  17 ; A1     440
  18 ; B1b    466
  19 ; B1     494
  20 ; C2     523
  21 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  22 
  23 repro bit P1.7
  24 
  25 akord:
  26     ; tón C délky 650ms
  27     mov R0,#170D
  28     periodaC:
  29         setb repro
  30         call delayC
  31         clr repro
  32         call delayC
  33         djnz R0, periodaC
  34     ; tón E délky 650ms
  35     mov R0,#214D
  36     periodaE:
  37         setb repro
  38         call delayE
  39         clr repro
  40         call delayE
  41         djnz R0, periodaE
  42     ; tón G délky 650ms
  43     mov R0,#254D
  44     periodaG:
  45         setb repro
  46         call delayG
  47         clr repro
  48         call delayG
  49         djnz R0, periodaG
  50     ; přestávka
  51     call del1s
  52     ; zase znovu
  53     jmp akord    
  54 
  55 
  56 delayC:
  57 ; START: Wait loop, time: 1903 us
  58 ; Clock: 12000.0 kHz (12 / MC)
  59 ; Used registers: R7, R6
  60    MOV R6, #005h
  61    MOV R7, #0BCh
  62    NOP
  63    DJNZ    R7, $
  64    DJNZ    R6, $-5
  65    NOP
  66 ; Rest: 0
  67 ; END: Wait loop 
  68 RET
  69 
  70 delayE:
  71 ; START: Wait loop, time: 1510 us
  72 ; Clock: 12000.0 kHz (12 / MC)
  73 ; Used registers: R7, R6
  74    MOV R6, #00Dh
  75    MOV R7, #038h
  76    NOP
  77    DJNZ    R7, $
  78    DJNZ    R6, $-5
  79 ; Rest: 0
  80 ; END: Wait loop
  81 RET
  82 
  83 delayG:
  84 ; START: Wait loop, time: 1270 us
  85 ; Clock: 12000.0 kHz (12 / MC)
  86 ; Used registers: R7, R6
  87    MOV R6, #003h
  88    MOV R7, #0D1h
  89    NOP
  90    DJNZ    R7, $
  91    DJNZ    R6, $-5
  92    NOP
  93    NOP
  94 ; Rest: 0
  95 ; END: Wait loop
  96 RET
  97 
  98 include delay12MHz.inc
  99 
 100 END
`--> stáhnout

Pokud si porovnáte předchozí příklad v Assembleru a následující příklad v jazyce C zjistíte, že zvuk generovaný v jazyce C tak úplně neladí. Je to proto, že časové zpoždění je zde řešeno poměrně nepřesně.

tuuTuu.c
   1 /*
   2  * Soubor:  tuu-tuu.c
   3  * Datum:   20.12.2011 22:11
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Úloha:   3 pípnutí reproduktoru
   7  * Popis:   Akord C-dur
   8  * C1     262   <-  T = 3816 us; T/2 = 1908 us
   9  * D1b    277
  10  * D1     294
  11  * E1b    311
  12  * E1     330   <-  T = 3030 us; T/2 = 1515 us
  13  * F1     349
  14  * G1b    370
  15  * G1     392   <-  T = 2551 us; T/2 = 1275 us
  16  * A1b    416
  17  * A1     440
  18  * B1b    466
  19  * B1     494
  20  * C2     523
  21  ****************************************************/
  22 
  23 #include <at89x52.h>
  24 
  25 /** Funkce pro časové zpoždění 100 us až 25500 us.
  26  * (Pro OSC 12.0 MHz) Časové zpoždění je vždy násobkem 100 us.
  27  * Režije spojená s voláním funkce k zadanému zpoždění
  28  * přidává ještě dalších 6 us.
  29  *
  30  * @param koef Celkové zpoždění = koef x 100us. */
  31 void delay_100u_x(unsigned char koef)
  32 {
  33     koef; //pouze prázdný výraz, abych nedostával warning při kompilac
  34     __asm
  35     MOV R6, DPL 
  36     ; 100 us 
  37 00002$: MOV R7, #48
  38 00003$:     DJNZ R7, 00003$
  39         NOP 
  40         DJNZ R6, 00002$ 
  41     __endasm;
  42 }
  43 
  44 /****************************************************
  45  *               Hlavní program.
  46  ****************************************************/
  47 
  48 void main(void)
  49 { 
  50     unsigned char i;
  51 
  52     while (1) {
  53         for ( i = 0; i < 170; i++) {
  54             P1_7 = 0;
  55             delay_100u_x(19);
  56             P1_7 = 1;
  57             delay_100u_x(19); 
  58         }
  59         for (i = 0; i < 214; i++) {
  60             P1_7 = 0;
  61             delay_100u_x(15);
  62             P1_7 = 1;
  63             delay_100u_x(15);
  64         }
  65         for (i = 0; i < 254; i++) {
  66             P1_7 = 0;
  67             delay_100u_x(12);
  68             P1_7 = 1;
  69             delay_100u_x(12);
  70         }
  71     }
  72 
  73 }
  74 
`--> stáhnout

Sem tam -- blikání a logické operace

V tomto příkladu je použita knihovna pro časové zpoždění delay12MHz.inc

sem-tam.asm
   1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   2 ; Soubor:  sem-tam.asm
   3 ; Datum:   02.01.2012 23:06
   4 ; Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5 ; Licence: GNU/GPL 
   6 ; Úloha:   světlo se pohybuje zleva doprava a
   7 ;          zprava doleva
   8 ; Popis:   ukázka skolků a logických operací
   9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10 
  11 ukazatel bit 0 ; symbolické jmeno pro ukazatel směru
  12 
  13 ; počáteční nastavení
  14 mov A, #01111111b  ; svítí LED vlevo
  15 setb ukazatel      ; pohybuje se doprava
  16 
  17 ; hlavní smyčka
  18 start:
  19     call roluj 
  20     call del100m
  21     jmp start
  22 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  23 
  24 ; podprogram posune světlo doleva nebo dobrava
  25 roluj:
  26     jnb ukazatel, vlevo ; doleva nebo doprava?
  27     RR A
  28     jmp posun
  29 vlevo:
  30     RL A
  31 posun:    
  32     mov P0, A 
  33     call smer ; prehodi sme -- poku je to potreba
  34     RET
  35 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  36   
  37 ; podprogram přehodí směr posunu
  38 smer:
  39     jnb A.0, negace
  40     jnb A.7, negace
  41     RET
  42 negace:
  43     cpl ukazatel
  44     RET
  45 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  46  
  47 include delay12MHz.inc   ; definice zpoždění
  48 
  49 END
`--> stáhnout

Pro ilustraci uvádím ještě jedno řešení stejného problému:

logicke-operace.asm
   1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   2 ; Soubor:  sem-tam.asm
   3 ; Datum:   02.01.2012 23:06
   4 ; Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5 ; Licence: GNU/GPL 
   6 ; Úloha:   světlo se pohybuje zleva doprava a
   7 ;          zprava doleva
   8 ; Popis:   ukázka skolků a logických operací
   9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10 smer bit 7 ; symbolické jmeno pro ukazatel směru
  11 
  12 mov R0, #1d
  13 setb smer  ;; bit 5 označuje směr  1=vlevo 0= vpravo
  14 
  15 ; hlavní proramová smyčka  
  16 start:
  17    call zobrazuj
  18    call del200m
  19    jmp start
  20    
  21 
  22 ; podprogram pro zobrazení světla na LED
  23 zobrazuj:
  24    mov A, R0 
  25    jb smer, rotujVlevo
  26    jmp rotujVpravo
  27 rotujVlevo:
  28    RL A
  29    jmp uloz
  30 rotujVpravo:
  31    RR A
  32    jmp uloz
  33 
  34 uloz:  
  35    mov R0, A  ; uchovává číslo logicky
  36    cpl A       
  37    mov P0, A  ; P0 zobrazuje 
  38 
  39 ; kontroluju jestli jsem došel doleva -- pomocí CJNE
  40    CJNE R0, #10000000b, preskoc
  41    jmp vpravo
  42 preskoc:   
  43 ; kontroluju jestli jsem došel doprava -- pomocí ANL
  44    mov A, #00000001b
  45    ANL A, R0
  46    jnz vlevo
  47    RET
  48 
  49 ; otáčí směr pohyby doprava
  50 vpravo:
  51    clr smer
  52    RET
  53 ; otáčí směr pohybu doleva    
  54 vlevo:
  55    setb smer
  56    RET 
  57 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  58 
  59 
  60 include delay12MHz.inc
  61 
  62 END
`--> stáhnout

I program v C používá malou knihovnu pro zpoždění:

semTam.c
   1 /*
   2  * Soubor:  sem-tam.c
   3  * Datum:   02.01.2012 23:47
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Úloha: 
   7  * Popis:   
   8  ****************************************************/
   9 #include <at89x52.h>
  10 
  11 #include "delay12MHz.h"
  12 
  13 
  14 /* **************************************************
  15  *               Hlavní program.
  16  ****************************************************/
  17 
  18 #define VLEVO 0
  19 #define VPRAVO 1
  20 void main(void)
  21 {
  22     __bit smer = VPRAVO;
  23     unsigned char svetlo = 0b10000000;
  24     for (;;) {
  25         /* sviť */
  26         P0 = ~svetlo;
  27         /* rotace */
  28         if (smer == VPRAVO) {
  29             svetlo = svetlo >> 1;
  30         } else if (smer == VLEVO) {
  31             svetlo = svetlo << 1;
  32         }
  33         /* prohození směru */
  34         if (svetlo == 128 || svetlo == 1) {
  35             smer = !smer;
  36         }
  37         /* čekej */
  38         delay_10m_x(10);
  39     }
  40 }
`--> stáhnout

7-segment

V těchto jednoduchých příkladech si všimněte použití symbolu PORT. Ten ukazuje na port P2, ale pokud bude 7-segmentový display umístěn na jiném portu lze ho velice jednoduše -- na jednom místě, změnit.

7-segment.asm
   1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   2 ; Soubor:  7-segment.asm
   3 ; Datum:   06.01.2012 12:32
   4 ; Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5 ; Licence: GNU/GPL 
   6 ; Úloha:   Zobrazí na 7-segmenotvém displayi čísla 0-9.
   7 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   8 
   9 port EQU P2 ; definice symbolu
  10 
  11 start:
  12     mov port,#11000000b  ; 0
  13     call del800m
  14     mov port,#11111001b  ; 1
  15     call del800m
  16     mov port,#10100100b  ; 2
  17     call del800m
  18     mov port,#10110000b  ; 3 
  19     call del800m
  20     mov port,#10011001b  ; 4
  21     call del800m
  22     mov port,#10010010b  ; 5
  23     call del800m
  24     mov port,#10000010b  ; 6
  25     call del800m
  26     mov port,#11111000b  ; 7
  27     call del800m
  28     mov port,#10000000b  ; 8
  29     call del800m
  30     mov port,#10010000b  ; 9
  31     
  32     jmp start
  33 
  34 include delay12MHz.inc
  35 
  36 END
`--> stáhnout
7segment.c
   1 /*
   2  * Soubor:  7-segment.c
   3  * Datum:   06.01.2012 12:52
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Úloha: Zobrazí na 7-segmenotvém displayi čísla 0-9.
   7  ****************************************************/
   8 #define _ISOC99_SOURCE
   9 #define _GNU_SOURCE
  10 #include <at89x52.h>
  11 
  12 #include "delay12MHz.h"
  13 
  14 /* ***************    Makra    ******************** */
  15 #define PORT P2
  16 
  17 
  18 /****************************************************
  19  *               Hlavní program.
  20  ****************************************************/
  21 int main(void)
  22 {
  23     while (1) {
  24         PORT = 0b11000000;         // 0
  25         delay_10m_x(80);
  26         PORT = 0b11111001;         // 1
  27         delay_10m_x(80);
  28         PORT = 0b10100100;         // 2
  29         delay_10m_x(80);
  30         PORT = 0b10110000;         // 3 
  31         delay_10m_x(80);
  32         PORT = 0b10011001;         // 4
  33         delay_10m_x(80);
  34         PORT = 0b10010010;         // 5
  35         delay_10m_x(80);
  36         PORT = 0b10000010;         // 6
  37         delay_10m_x(80);
  38         PORT = 0b11111000;         // 7
  39         delay_10m_x(80);
  40         PORT = 0b10000000;         // 8
  41         delay_10m_x(80);
  42         PORT = 0b10010000;         // 9
  43         delay_10m_x(80);
  44     }
  45     return 0;
  46 }
`--> stáhnout

7-segment s pomocí tabulky

7-seg-tab.asm
   1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   2 ; Soubor:  7-seg-tab.asm
   3 ; Datum:   06.01.2012 13:51
   4 ; Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5 ; Licence: GNU/GPL 
   6 ; Úloha:   Na 7-segmentovém displayi cykluje čísla 0-9
   7 ; Popis:   Ukazka práce s tabulkou.
   8 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   9 
  10 mov DPTR, #segment ; uloží adresu tabulky
  11 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  12 tabulka:
  13     mov R0, #0      ; nuluje při překroční čísla 9
  14 smycka:
  15     call zobrazuj
  16     call del1s
  17     inc R0             ; zvýší hodnotu R0 o 1
  18     cjne R0, #10, smycka ; počítá jen do 10 
  19     jmp tabulka
  20 
  21 ; podprogram přepíš registr R0 na port 7-segment
  22 zobrazuj:
  23     mov A, R0         ; v A je číslo, které chci zobrazit
  24     movc A,@A+DPTR    ; číslo, které chci zobrazit najdu v tabulce a uložím opět do A
  25     mov P2, A         ; zobrazím číslo vytažené z tabulky
  26     RET
  27 
  28 ;; tabulka číslic displaye
  29 segment: db 11000000b  ; 0
  30          db 11111001b  ; 1
  31          db 10100100b  ; 2
  32          db 10110000b  ; 3 
  33          db 10011001b  ; 4
  34          db 10010010b  ; 5
  35          db 10000010b  ; 6
  36          db 11111000b  ; 7
  37          db 10000000b  ; 8
  38          db 10010000b  ; 9
  39 
  40 include delay12MHz.inc
  41 
  42 END
`--> stáhnout

V jazyce C je místo tabulky, použit klasické pole. Paměťová řída __code říká, že se se pole nemá ukládat do paměti RAM, ale do paměti programu.

7segmentPole.c
   1 /*
   2  * Soubor:  7-seg-pole.c
   3  * Datum:   06.01.2012 14:49
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Úloha:   Na 7-segmentovém displayi cykluje čísla 0-9
   7  * Popis:   Práce s polem.
   8  ****************************************************/
   9 #define _ISOC99_SOURCE
  10 #define _GNU_SOURCE
  11 #include <at89x52.h>
  12 
  13 #include "delay12MHz.h"
  14 
  15 /* ***************    Makra    ******************** */
  16 #define PORT P2
  17 
  18 
  19 /****************************************************
  20  *               Hlavní program.
  21  ****************************************************/
  22 int main(void)
  23 {
  24     /* pole uložené v paměti programu představuje čísla na displayi */
  25     __code char segment[] = { 0b11000000,       //0
  26         0b11111001,           // 1
  27         0b10100100,           // 2
  28         0b10110000,           // 3 
  29         0b10011001,           // 4
  30         0b10010010,           // 5
  31         0b10000010,           // 6
  32         0b11111000,           // 7
  33         0b10000000,           // 8
  34         0b10010000            // 9
  35     };
  36     /* zobrazované číslo */
  37     char cislo = 0;
  38 
  39     while (1) {
  40         PORT = segment[cislo];  // zobrazí
  41         delay_10m_x(80);        // čeká
  42         if (cislo < 9) {
  43             cislo++;
  44         } else {
  45             cislo = 0;
  46         }
  47         
  48     }
  49 
  50     return 0;
  51 }
`--> stáhnout

Hrací kostka -- tlačítko poprvé

V tomto programu se na display zobrazuje náhodné číslo v rozsahu 1-6. Využívám zde toho, že procesor je poměrně rychlý a proto při stisku tlačítka nikdy nevím, kolik strojových cyklů ho vlastně držím. Proto se na displayi zobrazí pokaždé jiné číslo.

hraci-kostka.asm
   1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
   2 ; Soubor:  hraci-kostka.asm
   3 ; Datum:   09.01.2012 10:00
   4 ; Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5 ; Licence: GNU/GPL 
   6 ; Úloha:   Hrací kostka
   7 ; Popis:   Po stisknutí tlačíta zobrazí 7-segmentovce náhodné
   8 ;          číslo.
   9 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10 
  11 ; symbol pro bit, na kterém je ovládací tlačítko
  12 TL bit P1.0
  13 
  14 ; počáteční nastavení
  15 mov DPTR, #segment
  16 mov R0, #1d
  17 
  18 ; hlavní smyčka, pokud není stiskuné tlačíto, jen se zobrazuje
  19 kostka:
  20     jnb TL, cykluj ; pokud je stisnuto tlačítko, volej cykluj
  21     CALL zobrazuj
  22     jmp kostka
  23 
  24 ; dokud je stisknuté tlačítko, zvětšuj hodnotu R0
  25 cykluj:
  26     mov P2, #0FFH ; zhasni 7-segmentovku
  27     clr P2.7     ; rozsviť tečku
  28     inc R0       ; zvedni hodnotu R0
  29     cjne R0, #7d, nenuluj ; počítej jen do 6.
  30     mov R0, #1d
  31 nenuluj:
  32     jmp kostka
  33    
  34 ; číslo z registru R0 zobrazí na 7-segmentovku
  35 zobrazuj:
  36     mov A, R0
  37     movc A,@A+DPTR
  38     mov P2, A
  39     RET
  40 ; tabulka zobrazení na 7-segmentovce
  41 segment: db 11000000b  ; 0
  42          db 11111001b  ; 1
  43          db 10100100b  ; 2
  44          db 10110000b  ; 3 
  45          db 10011001b  ; 4
  46          db 10010010b  ; 5
  47          db 10000010b  ; 6
  48          db 11111000b  ; 7
  49          db 10000000b  ; 8
  50          db 10010000b  ; 9
  51 
  52 include delay12MHz.inc
  53 
  54 END
`--> stáhnout
hraciKostka.c
   1 /*
   2  * Soubor:  hraci-kostka.c
   3  * Datum:   09.01.2012 10:21
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Úloha: 
   7  * Popis:   
   8  ****************************************************/
   9 #define _ISOC99_SOURCE
  10 #define _GNU_SOURCE
  11 #include <at89x52.h>
  12 
  13 /* ***************    Makra    ******************** */
  14 #define DISPLAY P2
  15 #define TECKA P2_7
  16 #define TLACITKO (P1_0 == 0)
  17 
  18 
  19 /* pole uložené v paměti programu představuje čísla na displayi */
  20 __code char segment[] = { 
  21     0b11000000,           //0
  22     0b11111001,           // 1
  23     0b10100100,           // 2
  24     0b10110000,           // 3 
  25     0b10011001,           // 4
  26     0b10010010,           // 5
  27     0b10000010,           // 6
  28     0b11111000,           // 7
  29     0b10000000,           // 8
  30     0b10010000            // 9
  31 };
  32 
  33 
  34 /****************************************************
  35  *               Hlavní program.
  36  ****************************************************/
  37 void main(void)
  38 {
  39     char cislo = 1;
  40 
  41     /* Pokud je stisknuté tlačítko, tak se v proměnné cislo
  42      * cykluje hodnota 1-6. Pokd tlačítko stisnuté není, 
  43      * hodnota proměnné cilo se zobrazuje na display.      */
  44     while (1) {
  45         if (TLACITKO) {
  46             DISPLAY = 0b01111111;
  47             cislo = cislo < 6 ? cislo + 1 : 1;
  48         } else {
  49             DISPLAY = segment[cislo];
  50         }
  51     }
  52 }
`--> stáhnout

Sem tam -- tlačítko podruhé

semTamTlac.c
   1 /*
   2  * Soubor:  sem-tam.c
   3  * Datum:   02.01.2012 23:47
   4  * Autor:   Marek Nožka, nozka <@t> spseol <d.t> cz
   5  * Licence: GNU/GPL 
   6  * Úloha:   Světlo se pohybuje doleva a doprava
   7  * Popis:   Tlačítka řídí rychlost.
   8  ****************************************************/
   9 #include <at89x52.h>
  10 #include <stdbool.h>
  11 
  12 #include "delay12MHz.h"
  13 
  14 
  15 /* **************************************************
  16  *               Hlavní program.
  17  ****************************************************/
  18 
  19 #define VLEVO 0
  20 #define VPRAVO 1
  21 // tlačítko, které zvyšuje rychlost
  22 #define TLPLUS (P1_0 == 0)
  23 // tlačítko, které snižuje rychlost
  24 #define TLMINUS (P1_1 == 0)
  25 // tlačítko, které zastavuje a spouští
  26 #define TLSTOP (P1_2 == 0)
  27 // (jak dlouho musím držet tlačítko, aby reagovalo) x 10 ms 
  28 #define DRZIM 10 
  29 
  30 
  31 /** Funkce se stará o zobrazování a prohozazování směru
  32  *  pohybu světla 
  33  */
  34 void zobrazuj(void)
  35 {
  36     static bool smer = VPRAVO;
  37     static unsigned char svetlo = 0b10000000;
  38 
  39     /* sviť */
  40     P0 = ~svetlo;
  41     /* rotace */
  42     if (smer == VPRAVO) {
  43         svetlo = svetlo >> 1;
  44     } else if (smer == VLEVO) {
  45         svetlo = svetlo << 1;
  46     }
  47     /* prohození směru */
  48     if (svetlo == 128 || svetlo == 1) {
  49         smer = !smer;
  50     }
  51 }
  52 
  53 /** Funkce zobrazí na 7segmentu orientačí hodnotu rychlosti
  54  * (0 až 9)
  55  */
  56 
  57 void zobrazuj7(unsigned char cas)
  58 {
  59     /* pole uložené v paměti programu představuje čísla na displayi */
  60     __code char segment[] = { 
  61         0b11000000,           //0
  62         0b11111001,           // 1
  63         0b10100100,           // 2
  64         0b10110000,           // 3 
  65         0b10011001,           // 4
  66         0b10010010,           // 5
  67         0b10000010,           // 6
  68         0b11111000,           // 7
  69         0b10000000,           // 8
  70         0b10010000            // 9
  71     };
  72     P2 = segment[9 - (cas-1)/10 ];
  73 
  74 }
  75 
  76 /** Tato funkce se zpouští každých 10ms a kontroluje přidržení
  77  *  tlačítek.
  78  */
  79 void kontrolujPlusMinus(unsigned char * cas)
  80 {
  81     static unsigned char indikatorPlus = 0;
  82     static unsigned char indikatorMinus = 1;
  83     static bool drzimPlus = false;
  84     static bool drzimMinus = false;
  85     // tlačítko PLUS
  86     if (TLPLUS) {
  87         drzimPlus = true;
  88         indikatorPlus++;
  89     } else {
  90         drzimPlus = false;
  91         indikatorPlus = 0;
  92     }
  93     if (indikatorPlus > DRZIM) {
  94         (*cas) = (*cas) <= 2 ? 2 : (*cas) - 1;
  95         indikatorPlus = 0;
  96     }
  97     // tlačítko MINUS
  98     if (TLMINUS) {
  99         drzimMinus = true;
 100         indikatorMinus++;
 101     } else {
 102         drzimMinus = false;
 103         indikatorMinus = 0;
 104     }
 105     if (indikatorMinus > DRZIM) {
 106         (*cas) = (*cas) >= 100 ? 100 : (*cas) + 1;
 107         indikatorMinus = 0;
 108     }
 109 }
 110 
 111 void main(void)
 112 {
 113     unsigned char cas = 50;
 114     unsigned char i;
 115     bool stop = false;
 116     bool stopPamet = false;
 117     for (;;) {
 118         if (!stop) {
 119             zobrazuj();
 120             zobrazuj7(cas);
 121             // realizuje zpoždění a zároveň kontroluje tlačítko
 122             for (i = 0; i < cas; i++) {
 123                 delay_10m_x(1);
 124                 kontrolujPlusMinus(&cas);
 125             }
 126         }
 127         // TLSTOP reaguje při uvolnění
 128         if (!TLSTOP && stopPamet) {
 129             stop = ! stop;
 130         } 
 131         stopPamet = TLSTOP;
 132     }
 133 }
`--> stáhnout

| navigace |

Licence Creative Commons Valid XHTML 1.0 Strict Valid CSS! Antispam.er.cz Blog: Tlapicka.net