nevíte jestli nějaká instrukce která třeba do registru “A” nebo jiného načte libovolné číslo?? nebo si budu muset vymyslet nějakej cyklus na ruznej součet či nasobeni pár čísel…
Ač se to programátorům vyšších programovacích jazyků nezdá, tak u mikrokontrolerů je s náhodnými čísly problém. Instrukci rand (omylem jsem napsal round - zaokrouhlení, díky za opravu Freshmane), které udělá vše za tebe, nenajdeš. Nejčastěji se vytváří náhodná čísla počítáním času držení tlačítka (každý stisk tlačítka je jedinečný).
Koukni na následující kód:
Mělo by to generovat 8-bit náhodné číslo, program jsem nestudoval, takže neručím za fungování.
[code].equ code, 0x2000
.equ pm2_phex, 0x0034
.equ pm2_esc, 0x003E
.org code
.db 165, 229, 224, 165
.db 35, 255, 0, 0
.db 0, 0, 0, 0
.db 0, 0, 0, 0
.db 0, 0, 0, 0
.db 0, 0, 0, 0
.db 0, 0, 0, 0
.db 255, 255, 255, 255
.db “ArcFour”,0
.org code+60
ajmp arcfour_set_key
ajmp arcfour
;-----
mov dptr, #code+0x100
acall arcfour_set_key
loop:
clr a
acall arcfour
lcall pm2_phex
lcall pm2_esc
jnc loop
ret
;-----
arcfour_set_key:
push acc
mov dpl, #0
inc dph
arcfour_reset_sbox_loop:
mov a, dpl
movx @dptr, a
inc dpl
clr a
cjne a, dpl, arcfour_reset_sbox_loop
dec dph
mov r6, #0
arcfour_rand_sbox_loop:
movx a, @dptr
add a, r6
mov r6, a
inc dph
movx a, @dptr
mov r7, a
add a, r6
mov r6, a
push dpl
mov dpl, r6
movx a, @dptr
xch a, r7
movx @dptr, a
pop dpl
mov a, r7
movx @dptr, a
dec dph
inc dpl
clr a
cjne a, dpl, arcfour_rand_sbox_loop
mov r6, #0
mov r7, #0
pop acc
ret
;-----
arcfour:
push b
push acc
inc dph
inc r6
mov dpl, r6
movx a, @dptr
mov b, a
add a, r7
mov r7, a
mov dpl, r7
movx a, @dptr
xch a, b
movx @dptr, a
mov dpl, r6
xch a, b
movx @dptr, a
add a, b
mov dpl, a
movx a, @dptr
pop b
xrl a, b
dec dph
pop b
ret[/code]
administrator asi myslel instrukci rand, nikoliv round. Tlacitko je bezne a jednoduche, urcite je i spousta dalsich pouzitelnych zpusobu, docela vtipne mi prislo reseni pouzite autorem tohoto sikanovaciho nastroje: mcu.cz/news.php?extend.1371.2
zkus se podívat po něčem jakoje pseudořada, generátor pseud čísel, takto se dělají “náhodná” čísla…
měl bych tu programna pseudořadu jak pro PIC tak AVR, sice ne pro tu 8051m jelikož jí moc neumím, ale pokud budeš chtít tak sinapiš SZ a pošlu ti to
avr ani pic zas nedělám já takže by to bylo asi na nic
Zdravim!
Mám podobný problém. Chcem spraviť losovacie zariadenie a potrebujem s 8051 urobiť generátor náhodných čísiel v určitom rozsahu. napr 1…2000.
Mohol by niekto poradiť?
igor
tak já jsem si napsal nakonec takovej cyklus kterej vygeneruje “ruzný” čísla pomocí několika řádků přičítám k “A” číslo 53
[code]
ORG 000H ;Adresa následující po resetu (zapnutí)
JMP ZACATEK ;Po resetu skoč na začátek
;ORG 003H ;Adresa pro INT0
;JMP PRE0
;ORG 013H ;Adresa pro INT1
;JMP PRE1
;------------------------------------------------------------------------------
ZACATEK:MOV IE,#10000101B ;povoli preruseni od INT0 a INT1 (tlač.)
MOV TMOD,#00000001B ;NASTAVI ČASOVAČ 0 DO MODU 1
SETB IT0 ;Vnější přerušení (tlačítka) jsou
SETB IT1 ;aktivní na sestupnou hranu
MOV A, #1 ;přednastavení A
MOV R7,#53 ; přednastavení R7
SMYCKA: ADD A,R7 ;součet A+53
MOV P1,A ;přesuň data na P1
CALL ZPOZDENI
JMP SMYCKA
ZPOZDENI: MOV R1,#227 ; přesně [ms]: 50,0022
SK0: MOV R0,#100
DJNZ R0,$
DJNZ R1,SK0
RET
END[/code]
neni to nic moc ale na barevnou hudbu mi to snad bude stačit, přerušení zatím nepoužívám takže je za středníkem…jo a řekl bych Igore že vzhledem k osmi bitove sběrnici nevytvoříš větší číslo než je 255 takže 2000 asi nedáš
proč by nedal větší číslo ?? KDyž spojíš dva osmi bitové registry tak máš šesnácti bitové číslo a to je 65536
v tom tvém principu nevím jak je to s náhodností, ale v té pseudořadě je to právě tak, že každé číslo je tam pouze jednou !!! takže pokud máme 16bit. registr tak máme 65535 možností prostě se vygenerují všechny čísla od ted nevím jestli se tamvygeneruje i nule nebo ne protože nesmí být nula jako počáteční podmínka, ale vygeneruje se ti to bud od nuly nebo jedničky do tch 65535, coz znamená že tam ta nula není pokud jejenom 65535 možností
no ale tak pokud bude pracovat jen s těma osmi bitama jako já tak je to jen 0-255 a co se náhodnejch čísel týče no tak prostě mi na port P1 skáčou různý čísla a to mi stačí
Vrele doporucujem si pozriet odkaz, ktory uvadza Freshman.
Je to velmi poucne nie len ako generovat nahodne cisla, ale autor velmi exaktne realizoval i matematicku statistiku, do akej miery je nahoda nahodou. A ak niekto robi losovacie zariadenie, asi by mal mat nejaky exaktny vysledok, ze vsetky cisla sa generuju aspon priblizne s rovnakou pravdepodobnostou.
to kyberbob: Odkial ti na port P1 “skacu” cisla? Ako tozabezpecujes?
tímhle kodem
MOV P1,A ;přesuň data na P1
pošlu data na p1 jestli jsem pochopil dotaz
Nepytal som sa ako data z P1 prenesies “z programu”,
ale ako zabezpecujes, aby na P1 ako pises
Ako zabezpecujes tu nahodnost?
to by mohlo byt dost zaujimave i pre inych, ako generovat RANDOM data.
no tak z kodu je vidět že v A je 1 R7 je 53, no a já stále opakuji funkci ADD která je součet dvou čísel takže z tohoto:
cyklus:
ADD A,R7
jmp cyklus ;A a R7 secti a uloz do A
je tohle:
A=1, R7=53
1+53=54 A=54 > opakovat
A=54, R7=53
54+53=107 A=107 > opakovat
A=107, R7=53
107+53=107 A=160 > opakovat
a takhle je to furt dokola, když je to A větší než 255 tak se vynuluje a počítá to od 0 “asi”, to číslo 53 jde změnit za jine a bude to zase tvořit jiná šísla je to prostě nej posloupnost sčítání což jde i změnit v atmelu jsem to ještě neměl ale simulační program snad nelže, viz graf, v budoucnu se na port P1 přenesou data jen vyvoláním přerušení aby to bylo vic náhodné, pokud dělám chybu tak se fšem omlouvám mě to takhle stačí
Jasne
To kyberbob:
omluvam sa, ze som si dobre nepozrel program z 28.1., respektive som ho nespojil s Tvojim menom. Nejak som omylom nadobudol dojem, ze sa jedna o nejaky iny princip. Z toho Tvojho sw je to predsa jasne
Rutina na náhodná čísla zde: (Ověřeno, funguje - a dobře ):
dhservis.cz/rutiny_soubory/nahoda.htm
EDIT: tys mě předběh Igore!
Pro správný random generátor by měly být splněny nasledující požadavky:
- Pravděpodobnost výskytu každého generovaného čísla ze zvoleného intervalu musí být stejná při nekonečném množsví vzorků.
- Generování nesmí být periodické. Žádná větší posloupnost čísel se nesmí opakovat.
- Žádná další hodnota z generátoru nesmí být předvídatelná.
- Dvě stejná zařízení se stejným SW nesmí generovat stejnou posloupnost čísel.
Jinými slovy, random generátor se musí chovat jako zdroj bílého šumu.(obsahuje všechny fekvence se stejnou amplitudou).
Kupříkladu funkce:
Y(t) = sin(at) + sin(bt)
kde t je čas a a a b jsou reálná čísla nemající celý společný násobek je neperiodická. Zdálo by se, že to lze pro random gen. použít, ale nespňuje podmínky 3 a 4.
Aby to fungovalo, musí být do výpočtu zavlečen jistý fyzikální jev, jež je jedinečný pro to které zařízení. Už zde bylo vzpomenuto měření teploty nebo šumu z ADC.
Napadlo mě docela jednoduché řešení vycházející z výše uvedené funkce. Není třeba počítat siny, ale stačí vzít 2 nezávislé frekvence, které přirozeně budou nesoudělné. Jejich součet by dal neperiodický signál. Jednou frekvencí může být krystal MCU a druhou frekvencí sít nebo RTC.
Pak stačí spustit 1 timer, jehož inkrementování je odvozeno od krystalu MCU a druhá frekvence generuje přerušení např. od síťové frekvence. V přerušení se odečte okamžitý stav timeru. Takto získané vzorky mohou posloužit jako parametry nějaké funkce či polynomu pro výpočet náhodného čísla.
V jednoduším případě lze vytvořit přerušení od timeru v pravidelných časových intervalech a přečíst si v něm hodnotu PC registru, což je vlastně návratová adresa v zásobníku. Protože k přerušení může docházet v libovolné části programu, získáme tak posloupnost pseudonáhodných čísel ale jen tehdy, není-li hlavní program nějak synchronizován s tímto timerem.
Technik: Jseš řek bych velký detajlista, ale máš pravdu, že náhodná čísla se většinou odvozují od časově závislých funkcí. I PC to tak dělá.
Nepročítal jsem toto téma podrobně, ale “jak moc” musí být ta generovaná čísla náhodná? (otázka pro autora tématu)
Jako kompliment to moc nezní, ale když jsem si pročítal zdejší příspěvky, tak má poci, že mnozí podléhají jisté iluzi.
Jeli náhodné číslo generováno funkcí
y = f(a++)
kde a je vnitřní proměnná typu static a inkrementuje se s každým použitím této funkce, nemůže jít o generování náhodných čísel. Už si přesně nepamatuju terminologii z matematiky takže se asi dopustím asi pojmové chyby. Funkce je zobrazením množiny A do množiny Y. Tzn. že každému prvku a z množiny A je jednoznačne přiřazen prvek y z množiny Y. Přičemž 2 různým a může být přiřezen tentýž prvek y. Z toho plyne, že jakákoli funkce zařídí pouze záměnu pořadí generovaných čísel, ale jejich poslounost se bude periodicky opakovat. Je to stejné, jako když vezmete paměť EEPROM, do ní nahrajete “zázračná” data, na adresové vodiče připojíte čítač, který se inkrementuje s každám použitím funkce a z datových vodičů odeberet “náhodné” číslo. Nic na tom nezmění ani obsah paměni, ani záměna datových nebo adresových vodičů. Pouze to bude mít vliv na generování pořadí čísel, ale pořád je to systametický periodický generátor čísel. nikoli náhodný.
Jednoduchá ukázka praktického použití randomgenerátou, kde záleží na tom, aby opravdu generoval náhodá čísla, je tzv. zasněžení grafické plochy pomocí kreslení pixelu. Pixely se vykreslují např. do obdelníku tak dlouho, až pokryjí celou plochu. Jeho souřadnice X,Y se počítají z randomgenerátoru. Pokud to nejsou opravdu náhodná čísla, tedy nesplňují 4 výše uvedené podmínky, místo zaplnění celé plochy se nakreslí prapodivné obrazce a určitá místa se nikdy nevykreslí.
Nemá smysl uvažovat o funkci y = f(a++) a hledat zázračné algoritmy typu XOR, SWAP, ROL nebo přičítání 53, jak je zde nabízeno, protože funkce má jedinou vnitřní proměnou a, kterou když vynulujeme, bude generovat vždy sejnou poloupnost čísel. Musí obsahovat ještě další patametr, jež se mění nezávisle na chodu MCU, jako je šum ADC, frekvence sítě, frekvence RTC, doba stisknutého tlačítka atd. atd.