Перейти к содержимому

Фото
- - - - -

STM32 + Keil Получение случайного \ псевдослучайного числа


  • Вы не можете создать новую тему
  • Please log in to reply
14 ответов в этой теме

#1 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 23 января 2017 - 20:55

Застрял на пустом месте.

Не могу получить сколько нибудь приемлемое случайное число.

 

если просто пишу:

 

x = rand();  - даёт повтаряющуюся последовательность.

 

 

если добавляю:

 

#include <stdlib.h>
#include <time.h>

srand(time(NULL)); - не переваривает компилятор. 

 

RNG на борту нет. MK STM32F100RB  или  STM32F103C8T6TR

 

Нужно несложное решение или готовая функция которую переварит Keil.

Третьи сутки читаю тырнет, но там либо заумные криптовзломные алгоритмы, либо варианты того что написано выше и не работает.

 

 

 


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#2 Дык

Дык
  • Постоялец
  • 10 897 сообщений
  • Откуда:/dev/null

Отправлено 23 января 2017 - 23:06

Если я не ошибаюсь, rand() - это псевдо-случайный генератор (PRNG), т.е результат вычисления зависит от начального значения "seed".
Если его не задать, то оно берётся буквально с потолка (или вообще приравнивается к какой-нибудь константе) и ты всегда будешь получать одни и те же значения
Чтобы получать рандомные значения, надо выставить выставить seed. Вариант с srand правильный. На что ругается компилятор? 


  • 0

Вначале делаю, потом думаю :)


#3 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 23 января 2017 - 23:33

srand(time(NULL)); это и есть тот самый seed.
 
 
Ошибка компилятора:
 
Error: L6218E: Undefined symbol time (referred from main.o).
Not enough information to list image symbols.

  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#4 Вырвиглаз

Вырвиглаз

    Убийца травы

  • Постоялец
  • 15 928 сообщений
  • Откуда:Эстония, Таллин

Отправлено 24 января 2017 - 14:19

Не имея RTC трудно взять некое референсное значение для начала работы генератора. Я использовал шум ADC. Последние три-четыре разряда конвертера при висячей в воздухе ноге ловят невероятное количество шумов.


  • 0
Кто живет и грешит в Эстонии, тот опять родится в Эстонии.

#5 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 24 января 2017 - 17:50

Вырвиглаз, мне не нужноа идеальная случайность. Вариант с rand(); / srand(time(NULL)); меня вполне устроит. Пока не пойму мочему не компилируется с srand.  


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#6 Дык

Дык
  • Постоялец
  • 10 897 сообщений
  • Откуда:/dev/null

Отправлено 29 января 2017 - 00:36

Ну как, разобрался?))
Я думаю, что воспользоваться "time" ты не сможешь, потому что вендор его просто выпилил, ибо RTC на борту микроконтроллера так и так нет - время брать неоткуда. Поэтому и ругается. :)


  • 0

Вначале делаю, потом думаю :)


#7 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 29 января 2017 - 10:27

В данном случае костыль выглядит так: На старте задаю конкретный номер seed, потом в while (1) постоянно вызываю присвоение случайного числа во многих местах. Ну и когда вызываю в нужном месте с дальнейшим использованием результата там значения достаточно случайные. Для моих целей более чем хватает.

 

Но блин... никак не могу понять, почему с программирование stm32 такая жопа? Почему нужно по два дня курить мануал и даташиты чтобы запустить pwm через таймер на новом контроллере? То же самое кодится на ардуино за пол часа, на AVR за 2 часа...   Хочется работать с stm но, похоже, я не готов тратить гору времени на борьбу с их системой.  


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#8 Дык

Дык
  • Постоялец
  • 10 897 сообщений
  • Откуда:/dev/null

Отправлено 29 января 2017 - 11:32

Ха ))) Знакомо. :D Мне тоже надо было PWM запилить и тоже не мог понять - как оно связано с таймерами. Но ничего, потом понял. Даже тему на форуме тут создавал - можешь поискать, почитать. Спасибо Вырвиглазу - объяснил тогда. У меня, правда, STM8L был. Ардуино - это прекрасно, но имхо лучше знать на самом низком уровне, как оно всё устроено и работает. Сейчас ты с этим сражаешься яростно, а в конце будешь более годным инженером, имхо.


Сообщение изменено: Akhenaton (29 января 2017 - 11:34 )

  • 0

Вначале делаю, потом думаю :)


#9 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 29 января 2017 - 11:52

Инженером не буду, старый уже. Это хобби просто. На него времени и так мало остаётся, и уходит оно не на создание поделки а на борьбу с мельницами.


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#10 Вырвиглаз

Вырвиглаз

    Убийца травы

  • Постоялец
  • 15 928 сообщений
  • Откуда:Эстония, Таллин

Отправлено 29 января 2017 - 12:18

Ты как-нибудь заезжай в гости, я покажу, как все делать легко и быстро.

На самом деле ардуино - это молоток. Если тебе надо закрутить саморез, тебе все равно придется его забивать.

А STM32 - это цех с инструментом и рабочими, которые могут всё. Ты это потом поймешь.

Выделяй ячейку, храни в ней число, с каждым вызовом RAND инкременируй, при потере питания сохраняй во флеш.

Или сразу храни в backup регистре, если есть батарейка в RTC.


Ты еще не вкурил всю силу дебага в реальном времени. А потом запустишь RTOS, и будешь удивлен, какие возможности на самом деле имеет STM32 - это ведь целая платформа с минимальными усилиями для миграции. Переход всего проекта с Cortex M0 на Cortex M4 за 20 минут? Да за такие слова 10 лет назад программисты сожгли бы меня на костре. А теперь радуются.

STM32 - это не только RTOS, это еще и DSP с полным функционалом, быстрым FFT и кучей доп инструкций, которых тебе даже не надо учить. Это мощь в полном понимании этого слова.


  • 0
Кто живет и грешит в Эстонии, тот опять родится в Эстонии.

#11 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 29 января 2017 - 12:31

Вырвиглаз, тут видать сказывается мой очень начальный уровень программирования. Мне для самого простого проекта бывает сложно придумать алгоритм. С++ я знаю на 2 с минусом. Я понимаю что это можно закодить, сижу, читаю синтаксис. пробую. Вот последний пример:

 

Нужно плавно зажигать и гасить группу светодиодов. Работать пробую в связке Keil+CubeMix+Hal  на ютубе и в нете примеров достаточно. Выглядит всё примрно так:

        HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_1);
        HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_2);
        HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_3);
        HAL_TIM_PWM_Start(&htim4, TIM_CHANNEL_4);


 for(i=0;i<=65535 ;i++)
                {
TIM4->CCR1=i;

 for(d=0;d<300;d++)
{
}
                } 

Хрен с ним, что у меня таймер не 4 а 3 с этим я разобрался быстро. Но ССR1 !!! откуда мне знать что именно эта хрень привязана к каналу... итог - на моей плате светодиоды на 3 и 4 каналах таймера, соответственно ничего не работает,  а у меня нервный срыв от того что я такой тупой не могу лампочку зажечь. 

 

Что самое плохое, это то что есть гора нюансов. Настройки среды, настройки куба, параметры таймеров, каналы, режимы... и в любом месте может быть косяк. Не знаешь где искать = поиск длится безумно долго. 

 

Ну и мелочи конечно бесят в самом примитивном бейсике нормально можно случайное число получить, но не тут... 

Delay им тоже показался лишним - мутим циклы, задержка у которых зависит от частоты. 

Спрашивается НАКУЯ?

 

:) Налейте мне валерьянки. 


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#12 Вырвиглаз

Вырвиглаз

    Убийца травы

  • Постоялец
  • 15 928 сообщений
  • Откуда:Эстония, Таллин

Отправлено 29 января 2017 - 13:06

Давай разберемся по порядку.

ШИМ - это переферия, надстройка над таймером. Она берет значение таймера и сравнивает с регистром захвата. Дальше она выдает эвент, который мы должны соединить с нужным нам пином.

Т.е. чтобы увидеть импульсы на ноге, надо:

1. Настроить и запустить таймер

2. Подключить к этому таймеру шим

3. Вывести шим на ногу

 

Теперь про задержки. В HAL и SPL задержки есть и сделаны они очень грамотно - при любых возможных настройках генератора они четко отрабатывают свои микросекунды за счет применения системного таймера. Файлы  stm32f10x_systick.c и systick.c:

void delay_init(void)
{
    RCC_ClocksTypeDef RCC_ClocksStatus;

    RCC_GetClocksFreq(&RCC_ClocksStatus);
    SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);  /*Ñ¡ÔñÍⲿʱÖÓ  HCLK/8 */
	SysTick_ITConfig(DISABLE);
    delay_fac_us = RCC_ClocksStatus.HCLK_Frequency / 4000000;
    delay_fac_ms = RCC_ClocksStatus.HCLK_Frequency / 4000;      
}
					
/*******************************************************************************
* Function Name  : delay_us
* Description    : ³õʼ»¯ÑÓ³Ùº¯Êý 
* Input          : - Nus: ÑÓʱus
* Output         : None
* Return         : None
* Attention		 : ²ÎÊý×î´óֵΪ 0xffffff / (HCLK / 8000000)
*******************************************************************************/            
void delay_us(u32 Nus)
{ 
    SysTick_SetReload(delay_fac_us * Nus);          /* ʱ¼ä¼ÓÔØ */
    SysTick_CounterCmd(SysTick_Counter_Clear);		/* Çå¿Õ¼ÆÊýÆ÷ */
    SysTick_CounterCmd(SysTick_Counter_Enable);		/* ¿ªÊ¼µ¹Êý */ 	
    do
    {
        Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);
    }while (Status != SET);							/* µÈ´ýʱ¼äµ½´ï */
    SysTick_CounterCmd(SysTick_Counter_Disable);    /* ¹Ø±Õ¼ÆÊýÆ÷ */
	SysTick_CounterCmd(SysTick_Counter_Clear);	    /* Çå¿Õ¼ÆÊýÆ÷ */   
}


/*******************************************************************************
* Function Name  : delay_ms
* Description    : ³õʼ»¯ÑÓ³Ùº¯Êý 
* Input          : - nms: ÑÓʱms
* Output         : None
* Return         : None
* Attention		 : ²ÎÊý×î´óÖµ nms<=0xffffff*8*1000/SYSCLK ¶Ô72MÌõ¼þÏÂ,nms<=1864 
*******************************************************************************/  
void delay_ms(uint16_t nms)
{    
    uint32_t temp = delay_fac_ms * nms;

    if (temp > 0x00ffffff)
    {
        temp = 0x00ffffff;
    }
    SysTick_SetReload(temp);		             /* ʱ¼ä¼ÓÔØ */
    SysTick_CounterCmd(SysTick_Counter_Clear);	 /* Çå¿Õ¼ÆÊýÆ÷ */
    SysTick_CounterCmd(SysTick_Counter_Enable);	 /* ¿ªÊ¼µ¹Êý */ 
    do
    {
        Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);
    }while (Status != SET);				         /* µÈ´ýʱ¼äµ½´ï */
    SysTick_CounterCmd(SysTick_Counter_Disable); /* ¹Ø±Õ¼ÆÊýÆ÷ */
	SysTick_CounterCmd(SysTick_Counter_Clear);	 /* Çå¿Õ¼ÆÊýÆ÷ */
}

  • 0
Кто живет и грешит в Эстонии, тот опять родится в Эстонии.

#13 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 29 января 2017 - 13:21

Всё верно. Я и говорю про то, что шагов до результата много, уровень знания и понимания низкий. Интуитивно понятно хорошо если 10% кода.

Вот и гадаю - где накосячил?

 

С задержками попробую разобраться.  спасибо за код.


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu


#14 Вырвиглаз

Вырвиглаз

    Убийца травы

  • Постоялец
  • 15 928 сообщений
  • Откуда:Эстония, Таллин

Отправлено 29 января 2017 - 13:23

Потом наберется целый обоз своих наработок и библиотек. Проект будет тупо копи-пастится и процесс пойдет быстро.


  • 0
Кто живет и грешит в Эстонии, тот опять родится в Эстонии.

#15 BiHiTRiLL

BiHiTRiLL
  • Пользователь
  • 396 сообщений

Отправлено 29 января 2017 - 13:49

:D  ой, далеко ещё до этого


  • 0

¡ʁɐнεɐd ɐно - ɐɓʚɐdu