# Setting RNG (Random Number Generator) boundries

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

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

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 :)

• 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? – Mamur Djurayev Dec 30 '12 at 12:42
• 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); – Mamur Djurayev Dec 30 '12 at 12:43
• 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? – Tom L. Dec 30 '12 at 16:20
• 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). – Kevin Reid Dec 30 '12 at 17:08
• @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? – Tom L. Dec 30 '12 at 18:13

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;
}
`