Autor: Dondu
Czasami w projektach zachodzi potrzeba użycia liczb losowych. Na szczęście kompilatory języka C mają odpowiednie funkcje, które generują pseudo-losowe liczby. Podstawową funkcją losową jest funkcja rand() dostępna w bibliotece stdlib.
W kompilatorze GCC funkcja ta losuje liczby od 0 do RAND_MAX, który jest zdefiniowany na stałe jako 0x7FFF. Oznacza to, że rand() potrafi losować liczby z zakresu od 0 do 32767.
Rozwiązania zadania:
Zaletami rand() są przede wszystkim- Generator liczb losowych by Dondu
- Generator liczb losowych by miszcz310
- ... czekamy na inne propozycje.
- łatwość użycia
- nie wymaga wykorzystania żadnych wewnętrznych układów mikrokontrolera.
Wadami rand() są natomiast:
- pseudo-losowość (w końcu to jest tylko program, czyli jakiś algorytm),
- zajmuje sporo miejsca w pamięci programu.
Sporo miejsca to znaczy ile?
Spróbujmy to szybko sprawdzić:
#include <avr/io.h> volatile unsigned char liczba_RND; //wylosowana liczba int main(void) { while(1) { liczba_RND = 0; } }Taki kod zajmuje:
- Program: 430 bytes
- Data: 1 bytes
A teraz zobaczmy o ile wzrośnie gdy wykorzystamy funkcję rand():
#include <avr/io.h> #include <stdlib.h> volatile unsigned char liczba_RND; //wylosowana liczba int main(void) { while(1) { liczba_RND = rand(); } }Ten kod zajmuje:
- Program: 930 bytes
- Data: 5 bytes
Jak widzisz przede wszystkim wzrosło wykorzystanie pamięci programu i to aż o 500 bajtów (!).
Dlaczego aż tyle? Ponieważ kompilator do kodu wynikowego dołączył część biblioteki stdlib, która jest niezbędna, by móc korzystać z funkcji rand().
500 bajtów - to duża strata czy mała?
To zależy jaki mikrokontroler używasz i ile masz wolnej pamięci - czasami walczy się o kilkadziesiąt bajtów, a w skrajnych przypadkach o każdy bajt.
Jak to jest z tą losowością? Zobacz rozwiązania przedstawione powyżej. |
Co można zrobić, by cennej pamięci nie tracić?
I to jest właśnie następne zadanie z cyklu Efektywne Planowanie Projektu.
Cel:
Opracować alternatywny sposób uzyskania generatora liczb losowych z przedziału 0-255.
Warunki:
- ATmega8 z zegarem 8MHz,
- generator ma pracować w tle, a liczba losowa ma być dostępna w dowolnym momencie w zmiennej globalnej: liczba_RND,
- możesz wykorzystać dowolny wewnętrzny układ mikrokontrolera.
- możesz wykorzystać dodatkowe zewnętrzne elementy elektroniczne, ale priorytetem są: najniższy możliwy koszt i mała zajętość miejsca na PCB,
- strata pamięci programu musi być sporo mniejsza niż 500 bajtów,
- strata pamięci RAM także powinna być możliwie niewielka.
- pozostałe określone dla całego cyklu EPP: Efektywne Planowanie Projektu
Kod ma być w wersji "gołej" tzn. zawierać kompletny program, ale bez dodatkowych funkcji jak np. wyświetlanie na LCD (zobacz jak to jest w moim rozwiązaniu).
Termin:
Termin nadsyłania rozwiązań do:
Termin już upłynął, ale możesz przesłać swoje rozwiązanie, jeżeli jest ono inne niż opublikowane.
Chcę przesłać swoje rozwiązanie!
Wszelkie zasady znajdziesz tutaj: EPP: Zasady uczestnictwa i publikacji
Pytania
Jeżeli masz pytania dot. tego zadania, zadawaj je w tym temacie w formie komentarza, w ten sposób wszyscy będą mogli przeczytać pytanie i moją odpowiedź.
Dotychczasowi autorzy rozwiązań z cyklu EPP:
Listę autorów, którzy nadesłali swoje rozwiązania do któregoś z artykułów z cyklu EPP, możesz znaleźć tutaj: Autorzy rozwiązań
Witaj,
OdpowiedzUsuńCzyli mogę zrobić prosty generatorek szumów i nim traktować Atmegę?
Swoją drogą fajny pomysł z tym EPP.
Pozdro!
Cześć,
OdpowiedzUsuńOczywiście, że możesz i jest to zgodne z warunkami, które wymieniłem. Jest przy tym punkcie na czerwono tekst mówiący o tym, że koszt i zajętość miejsca na PCB powinny być minimalne - mam tu na myśli 1zł lub niewiele więcej :-)
oto moje podejście. słuchałem tego na 16 bitowym dacu i grało pięknie!
OdpowiedzUsuńpolecam i pozdrawiam :)
uint8_t rnd() {
static uint16_t s=0xaa,a=0;
s^=s<<3;
s^=s>>5;
s^=a++>>2;
return(s);
}
oto moje podejście. słuchałem tego na 16 bitowym dacu i grało pięknie :)
OdpowiedzUsuńuint8_t rnd() {
static uint16_t s=0xaa,a=0;
s^=s<<3;
s^=s>>5;
s^=a++>>2;
return(s);
}
ushort GetRand(ushort Mask)
OdpowiedzUsuń{
static ushort x;
uint y;
x = x + (ADC * ADC) + (ADC + (x<<3));
y = ((x & 0xff) * Mask) / 255;
return (ushort)y;
}
Twoja propozycja odnosi się do tego artykułu:
UsuńEPP: Generator liczb losowych by Dondu
i jest jednym z możliwych choć czasochłonnych rozwiązań.
To jest szybkie i w miarę lekkie:
OdpowiedzUsuńhttps://en.wikipedia.org/wiki/Linear-feedback_shift_register