/*
* DFT_on_AVR.c
*
* Created: 19-08-2016 11:02:32 PM
* Author : Akash Kollipara
*/
#define F_CPU 16000000UL
#define RS 2
#define EN 3
#include <avr/io.h>
#include <util/delay.h>
#include <math.h>
#include <avr/pgmspace.h>
//INITIALZATIONS
#define N 32 //#samples
uint16_t f[N], angle;
float cs, ss;
uint8_t x, k;
char pin;
char arr[8][8]=
{
{0, 0, 0, 0, 0, 0, 0, 31}, //L1
{0, 0, 0, 0, 0, 0, 31, 31}, //L2
{0, 0, 0, 0, 0, 31, 31, 31}, //L3
{0, 0, 0, 0, 31, 31, 31, 31}, //L4
{0, 0, 0, 31, 31, 31, 31, 31}, //L5
{0, 0, 31, 31, 31, 31, 31, 31}, //L6
{0, 31, 31, 31, 31, 31, 31, 31}, //L7
{31, 31, 31, 31, 31, 31, 31, 31} //L8
};
//PRTOTYPING
//LCD FUNCTIONS
void lcd_init();
void cmd(char);
void Data(char);
void lcd_clear();
void lcd_printc(char);
void lcd_prints(char *);
void lcd_cust_char(char, char *);
void lcd_setCursor(char, char);
//ADC FUNCTIONS
void adc_init();
uint16_t analogRead();
//BOOTUP
void bootup();
const int16_t cosine_lookup[] PROGMEM =
{
1000, 980, 923, 831, 707, 555, 382, 195, 0, -195, -382, -555, -707, -831, -923, -980, -1000, -980, -923, -831, -707, -555, -382, -195, 0, 195, 382, 555, 707, 831, 923, 980, 1000, 923, 707, 382, 0, -382, -707, -923, -1000, -923, -707, -382, 0, 382, 707, 923, 1000, 923, 707, 382, 0, -382, -707, -923, -1000, -923, -707, -382, 0, 382, 707, 923, 1000, 831, 382, -195, -707, -980, -923, -555, 0, 555, 923, 980, 707, 195, -382, -831, -1000, -831, -382, 195, 707, 980, 923, 555, 0, -555, -923, -980, -707, -195, 382, 831, 1000, 707, 0, -707, -1000, -707, 0, 707, 1000, 707, 0, -707, -1000, -707, 0, 707, 999, 707, 0, -707, -1000, -707, 0, 707, 1000, 707, 0, -707, -1000, -707, 0, 707, 1000, 555, -382, -980, -707, 195, 923, 831, 0, -831, -923, -195, 707, 980, 382, -555, -1000, -555, 382, 980, 707, -195, -923, -831, 0, 831, 923, 195, -707, -980, -382, 555, 1000, 382, -707, -923, 0, 923, 707, -382, -1000, -382, 707, 923, 0, -923, -707, 382, 1000, 382, -707, -923, 0, 923, 707, -382, -1000, -382, 707, 923, 0, -923, -707, 382, 1000, 195, -923, -555, 707, 831, -382, -980, 0, 980, 382, -831, -707, 555, 923, -195, -1000, -195, 923, 555, -707, -831, 382, 980, 0, -980, -382, 831, 707, -555, -923, 195, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 999, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 1000, -195, -923, 555, 707, -831, -382, 980, 0, -980, 382, 831, -707, -555, 923, 195, -1000, 195, 923, -555, -707, 831, 382, -980, 0, 980, -382, -831, 707, 555, -923, -195, 1000, -382, -707, 923, 0, -923, 707, 382, -1000, 382, 707, -923, 0, 923, -707, -382, 1000, -382, -707, 923, 0, -923, 707, 382, -1000, 382, 707, -923, 0, 923, -707, -382, 1000, -555, -382, 980, -707, -195, 923, -831, 0, 831, -923, 195, 707, -980, 382, 555, -1000, 555, 382, -980, 707, 195, -923, 831, 0, -831, 923, -195, -707, 980, -382, -555, 1000, -707, 0, 707, -1000, 707, 0, -707, 1000, -707, 0, 707, -1000, 707, 0, -707, 1000, -707, 0, 707, -1000, 707, 0, -707, 1000, -707, 0, 707, -1000, 707, 0, -707, 1000, -831, 382, 195, -707, 980, -923, 555, 0, -555, 923, -980, 707, -195, -382, 831, -1000, 831, -382, -195, 707, -980, 923, -555, 0, 555, -923, 980, -707, 195, 382, -831, 1000, -923, 707, -382, 0, 382, -707, 923, -1000, 923, -707, 382, 0, -382, 707, -923, 1000, -923, 707, -382, 0, 382, -707, 923, -1000, 923, -707, 382, 0, -382, 707, -923, 1000, -980, 923, -831, 707, -555, 382, -195, 0, 195, -382, 555, -707, 831, -923, 980, -1000, 980, -923, 831, -707, 555, -382, 195, 0, -195, 382, -555, 707, -831, 923, -980, 1000, -1000, 1000, -1000, 999, -1000, 1000, -1000, 1000, -1000, 1000, -1000, 1000, -1000, 1000, -1000, 1000, -1000, 1000, -1000, 1000, -1000, 1000, -999, 1000, -1000, 1000, -1000, 1000, -999, 1000, -1000
};
const int16_t sine_lookup[] PROGMEM =
{
0, 195, 382, 555, 707, 831, 923, 980, 1000, 980, 923, 831, 707, 555, 382, 195, 0, -195, -382, -555, -707, -831, -923, -980, -1000, -980, -923, -831, -707, -555, -382, -195, 0, 382, 707, 923, 1000, 923, 707, 382, 0, -382, -707, -923, -1000, -923, -707, -382, 0, 382, 707, 923, 999, 923, 707, 382, 0, -382, -707, -923, -1000, -923, -707, -382, 0, 555, 923, 980, 707, 195, -382, -831, -1000, -831, -382, 195, 707, 980, 923, 555, 0, -555, -923, -980, -707, -195, 382, 831, 1000, 831, 382, -195, -707, -980, -923, -555, 0, 707, 1000, 707, 0, -707, -1000, -707, 0, 707, 999, 707, 0, -707, -1000, -707, 0, 707, 1000, 707, 0, -707, -1000, -707, 0, 707, 1000, 707, 0, -707, -1000, -707, 0, 831, 923, 195, -707, -980, -382, 555, 999, 555, -382, -980, -707, 195, 923, 831, 0, -831, -923, -195, 707, 980, 382, -555, -1000, -555, 382, 980, 707, -195, -923, -831, 0, 923, 707, -382, -1000, -382, 707, 923, 0, -923, -707, 382, 1000, 382, -707, -923, 0, 923, 707, -382, -1000, -382, 707, 923, 0, -923, -707, 382, 1000, 382, -707, -923, 0, 980, 382, -831, -707, 555, 923, -195, -1000, -195, 923, 555, -707, -831, 382, 980, 0, -980, -382, 831, 707, -555, -923, 195, 1000, 195, -923, -555, 707, 831, -382, -980, 0, 1000, 0, -1000, 0, 999, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 1000, 0, -1000, 0, 980, -382, -831, 707, 555, -923, -195, 1000, -195, -923, 555, 707, -831, -382, 980, 0, -980, 382, 831, -707, -555, 923, 195, -1000, 195, 923, -555, -707, 831, 382, -980, 0, 923, -707, -382, 999, -382, -707, 923, 0, -923, 707, 382, -1000, 382, 707, -923, 0, 923, -707, -382, 1000, -382, -707, 923, 0, -923, 707, 382, -1000, 382, 707, -923, 0, 831, -923, 195, 707, -980, 382, 555, -1000, 555, 382, -980, 707, 195, -923, 831, 0, -831, 923, -195, -707, 980, -382, -555, 1000, -555, -382, 980, -707, -195, 923, -831, 0, 707, -1000, 707, 0, -707, 1000, -707, 0, 707, -1000, 707, 0, -707, 1000, -707, 0, 707, -1000, 707, 0, -707, 1000, -707, 0, 707, -999, 707, 0, -707, 999, -707, 0, 555, -923, 980, -707, 195, 382, -831, 1000, -831, 382, 195, -707, 980, -923, 555, 0, -555, 923, -980, 707, -195, -382, 831, -1000, 831, -382, -195, 707, -980, 923, -555, 0, 382, -707, 923, -1000, 923, -707, 382, 0, -382, 707, -923, 1000, -923, 707, -382, 0, 382, -707, 923, -1000, 923, -707, 382, 0, -382, 707, -923, 999, -923, 707, -382, 0, 195, -382, 555, -707, 831, -923, 980, -1000, 980, -923, 831, -707, 555, -382, 195, 0, -195, 382, -555, 707, -831, 923, -980, 999, -980, 923, -831, 707, -555, 382, -195, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
//MAIN
int main(void)
{
bootup();
while(1)
{
for(k = 0; k < N; k++)
f[k] = analogRead(); //fetch samples
for(k = 0; k < N/2; k++)
{
cs = ss = 0;
for(x = 0; x < N; x++)
{
angle = x + (32*k);
cs += (float)f[x]*(int16_t)pgm_read_word(&cosine_lookup[angle]); //real part of dft
ss += (float)f[x]*(int16_t)pgm_read_word(&sine_lookup[angle]); //imaginary part of dft
}
cs /= N*1000;
ss /= N*1000;
x = (uint8_t)sqrt((cs*cs)+(ss*ss)); //absolute value of dft
x /= 2; //scaling
x++;
if(x > 16) x = 16;
if(x < 9)
{
lcd_setCursor(k, 0);
lcd_printc(' ');
lcd_setCursor(k, 1);
lcd_printc(x);
}
else
{
lcd_setCursor(k, 1);
lcd_printc(8);
lcd_setCursor(k, 0);
lcd_printc(x-8);
}
}
if(!(PINB & 0x01) && ((pin & 0x80) == 0x00))
{
pin |= 0x80;
pin++;
if((pin & 0x0f)>1) pin &= 0xf0;
switch((pin & 0x0f))
{
case 0:
{
ADCSRA = 0x86;
lcd_clear();
lcd_setCursor(2, 0);
lcd_prints("560 - 8960 Hz");
_delay_ms(1000);
break;
}
case 1:
{
ADCSRA = 0x87;
lcd_clear();
lcd_setCursor(2, 0);
lcd_prints("280 - 4480 Hz");
_delay_ms(1000);
break;
}
}
}
else if((pin & 0x80) && ((PINB & 0x01)))
{
pin &= 0x7f;
}
}
return 0;
}
//bootup functions
void bootup()
{
PORTB = 0x01; //internal pull-up
DDRD = 0xfc; //set o/p port for LCD
adc_init();
_delay_ms(1);
lcd_init();
for(k = 0; k < 8; k++)
lcd_cust_char((k+1), arr[k]); //load custom characters
lcd_clear();
}
//SYSTEM FUNCTIONS
void adc_init()
{
ADCSRA = 0x86;
ADMUX = 0x40;
}
uint16_t analogRead()
{
uint16_t adcl, adch;
ADCSRA |= (1<<ADSC);
while((ADCSRA & (1<<ADSC)));
adcl = ADCL;
adch = ADCH;
return((adch<<8)|adcl);
}
void lcd_init()
{
cmd(0x28); //2->4-bit mode, 8->2-line disp mode
_delay_ms(1);
cmd(0x28); //2->4-bit mode, 8->2-line disp mode
_delay_ms(1);
cmd(0x0c);
_delay_ms(1);
cmd(0x06);
_delay_ms(1);
cmd(0x80);
_delay_ms(1);
lcd_clear();
}
void cmd(char comm)
{
PORTD = (comm & 0xf0) | (1<<EN);
PORTD = (comm & 0xf0) & (~(1<<EN));
PORTD = ((comm << 4) & 0xf0) | (1<<EN);
PORTD = ((comm << 4) & 0xf0) & (~(1<<EN));
_delay_us(1150);
}
void lcd_clear()
{
cmd(0x01);
}
void lcd_printc(char c)
{
Data(c);
}
void lcd_prints(char *arr)
{
for(uint8_t i = 0; arr[i] != '\0'; i++)
Data(arr[i]);
}
void Data(char comm)
{
PORTD = (comm & 0xf0) | (1<<EN) | (1<<RS);
PORTD = ((comm & 0xf0) & (~(1<<EN))) | (1<<RS);
PORTD = ((comm<<4) & 0xf0) | (1<<EN) | (1<<RS);
PORTD = (((comm<<4) & 0xf0) & (~(0<<EN))) | (1<<RS);
_delay_us(100);
}
void lcd_cust_char(char i, char *arr)
{
cmd(0x40 | (8*i));
for(int j = 0; j <8; j++)
Data(arr[j]);
cmd(0x80);
}
void lcd_setCursor(char x, char y)
{
if(y)
cmd(0x80 + 0x40 + x);
else if(!y)
cmd(0x80 + x);
}
Comments
Please log in or sign up to comment.