Witam !
Mam taki programik napisany w Avr-gcc.
Kompilację przeszedł sprawnie, jednak podczas podglądu a Avr Studio, oraz pracy w procesorze z niewiadomych przyczyn nie wykonuje tych instrukcji:
chciałem w ten sposób zabezpieczyć się, żeby wysyłał na USART tylko raz tablicę spectrum. Co jest nie tak ? Dodam, że do konsoli nie docierają wogóle znaki 'FF'.
Mam taki programik napisany w Avr-gcc.
#include <avr/io.h>
#include <inttypes.h> //alternatywne typy zmiennych
#include <avr/pgmspace.h> //adresowanie zmiennych w obszarze programu
#include <avr/interrupt.h> //obsługa przerwań
#include <util/delay.h>
#include "ffft.h" //funkcje Fouriera
#include "usart.c" //obsługa USART
#define ADC_ON ADCSRA|= _BV(ADSC)|_BV(ADEN)|_BV(ADPS2)|_BV(ADPS0)
#define TIMER0_ON TCNT0 = 0x30
int16_t capture[FFT_N]; /* Wave capture buffer */
complex_t bfly_buff[FFT_N]; /* FFT buffer */
uint16_t spectrum[FFT_N/2]; /* Spectrum output buffer */
volatile uint8_t probka = 0; //zliczanie pobranych próbek
volatile uint8_t fla = 0;
//7 - bufor zapisany próbkami, dane gotowe do transmisji
//6 - trwa analiza Fouriera
//5 - trwa wysyłanie danych
//0 - zablokuj wysyłanie USART
#define f_buf_trans 7
#define f_analyze 6
#define f_usart_sending 5
#define f_usart_disable 0
void init(void){
//inicjalizacja trybu zliczania TIMERA 1--------------------------------------
//stan OC1A (PB1) zmieniany na przeciwny - generacja przebiegu 444 kHz
//na potrzeby filtra
DDRB = _BV(PINB1); //PB1 jako wyjście
OCR1A = 0x12; //załadowanie wartości do rejestru timera
TCCR1A = _BV(COM1A0) | _BV(FOC1A); //preskaler timera1=0; force output 1
TCCR1B = _BV(CS10) |_BV(WGM12); //tryb pracy CTC, resetowanie Timera 1 po każdym przepełnieniu
//inicjalizacja przetwornika ADC-----------------------------------------------
ADMUX = _BV(REFS0) | _BV(MUX2) | _BV(ADLAR); //wejście ADC4, pin PC4, wynik przesunięty do lewej
//konfiguracja Timera 0 - generacja przerwań 9,6 kHz wyzwalacjących próbkowanie ADC
//dla preskalera 8 musi odliczyć 208 razy
TIMER0_ON; //załadowanie wartości od której będzie odliczał - jeszcze 208 razy
TCCR0 = _BV(CS01); //ustawienie preskalera na 8
TIMSK = _BV(TOIE0); //zezwolenie na przerwania
sei(); //zezwolenie na przerwania
//Aktywacja USART-----------------------------------------------
UBRRL = 0x67; //transmisja 9600 dla kwarcu 16 MHz
UCSRB = (1<<RXEN)|(1<<TXEN);
UCSRC = _BV(URSEL)|_BV(UCSZ1)|_BV(UCSZ0);
}
ISR(SIG_OVERFLOW0){
TIMER0_ON;
ADC_ON;
while(!(ADCSRA & _BV(ADIF)));
capture[probka] = ADC;
++probka;
}
void send_usart(void){
if(!(fla & _BV(f_usart_disable))){
for(uint8_t i=0;i<FFT_N/2;i++){
while (!(UCSRA & (1 << UDRE)));
UDR = spectrum[i];
while (!(UCSRA & (1 << UDRE)));
UDR = (spectrum[i]>>8);
}
while (!(UCSRA & (1 << UDRE)));
UDR = 0xFF;
while (!(UCSRA & (1 << UDRE)));
UDR = 0xFF;
fla = _BV(f_usart_disable);
}
}
int main(void){
init();
while(1){
if(probka>FFT_N-1){ //jeśli zapełniłeś cały bufor wejściowy
probka=0; //zapełniaj od początku
fft_input(capture, bfly_buff); //przepisz do Fouriera
fft_execute(bfly_buff); //zrób Fouriera
fft_output(bfly_buff, spectrum); //zwróć wyniki obliczeń
send_usart();
}
}
return 0;
}
Kompilację przeszedł sprawnie, jednak podczas podglądu a Avr Studio, oraz pracy w procesorze z niewiadomych przyczyn nie wykonuje tych instrukcji:
while (!(UCSRA & (1 << UDRE)));
UDR = 0xFF;
while (!(UCSRA & (1 << UDRE)));
UDR = 0xFF;
fla = _BV(f_usart_disable);chciałem w ten sposób zabezpieczyć się, żeby wysyłał na USART tylko raz tablicę spectrum. Co jest nie tak ? Dodam, że do konsoli nie docierają wogóle znaki 'FF'.
