kenwi

fftest.c

Mar 18th, 2015
480
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.83 KB | None | 0 0
  1. /*------------------------------------------------*/
  2. /* FFTEST : A test program for FFT module */
  3.  
  4. #include <string.h>
  5. #include <avr/io.h>
  6. #include <avr/pgmspace.h>
  7. #include <avr/interrupt.h>
  8. #include "ffft.h" /* Defs for using Fixed-point FFT module */
  9. #include "mydefs.h"
  10.  
  11. /*------------------------------------------------*/
  12. /* Global variables */
  13.  
  14. int16_t capture[FFT_N];
  15. complex_t bfly_buff[FFT_N];
  16. uint16_t spektrum[FFT_N/2];
  17. uint16_t pwm_setting[6];
  18. uint8_t counter[6];
  19. volatile uint8_t peak[6];
  20.  
  21. const uint16_t pwmtable_10[64] PROGMEM = { 0, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5,
  22. 5, 6, 6, 7, 8, 9, 10, 11, 12, 13, 15, 17,
  23. 19, 21, 23, 26, 29, 32, 36, 40, 44, 49, 55,
  24. 61, 68, 76, 85, 94, 105, 117, 131, 146, 162,
  25. 181, 202, 225, 250, 279, 311, 346, 386, 430,
  26. 479, 534, 595, 663, 739, 824, 918, 1023 };
  27.  
  28. /*------------------------------------------------*/
  29. /* Timer 1 Output COMPARE A Interrupt */
  30.  
  31. ISR( TIMER1_COMPA_vect ) {
  32. static uint16_t pwm_cnt = 0;
  33. uint8_t tmp = 0;
  34.  
  35. OCR1A += (uint16_t) T_PWM;
  36.  
  37. if(pwm_setting[0] > pwm_cnt) tmp |= LED1;
  38. if(pwm_setting[1] > pwm_cnt) tmp |= LED2;
  39. if(pwm_setting[2] > pwm_cnt) tmp |= LED3;
  40. if(pwm_setting[3] > pwm_cnt) tmp |= LED4;
  41. if(pwm_setting[4] > pwm_cnt) tmp |= LED5;
  42. if(pwm_setting[5] > pwm_cnt) tmp |= LED6;
  43.  
  44. LED_PORT = tmp;
  45.  
  46. if(pwm_cnt == (PWM_STEPS - 1))
  47. pwm_cnt = 0;
  48. else
  49. pwm_cnt++;
  50.  
  51. // muЯ aus Performancegrьnden leider mit in die ISR
  52. if((pwm_cnt == 512) || (pwm_cnt == 0)) {
  53. if(counter[0] == 0)
  54. if(peak[0]) peak[0]--; // LED's zurьckfaden
  55.  
  56. if(counter[1] == 0)
  57. if(peak[1]) peak[1]--;
  58.  
  59. if(counter[2] == 0)
  60. if(peak[2]) peak[2]--;
  61.  
  62. if(counter[3] == 0)
  63. if(peak[3]) peak[3]--;
  64.  
  65. if(counter[4] == 0)
  66. if(peak[4]) peak[4]--;
  67.  
  68. if(counter[5] == 0)
  69. if(peak[5]) peak[5]--;
  70.  
  71. }
  72. }
  73.  
  74. /*------------------------------------------------*/
  75. /* Capture waveform */
  76.  
  77. void capture_wave(int16_t *buffer, uint16_t count) {
  78. ADMUX = _BV(REFS0)|_BV(ADLAR)|_BV(MUX2)|_BV(MUX0); // channel
  79.  
  80. do {
  81. #if defined (__AVR_ATmega8__)
  82. ADCSRA = _BV(ADEN)|_BV(ADSC)|_BV(ADFR)|_BV(ADIF)|_BV(ADPS2)|_BV(ADPS1);
  83. #elif defined (__AVR_ATmega32__) || defined (__AVR_ATmega644__)
  84. ADCSRA = _BV(ADEN)|_BV(ADSC)|_BV(ADATE)|_BV(ADIF)|_BV(ADPS2)|_BV(ADPS1);
  85. #endif
  86. while(bit_is_clear(ADCSRA, ADIF));
  87. *buffer++ = ADC - 32768;
  88. } while(--count);
  89.  
  90. ADCSRA = 0;
  91. }
  92.  
  93. /*------------------------------------------------*/
  94. /* */
  95.  
  96. int main (void) {
  97. uint16_t s;
  98.  
  99. LED_DIR |= (LED1 | LED2 | LED3 | LED4 | LED5 | LED6);
  100. LED_PORT &= ~(LED1 | LED2 | LED3 | LED4 | LED5 | LED6);
  101.  
  102. TCCR1B = (1 << CS10); // Timer lдuft mit vollem Systemtakt
  103. TIMSK |= (1 << OCIE1A); // Interrupt freischalten
  104.  
  105. sei();
  106.  
  107. for(;;) {
  108. capture_wave(capture, FFT_N);
  109. fft_input(capture, bfly_buff);
  110. fft_execute(bfly_buff);
  111. fft_output(bfly_buff, spektrum);
  112.  
  113. // Array in benцtigter GrцЯe vor Wiederverwendung 'sдubern'
  114. memset(capture, 0, 12);
  115.  
  116. // Berechnung der einzelnen Bдnder, ohne zunдchst offensichtlichem System,
  117. // ergab sich so aus den Unzulдnglichkeiten des AD-Wandlers,
  118. // (hab's versucht, mit rosa Rauschen so in etwa hinzubiegen)
  119. for (uint8_t n = 0; n < FFT_N / 2; n++) {
  120. s = spektrum[n];
  121.  
  122. if(n == 0) { // tiefstes Frequenzband
  123. if(s <= SCORE_MAX) capture[0] = s;
  124. else capture[0] = SCORE_MAX;
  125. }
  126.  
  127. if((n >= 1) && (n <= 3)) {
  128. if((capture[1] + s) <= SCORE_MAX) capture[1] += s;
  129. else capture[1] = SCORE_MAX;
  130. }
  131.  
  132. if((n >= 4) && (n <= 11)) {
  133. if((capture[2] + s) <= SCORE_MAX) capture[2] += s;
  134. else capture[2] = SCORE_MAX;
  135. }
  136.  
  137. if((n >= 12) && (n <= 21)) {
  138. if((capture[3] + s) <= SCORE_MAX) capture[3] += s;
  139. else capture[3] = SCORE_MAX;
  140. }
  141.  
  142. if((n >= 22) && (n <= 34)) {
  143. if((capture[4] + s) <= SCORE_MAX) capture[4] += s;
  144. else capture[4] = SCORE_MAX;
  145. }
  146.  
  147. if((n >= 35) && (n <= 63)) { // hцchstes Frequenzband
  148. if((capture[5] + s) <= SCORE_MAX) capture[5] += s;
  149. else capture[5] = SCORE_MAX;
  150. }
  151. }
  152.  
  153. for(uint8_t y = 0; y < 6; y++) {
  154. if(capture[y] > THRESHOLD) capture[y] -= THRESHOLD; // Schwellwert abziehen
  155. else capture[y] = 0;
  156.  
  157. capture[y] /= 256; // Ergebnis teilen
  158.  
  159. if(capture[y] > 63) capture[y] = 63; // auf 64 Stufen begrenzen (Murphy's Law)
  160.  
  161. if(counter[y]) counter[y]--; // vor dem zurьckfaden der LED's etwas warten
  162.  
  163. if(capture[y] >= peak[y]) { // so 'ne Art PeakHold
  164. peak[y] = capture[y];
  165. counter[y] = 3;
  166. }
  167.  
  168. cli();
  169. pwm_setting[y] = pgm_read_word(&pwmtable_10[peak[y]]); // Helligkeitsstufe zuweisen
  170. sei();
  171. }
  172. }
  173. }
Advertisement
Add Comment
Please, Sign In to add comment