АЦП в качестве генератора случайных чисел
Доброго времени суток! Решил рассказать о простом и интересном способе получения честных случайных чисел на микроконтроллерах, не имеющих на борту аппаратного генератора случайных чисел. Достаточно, чтобы у микроконтроллера был АЦП и один свободный вход. Подробности под катом.Идея не нова и много кому приходила в голову. Я её реализовал в одном из своих старых проектов на STM8S003F3, так что примеры кода будут к этому чипу, хотя перенести код на любую другую архитектуру не составит труда.Суть заключается в том, что при измерении напряжения при помощи АЦП младшие биты результата наиболее подвержены шумам. Мы используем этот факт себе на пользу — будем делать несколько замеров, и записывать младший бит результата (как самый «шумный»). Таким образом сделав 8 измерений можно получить совсем случайный байт.
Ухудшим результаты измерения насколько это возможно. Установим наименьшее время выборки, а вывод микроконтроллера, на котором расположен вход АЦП, повесим «в воздухе», никуда не подтягивая и ни к чему не подключая. Чем больше шума — тем лучше.
Инициализация АЦП:
CLK_PCKENR2 |= 0×08; //Подаём тактирование на АЦП ADC_CR1 = MASK_ADC_CR1_ADON; //Включение ADC_CR2 = MASK_ADC_CR2_ALIGN; ADC_CR3 = 0; ADC_CSR = 4; //Выбор канала Функция получения случайного байта: unsigned char GetRandom (void) { unsigned char i, result;
result = 0; for (i = 0; i < 8; i++) { ADC_CR1 = MASK_ADC_CR1_ADON; //Старт преобразования while (ADC_CSR == 4); //Ждём установки флага окончания преобразования result = (result << 1) + (result & 0x01); ADC_CSR = 4; //Сбрасываем флаг окончания преобразования }
return result; } Вот такая небольшая хитрость. Код восстанавливал по памяти, так что могут быть ошибки — о них прошу написать в ЛС.Буду очень рад мнению опытных людей о таком способе получения случайных чисел.