2
\$\begingroup\$

I am learning STM32F4 board. I want to get number between 0-15 using RNG. I can`t set boundaries to get that values.

Is there someone who has experienced with RNG or Can help me?

\$\endgroup\$
4
\$\begingroup\$

If you need an int use int bla = RNG_DR % 14 + 1 (yields a number between 0 and 15 (not including 0 and 15)); RNG_DR is the Data register of the RNG. You will need to check for the data ready flag to get valid values.

If you need something else, please specify :)

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I am sending output data to PC using Terminal software (board is connected to PC by Serial Port). I have done by this way. I am getting different kind of characters (like ASCII code). Sometimes there are number characters. How can I get exactly number? \$\endgroup\$ – Mamur Djurayev Dec 30 '12 at 12:42
  • \$\begingroup\$ RNG_Config(); uint32_t randomn=0; uint8_t necesnumber=0; while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET) { } randomn=RNG_GetRandomNumber(); necesnumber=(randomn%14)+1; Serial_PutChar(necesnumber); \$\endgroup\$ – Mamur Djurayev Dec 30 '12 at 12:43
  • \$\begingroup\$ Check asciitable.com. You need to convert the numbers to the appropriate ascii codes. I don't know how you output strings via the UART, but usually you would write something like: printf("%d", number); The %d then formats your number accordingly. Do you have a reference of your output functions somewhere? \$\endgroup\$ – Tom L. Dec 30 '12 at 16:20
  • 1
    \$\begingroup\$ Caution! Reducing the range of a random number generator using modulo (%) produces a biased random number, unless the RNG's output range size is divisible by the modulus. If you actually want numbers 0-15 inclusive, then RNG_DR % 16 is fine (given that RNG_DR has a range of 0…2^32-1, i.e. 32 bits), but modulo 14 is not OK (though the deviation will be small since the input range is large compared to the modulus). \$\endgroup\$ – Kevin Reid Dec 30 '12 at 17:08
  • \$\begingroup\$ @KevinReid: Thanks for the information. I wasn't aware of this but after some reading it makes sense. In case you need numbers from 1 to 14 (including these), how would you go calculating these numbers without a biased result? One idea I could think of was to just use numbers from 0...15 (which is divisable from the 2^32 range) and if the number is not within my range try it again? Is that a valid approach? \$\endgroup\$ – Tom L. Dec 30 '12 at 18:13
-1
\$\begingroup\$

There is my code

#include "main.h"


#define SW1 GPIO_Pin_9
#define SW2 GPIO_Pin_8
#define SW_IO GPIOB

void User_USART_Init()
{
  GPIO_InitTypeDef GPIO_InitStructure;
  USART_InitTypeDef USART_InitStructure;

  /* Enable GPIO clock */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  /* Enable UART clock */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

  /* Connect PXx to USARTx_Tx*/
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_USART1);

  /* Connect PXx to USARTx_Rx*/
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_USART1);

  /* Configure USART Tx as alternate function  */
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* Configure USART Rx as alternate function  */
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  USART_InitStructure.USART_BaudRate = 115200;
  USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  USART_InitStructure.USART_StopBits = USART_StopBits_1;
  USART_InitStructure.USART_Parity = USART_Parity_No;
  USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

  /* USART configuration */
  USART_Init(USART1, &USART_InitStructure);

  /* Enable USART */
  USART_Cmd(USART1, ENABLE);
}

void SendData(USART_TypeDef* USARTx, uint16_t Data)
{
  /* Check the parameters */
  assert_param(IS_USART_ALL_PERIPH(USARTx));
  assert_param(IS_USART_DATA(Data)); 

  /* Transmit Data */
  USARTx->DR = (Data & (uint16_t)0x01FF);
}

void Serial_PutChar(uint8_t c)
{
   while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
  {
  }
   SendData(USART1, c);
}

void Serial_PutString(uint8_t *s)
{
  while (*s != '\0')
  {
    Serial_PutChar(*s);
    s++;
  }
}

void RNG_Config (void)
{
 RCC_AHB2PeriphClockCmd(RCC_AHB2Periph_RNG, ENABLE);
 RNG_Cmd(ENABLE);
}

int main(void)
{
uint32_t random=0;
RCC_ClocksTypeDef RCC_Clocks;
RCC_GetClocksFreq(&RCC_Clocks);

  SysTick_Config(RCC_Clocks.HCLK_Frequency / 100);
  User_USART_Init();

//random number generator 
  RNG_Config();
while(1)
{
while(RNG_GetFlagStatus(RNG_FLAG_DRDY)== RESET)
      {
      }
random=RNG_GetRandomNumber()%16;
}
Serial_PutString("\n\r Your random Number\n\r");
Serial_PutChar(random);

}

There are some codes are skipped not to make a lot of lines.

Could you check if it is right or not? Thank you all, Happy New Year

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This will likely not work. I think you forgot the RNG_GetRandomNumber() function (what does it do exactely?). I suppose it returns an uint32 (or something similar) which you use then to do the module operation on. This will yield something between 0 and 15 (incl. these) and then you spit out that value. If you look up that value on asciitable.com you will see that you will be spitting out only special chars like EOT, STX, ... those will be picked up by the terminal program on the other side and the terminal application will try to display them. \$\endgroup\$ – Tom L. Dec 31 '12 at 9:18
  • 1
    \$\begingroup\$ It will fail to do so because those are not "real" characters but so called non-printables codes (control codes for "old" devices). To get something the terminal app can REALLY understand, you will need characters in the range from 48 to 57 (decimal, check the asciitable). \$\endgroup\$ – Tom L. Dec 31 '12 at 9:20
  • \$\begingroup\$ Is this the random number generator code? Please include only the specific code to solve the problem, explain it and - most important - verify it. \$\endgroup\$ – clabacchio Dec 31 '12 at 9:25
  • \$\begingroup\$ Now you have multiple options: 1) (nicest) You can build your custom version of printf (use va_args for that purpose) and feed the resulting char[]/string to your PutString function. 2) (easiest but not really recommended) Make a switch case statement that outputs the correct value for each number e.g. a value of 0 will output 48, 1 will output 49, ... 10 will output two characters (1 --> 49, 0 --> 48) and so on. \$\endgroup\$ – Tom L. Dec 31 '12 at 9:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.