Hi all,
Here we are with our new application which is super cool! Actually it's a bit old but I brought it back for the 1kb challenge. Anyways, lets talk about it.
It is an electronic dice based from random number generator which is also based from LFSR(Lineer Feedback Shift Register)
Random generator genarates two integers between 1-6 to perfom dice values. Than it shows the values on 7 segment displays.
You can see schematic circuit at figure-1. It consist of 3 main parts those are Microcontroller(AT89S52), 7 segment displays and their drivers(74HC595) and Dice button to play dice.
I have set circuit up on bread board as you can see at figure-2. Also there is isis simulation for the application. You can find it in the github repo.
Application codes written in assembly language. Code size is around 203 bytes which means it's fitted for 1kb challenge! Hooray!
;************************************************************************
; Program : ElectronicDice.asm *
; Author : Erhan YILMAZ *
; Date : 17-12-2016 *
; Version : 1.0 *
; Size : 203 Byte *
;************************************************************************
SHIFT_DATA EQU 0X20 ; Seri veri yoluna gönderilecek veriyi tutan yazmaç
CHIP_SELECT EQU 0X21.0 ; Gösterge(74HC595) Seçme biti
RASGELE_SAYI EQU 0X30 ; Rasgele sayı değişkeni
ANIMASYON_SAYAC EQU 0X30 ; Animasyon programı sayacı
ZAR_BUTON EQU P1.0 ; Zar atma butonu
SCK EQU P2.0 ; 74HC595 Saat sinyali çıkış pini
SDO EQU P2.1 ; 74HC595 Seri veri çıkış pini
CS1 EQU P2.2 ; Gösterge 1 seçme pini
CS2 EQU P2.3 ; Gösterge 2 seçme pini
ORG 0000H ;RESET vektörü adresi
AJMP BASLA ;BASLA etiketine git
ORG 0100H
;7 parça gösterge veri tablosu
; a
; -----
; | | b
; f | g |
; -----
; e | | c
; | |
; ----- . dp
; d
; .gfedcba
; Segment Data = 0bxxxxxxxx
; 7 parça göstergelere gönderilecek olan değerler program hafızadan sabit olarak okunarak göstegelere gönderilir.
SEGMENT_TABLO: DB 0X3F,0X06,0X5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F,0X77,0X7C,0X39,0X5E,0X79,0X71
ANIMASYON_TABLO: DB 0X01,0X02,0X04,0X08,0X10,0X20
BASLA:
CLR A ; Akümülatörü temizle
MOV P2,A ; Port2'yi temizle
MOV ANIMASYON_SAYAC,#0X00 ; Animasyon sayacını sıfırla
MOV TH0,#0X01 ; Timer0 reload değerini yükle
MOV TL0,#0X01 ; Timer0 ilk değerini yükle
MOV TMOD,#0XF2 ; Timer0 8 bit tekrar yüklemeli(0x01) olarak çalıştırılır.
SETB TCON.4 ; Timer0 çalıştırılır.
CLR CHIP_SELECT ; Başlangıçta Gösterge 1 temizlenir.
MOV SHIFT_DATA,#0x00
ACALL SHIFT_SEND_BYTE
SETB CHIP_SELECT ; Başlangıçta Gösterge 2 temizlenir.
MOV SHIFT_DATA,#0x00
ACALL SHIFT_SEND_BYTE
LOOP:
JB ZAR_BUTON,LOOP ; Butona basılana kadar bekle
ACALL GECIKME ; Buton arkını önlemek için bi süre beklenir.
KAL:
JB ZAR_BUTON,ATLA ; Buton bırakılana kadar animasyon programını çalıştır.
ACALL ANIMASYON
AJMP KAL
ATLA:
ACALL ZAR_AT ; Birinci zar değerini üret
CLR CHIP_SELECT ; Gösterge0'i seç
ACALL SEGMENT_GOSTER ; Zar değerini Gösterge0'de göster
ACALL ZAR_AT ; İkinci zar değerini üret
SETB CHIP_SELECT ; Gösterge1'i seç
ACALL SEGMENT_GOSTER ; Zar değerini Gösterge1'de göster
AJMP LOOP ; Sonsuz döngü
; Bu alt program 1-6 arasında rasgele sayı üretir sonucu Akümülatöre yazar.
ZAR_AT:
MOV RASGELE_SAYI,TL0 ; Rasgele sayı üreteci için Timer0'dan başlangıç değeri al
TEKRAR_URET:
ACALL RASGELE_SAYI_URET ; Rasgele sayı üret
MOV A,RASGELE_SAYI
ANL A,#0X0F
CJNE A,#0X00,SIFIR_DEGIL ; Üretilen rasgele sayının alt 4 bitinin sıfır olup olmadığını test et.
SJMP TEKRAR_URET ; Sıfırsa başka sayı üret.
SIFIR_DEGIL:
CLR C
SUBB A,#0X07
JC BITIR ; Üretilen sayının alt 4 bitinin 6'dan büyük olup olmadığını test et.
LJMP TEKRAR_URET ; Büyükse başka sayı üret.
BITIR:
MOV A,RASGELE_SAYI
RET
; Bu alt program (A) Akümülatördeki değerin alt 4 bitini (0-F) göstergelere
; gönderir. CHIP_SELECT bayrağı set edilmişse veri gösterge1'e edilmemişse gösterge0'a gider
SEGMENT_GOSTER:
ANL A,#0X0F
MOV DPTR,#SEGMENT_TABLO
MOVC A,@A+DPTR
MOV SHIFT_DATA,A
ACALL SHIFT_SEND_BYTE
RET
; Bu alt program SHIFT_DATA yazmacındaki 8 bit veriyi seri veri yolu üzerinden 74HC595 çiplerine gönderir.
SHIFT_SEND_BYTE:
MOV R0,#0X08 ;Sayac değeri olarak 8 yükle
GONDER:
SETB SDO ; Seri veri hattını set et
JB SHIFT_DATA.7,A1 ; SHIFT_DATA.7 bitini kontrol et
CLR SDO ; Sıfır ise seri veri hattını sıfıra çek
A1: SETB SCK ; Saat sinyalini oluştur.
CLR SCK
MOV A,SHIFT_DATA ; Diğer biti göndermek için 1 bit sola ötele.
RL A
MOV SHIFT_DATA,A ; 8 bit yollanana kadar devam et.
DJNZ R0,GONDER
JB CHIP_SELECT,A2 ; Gösterge 1 seçiliyse
SETB CS1 ; 1. 74HC595 latch edilir.
CLR CS1
A2:
JNB CHIP_SELECT,A3 ; Gösterge 2 seçiliyse
SETB CS2 ; 2. 74HC595 latch edilir.
CLR CS2
A3:
RET
; Bu alt program LFSR(Lineer Feedback Shift Register) temelli 8bit rasgele sayı üretir.(alıntıdır.)
RASGELE_SAYI_URET:
CLR C
MOV A,RASGELE_SAYI
RRC A
JNC SON1
XRL A,#0XB4
SON1:
MOV RASGELE_SAYI,A
RET
; Bu alt program göstergelerde yürüyen segment efekti yapar.
ANIMASYON:
MOV DPTR,#ANIMASYON_TABLO
MOV A,ANIMASYON_SAYAC
MOVC A,@A+DPTR
CLR CHIP_SELECT
MOV SHIFT_DATA,A
ACALL SHIFT_SEND_BYTE
SETB CHIP_SELECT
MOV SHIFT_DATA,A
ACALL SHIFT_SEND_BYTE
ACALL GECIKME
INC ANIMASYON_SAYAC
MOV A,ANIMASYON_SAYAC
CLR C
SUBB A,#0x06
JC SON2
CLR A
MOV ANIMASYON_SAYAC,A
SON2:
RET
; Bu alt program gecikme sağlamak için kullanılır. (alıntıdır)
GECIKME:
MOV R1,#0X04
MOV R2,#0X80
BEKLE:
DJNZ R1,BEKLE
DJNZ R2,BEKLE
RET
END
As you can see below it is written in asm. Unfortunately comments are in Turkish. But code is clean and you can understand it easily.And finally here application video. You can watch and see how much it is cool!
You can file all files in the github repo of ElectronicDice.
As result as It is a nice circuit entertaiment aimed. You can make it before xmas for your funny games! I hope it makes you inspired!
See you on next post!
Cheers..