Skip to main content

04 Experiment

Use LFSR based random number generator to generate a random number and display it.

Source and description

http://sincgrid.in/avr-tutorials/avr-tutorial-experiment-4/

http://sincgrid.in/avr-tutorials/avr-tutorial-experiment-4/
#define F_CPU 16000000UL
#include <stdlib.h>
#include <avr/io.h>
#include <util/delay.h>

#define LFSR_SEED (91)

#define BAUDRATE 9600
#define BAUD_PRESCALLER (((F_CPU / (BAUDRATE * 16UL))) - 1)

uint16_t adc_value; //Variable used to store the value read from the ADC
char buffer[5]; //Output of the itoa function
uint8_t i=0; //Variable for the for() loop

void adc_init(void); //Function to initialize/configure the ADC
uint16_t read_adc(uint8_t channel); //Function to read an arbitrary analogic channel/pin
void USART_init(void); //Function to initialize and configure the USART/serial
void USART_send( unsigned char data); //Function that sends a char over the serial port
void USART_putstring(char* StringPtr); //Function that sends a string over the serial port



static uint16_t generate_lfsr_value(void)
{
static uint16_t cnt16 = LFSR_SEED;
return (cnt16 = (cnt16 >> 1) ^ (-(cnt16 & 1) & 0xB400));
}

int main(void)
{
USART_init(); //Setup the USART

/* loop */
while (1) {
uint16_t x= generate_lfsr_value();

USART_putstring("LFSR value = ");
itoa(x, buffer, 10); //Convert the read value to an ascii string
char * itoa ( int value, char * str, int base );
USART_putstring(buffer); //Send the converted value to the terminal
USART_putstring(" "); //Some more formatting
USART_send('\r');
USART_send('\n'); //This two lines are to tell to the terminal to change line


}
return 0;
}

void adc_init(void){
ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)); //16Mhz/128 = 125Khz the ADC reference clock
ADMUX |= (1<<REFS0); //Voltage reference from Avcc (5v)
ADCSRA |= (1<<ADEN); //Turn on ADC
ADCSRA |= (1<<ADSC); //Do an initial conversion because this one is the slowest
//and to ensure that everything is up and running
}

uint16_t read_adc(uint8_t channel){
ADMUX &= 0xF0; //Clear the older channel that was read
ADMUX |= channel; //Defines the new ADC channel to be read
ADCSRA |= (1<<ADSC); //Starts a new conversion
while(ADCSRA & (1<<ADSC)); //Wait until the conversion is done
return ADCW; //Returns the ADC value of the chosen channel
}

void USART_init(void){
UBRR0H = (uint8_t)(BAUD_PRESCALLER>>8);
UBRR0L = (uint8_t)(BAUD_PRESCALLER);
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
UCSR0C = (3<<UCSZ00);
}

void USART_send( unsigned char data){

while(!(UCSR0A & (1<<UDRE0)));
UDR0 = data;
}

void USART_putstring(char* StringPtr){

while(*StringPtr != 0x00){
USART_send(*StringPtr);
StringPtr++;}

}