Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki



Teraz jest 23 kwi 2024, o 17:05


Strefa czasowa: UTC + 1





Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 
Autor Wiadomość
PostNapisane: 13 gru 2012, o 19:47 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2012
Posty: 88
Pomógł: 2

Mam prosty kod w C który generuje częstotliwości, chce aby po każdym przerwaniu zwiększać częstotliwość o 1kHz. Przerwanie wykonuje się przy porównaniu z maksymalną wartością OCR1A. Kod musi być najprostszy bo każde linijki kodu powodują zmniejszenie rozdzielczości wyjściowej i dostaje "schodki" na wyjściu. Program wchodzi w pętle i generuje częstotliwość ale chce uzyskać efekt, że przerwanie zmienia zmienną częstotliwość i ta się zmienia zmienia na wyjściu.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


Jak najprościej zwiększyć częstotliwość w tym while? Próbowałem przez cały dzień wiele sposobów.

czy można ustawić w przerwaniu odpowiednią flagę, lub ustawić wskaźnik który zmieni wartość pod np. deltaphase podczas przerwania?

Moje ostatnie próby to:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Poprawiłem znaczniki [syntax=c ] a nie syntax= C :) SunRiver

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 gru 2012, o 10:03 
Offline
Uzytkownik zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 16 lip 2012
Posty: 2088
Lokalizacja: Leżajsk / Kraków
Pomógł: 411

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

A z tym #define resolution 16.2 to nie da się nic zrobić? Przecież wystarczy dać #define resolution 162 i podczas działań na fout wynik pomnożyć razy 10 albo lepiej najpierw pomnożyć razy 10UL i później podzielić przez resolution

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 14 gru 2012, o 22:17 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2012
Posty: 88
Pomógł: 2

dzięki Krauser działa, muszę popracować nad zmniejszeniem programu bo zajmuje już za dużo. Zaraz popatrzę na to resolution

teraz zamierzam dodać kolejne tabelę z innymi kształtami + zmiana tabeli po przejściu do częstotliwości granicznej.

edit
w przerwaniu po osiągnięciu maksymalnej częstotliwości zmieniam wartość zmiennej mode o jeden. Ma to na celu zmienić typ sygnału. O w tej linijce:
R2RPORT = pgm_read_byte(&sinewave[akumulator >> 8]); jak teraz optymalnie podmieniać pogrubione w zależności od mode

mode to volatile uint8_t mode=0; <- zmieniane w przerwaniu

wpadłem na pomysł zrobienia takiej tablicy
Kod:
const uint8_t *SIGNALS[] ={
   sinewave,
   squarewave,
   trianglewave,
   sawtoothwave,
   rewsawtoothwave,
   ECG
};


utworzeniu zmiennej globalnej uint8_t *wsk;, przypisania adresu wsk=&mode a następnie takiego odwołania R2RPORT = pgm_read_byte(&SIGNALS[*wsk][akumulator >> 8]);

Nie jestem dziś sprawdzić czy typ sygnału się zmienia, w pon będę miał dostęp do oscyloskopu.

No i dostaje przy wsk=&mode; warning assignment discards qualifiers from pointer target type

Może ktoś ma inny pomysł jak podmienić rodzaj sygnału najprościej.

każda podmiana w &SIGNALS[] w nawiasach kwadratowych jakąś zmienną powoduje spadek częstotliwości z 1kHz dla do 0.57kHz. Jak wpisze &SIGNALS[1] to jest równo 1kHz. Jak podmienić wartość w nawiasach bez spadku wydajność?

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 gru 2012, o 04:31 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2012
Posty: 88
Pomógł: 2

Czy to ma prawo działać bo nie mam przy sobie oscyloskopu aby sprawdzić a weekend jest długi aby czekać. Wklejam tylko potrzebne linijki kodu, które są kluczowe. Do rzucenia okiem jest ta pętla while, przerwanie, oraz wskażnik wsk oraz zmienia typ. 4 rzeczy dla specjalistów.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



Zostawiłem co potrzebne. Resztę kodu wyciąłem aby nikt nie musiał analizować i patrzeć na niepotrzebne.
Proszę mi odpowiedzieć czy zostanie w tej linijce R2RPORT = pgm_read_byte(&SIGNALS[typ][akumulator >> 8]); zmieniony sygnał np na kwadrat jak w przerwaniu częstotliwość dojdzie do 19kHz. Robię to w ten sposób bo każda inna zmiana jaką próbowałem BARDZO wpływa na częstotliwość wyjściową, po prostu ją obniża.

pgm_read_byte(&SIGNALS[typ][akumulator >> 8]); jak wpisze zamiast TYP:
1. np. 1 to działa super odwołując się do tablicy SIGNALS
2. jak dam tam zmienną zadeklarowaną w int main która to ma przypisane stałą wartość to również działa ok
3. Gdy zamiast typ wstawię wskaźnik do zmiennej mode która zmieniana jest w przerawniu to częstotliwość mi spada aż o POŁOWĘ :roll:
4. Gdy w przerwaniu będę zmieniał jakąś zmienną o 1 np mode po każdym przekroczeniu a potem tą zmienną użyję w SIGNALS[typ] zamiast typ to również częstotliwość mi spada.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 gru 2012, o 09:56 
Offline
Moderator
Avatar użytkownika

Dołączył(a): 03 paź 2011
Posty: 27225
Lokalizacja: Szczecin
Pomógł: 1041

powiedz mi po co takie sztuczki cyrkowe - w ogóle niepotrzebne

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



a potem w przerwaniu:

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.


nie mówię, że to jest błąd - ale widać, że próbujesz sobie w GIGANTYCZNY sposób utrudniać życie :( dlaczego nie możesz zmiennej typ zrobić globalnej i volatile. Nie dość że nie będziesz musiał jej zerować jawnie to jeszcze posługiwać się nią i w przerwaniu i funkcji main()

_________________
zapraszam na blog: http://www.mirekk36.blogspot.com (mój nick Skype: mirekk36 ) [ obejrzyj Kurs EAGLE ] [ mój kanał YT TV www.youtube.com/mirekk36 ]



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 gru 2012, o 11:52 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2012
Posty: 88
Pomógł: 2

już odpowiadam, a do tego wyżej to i tak chyba nie działa, bo przypisałem na twardo w przerwaniu *wsk=7; czyli coś poza tablicą i pętla leci dalej a nie powinna?

robię teraz tak jak Pan pisze ( jest jakiś sposób aby zapisać znak and - shift+7 na forum bo pojawia się właśnie &)
Kod:
volatile uint8_t typ=0;

Kod:
R2RPORT = pgm_read_byte(&SIGNALS[typ][akumulator >> 8]);

a w przerwaniu
Kod:
       
   typ++;
        if (typ>5) typ=0;


i częstotliwość mi spada dramatycznie, bo z zadanej 1kHz spada do 0.55kHz, czyli muszę znowu rozdzielczość obniżyć aby podnieść częstotliwość a to wiąże się z utratą ilości próbek na okres, czyli dostaje przysłowiowe "schodki". Chciałem zostawić resoulution na 16 i nie schodzić niżej a właśnie znaleźć sposób na tą zmianę rodzaju sygnału. Tego wyżej też próbowałem. Na koniec prób właśnie wyszły takie fikołki ze wskaźnikami.

Teraz przedstawię taki mój test. Umieszczam 3 rodzaje zmiennych:

1. volatile uint8_t typ1=0; zmienna globalna volatile
2. uint8_t typ2=0; zmienna globalna
3. uint8_t typ3=0; zmienna lokalna w main

i kolejno ręcznie podstawiam w linijce:
R2RPORT = pgm_read_byte(&SIGNALS[typ#][akumulator >> 8]);

I co uzyskuje na mierniku:
1. 0.55kHz
2. 0.78kHz
3. 1Khz

czyli to że zmienna jest globalna już powoduje mi spadek częstotliwości. Częstotliwość wyjściowa jest zależna od rozdzielczości a ta rozdzielczość od taktowania uC oraz ilości linijek kodu, więc widzicie Panowie, taka drobna zmiana i już mam gorszy sygnał.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 gru 2012, o 16:43 
Offline
Uzytkownik zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 16 lip 2012
Posty: 2088
Lokalizacja: Leżajsk / Kraków
Pomógł: 411

W 1 przypadku dostęp jest najwolniejszy bo skoro to zmienna z modyfikatorem volatile to może zmienić się w każdym momencie i co chwila jest odczytywana z pamięci do rejestrów. W drugim przypadku nie ma któregoś z odczytów, ale jak nie ma volatile to zmiana w przerwaniu nie zostanie zauważona przez pętlę główną. Trzeci przypadek zmienna lokalna jest przechowywana w rejestrze (chyba że jest ich dużo) i od razu można na niej wykonywać operacje. Powinieneś wszystkie operacje przeprowadzać w pętli głównej na zmiennych lokalnych. Możesz również spróbować dodać modyfikator register dla zmiennych do których dostęp ma być możliwie szybki.

Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 gru 2012, o 17:42 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2012
Posty: 88
Pomógł: 2

Krauser, próbowałem coś podobnego ale bez użycia register. Dodanie tylko dwóch linijek:
Kod:
typ++;
 if (typ>5) typ=0;

w pętli:
Kod:
          if(!check){
                 if (fout>19000){
                     fout=1000;
                     typ++; //zmiana o 1
                     if (typ>5) typ=0; // jeśli wartość wskaźnika jest większa niż 5 to zeruj
                    }
                    else fout=fout+1000;

                deltaPhase=(fout/resolution);
                check=~check;
                }

powoduje spadek zadanej częstotliwość fout=1000 z 1kHz do 0.57kHz

wszystkie ingerencje w zmianę typu sygnału powodują spadek częstotliwości. 2 linijki w C będę musiał nadrobić kwarcem 16MHz -> 24MHz w Atmega8 :mrgreen:

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 gru 2012, o 20:00 
Offline
Uzytkownik zasłużony dla forum.atnel.pl
Avatar użytkownika

Dołączył(a): 16 lip 2012
Posty: 2088
Lokalizacja: Leżajsk / Kraków
Pomógł: 411

Proponuję:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

zstąpić:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

a w warunku zmiany sygnału wypełniać temp_tab odpowiednią tablicą z pamięci programu:
Składnia: [ Pobierz ] [ Ukryj ]
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

Ta pętla for musi również znaleźć się na starcie programu.


Autor postu otrzymał pochwałę

_________________
Dragonus Cracovus: Biomagia



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 15 gru 2012, o 22:27 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2012
Posty: 88
Pomógł: 2

Częstotliwość zmienia się o zadaną w (!check), tylko częstotliwość startowa jest zła.
Ustawiłem w SIGNALS[0][i] czyli sinus i początkowa częstotliwość to ~7kHz. Jak dałem na stale kwadrat to zaczyna 1kHz. Krauser bardzo fajny pomysł z tym temp_tab. Nie wiem czemu tak sinusa zaczyna od tak wysokiej częstotliwości.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
PostNapisane: 17 gru 2012, o 18:50 
Offline
Użytkownik
Avatar użytkownika

Dołączył(a): 29 lis 2012
Posty: 88
Pomógł: 2

Ok temat wydaje mi się rozwiązany. Dziękuje Krauser za pomoc. Wyślę Ci na pw link do filmiku jak to wygląda.

_________________
sig off ;(



Góra
 Zobacz profil  
cytowanie selektywne  Cytuj  
Wyświetl posty nie starsze niż:  Sortuj wg  
Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 11 ] 

Strefa czasowa: UTC + 1


Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 3 gości


Nie możesz rozpoczynać nowych wątków
Nie możesz odpowiadać w wątkach
Nie możesz edytować swoich postów
Nie możesz usuwać swoich postów
Nie możesz dodawać załączników

Szukaj:
Skocz do:  
Sitemap
Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
phpBB SEO