Koleżankom i Kolegom Radioamatorom, Krótkofalowcom,
Konstruktorom i Waszym Rodzinom – w tych trudnych czasach –
Zdrowych, Spokojnych i Pogodnych Świąt Bożego Narodzenia oraz
Szczęśliwego Nowego Roku

Życzy Zespół Home Made


Odpowiedz 
 
Ocena wątku:
  • 0 Głosów - 0 Średnio
  • 1
  • 2
  • 3
  • 4
  • 5
Sterowanie syntezą LM7001 z Arduino
SP7EZG Offline
Artur
***

Liczba postów: 195
Dołączył: 06-12-2015
Post: #11
RE: Sterowanie syntezą LM7001 z Arduino
Cytat:Widzisz dalej nie jest to jasne dla Ciebie. Dlaczego jeśli jest 0 to ma czekać ? Gdzie czeka ? i co czeka ?

No czeka, ustawia na porcie stan niski, i czeka (powinien - w domyślnej wersji programu) na takt CL. Po takcie CL synteza wie, który bit gdzie jest.

AND to koniunkcja. 1 i 1 = 1, ale 1 i 0 = 0. Dlatego if 'szuka' na numerze bitu (idx) wartości 1, jeśli 1 to stan wysoki, jeśli 0 stan niski.

Postać zapisu 0x0001 nie ma znaczenia, bo i to i tak jedynka, obojętnie od zapisu.

Dzięki za PW. Gdy będę miał warunki sprzyjające (w domu mam słaby internet) z przyjemnością się odezwę.

Pozdrawiam, Artur
25-02-2017 17:07
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SQ8MVY Offline
Paweł
****

Liczba postów: 724
Dołączył: 30-07-2011
Post: #12
RE: Sterowanie syntezą LM7001 z Arduino
(25-02-2017 17:07)SP7EZG napisał(a):  [quote]Widzisz dalej nie jest to jasne dla Ciebie. Dlaczego jeśli jest 0 to ma

Postać zapisu 0x0001 nie ma znaczenia, bo i to i tak jedynka, obojętnie od zapisu.

Oj nie do końca nie ma znaczenia. Tak 0x01, czy 0x0001 to jest tylko 1.
Tylko zwróć uwagę na jedną rzecz. Na typ danych !!!

0x01 to liczba 8 bitowa - uint8_t
0x0001 to liczba 16 bitowa - uint16_t

W tak prostym przykładzie pewnie nie ma to znaczenia czy będzie 0x01 czy 0x0001. Ale w rozbudowanych obliczeniach może napsuć krwi, bo kompilator będzie nieraz robił niejawne rzutowania typów danych.

Sam jestem bardzo początkującym w języku C, ale miałem już (nie)przyjemność szukać takich drobnostek związanymi z typami danych.
Ale odbiegamy chyba od tematu LM7001 troszkę...

73 Paweł
(Ten post był ostatnio modyfikowany: 25-02-2017 17:40 przez SQ8MVY.)
25-02-2017 17:40
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP7EZG Offline
Artur
***

Liczba postów: 195
Dołączył: 06-12-2015
Post: #13
RE: Sterowanie syntezą LM7001 z Arduino
Kod:
#define DATA 7
#define CL 6
#define CE 5


uint16_t Fpom = 1;
int Sterowanie = 255 ; //25 kHz10100000


void setup() {
pinMode(DATA, OUTPUT);
pinMode(CL, OUTPUT);
pinMode(CE, OUTPUT);
synteza();

}


void loop() {

}


void synteza(){
  
digitalWrite(CE, HIGH);
for( uint8_t idx=0; idx<14; idx++ ) //wysyłanie 14 bitów częstotliwości
{
   if ( ( Fpom >> idx ) & 0x0001 )
   {
      digitalWrite(DATA, HIGH);         // Pin DATA ustawiamy na 1
   } else
   {
      digitalWrite(DATA, LOW) ;         // Pin DATA ustawiamy na 0
   }
   zegarek(); // Generujemy impuls na linii CL
}
    digitalWrite(DATA, LOW); //wysłanie T0
    zegarek();
    digitalWrite(DATA, LOW); //wysłanie T1
    zegarek();
    
for( uint8_t idy=0; idy<8; idy++ ) //wysyłanie 14 bitów częstotliwości
{
   if ( ( Sterowanie >> idy ) & 0x01 )
   {
      digitalWrite(DATA, HIGH);        
   } else
   {
      digitalWrite(DATA, LOW) ;        
   }
   zegarek();
   digitalWrite(DATA, LOW);
}
  
   digitalWrite(CE, LOW);
  
  
}


void zegarek(){
  digitalWrite(CL, LOW);
  delay(10);
  digitalWrite(CL, HIGH);
  delay(10);
  digitalWrite(CL, LOW);
  delay(10);
}

I teraz problem w drugą stronę. Sterowanie przechodzi tylko jako postać dziesiętna korzystając z tej pętelki.

Pozdrawiam, Artur
25-02-2017 18:55
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SQ8MVY Offline
Paweł
****

Liczba postów: 724
Dołączył: 30-07-2011
Post: #14
RE: Sterowanie syntezą LM7001 z Arduino
(25-02-2017 18:55)SP7EZG napisał(a):  [code]
....
uint16_t Fpom = 1;
int Sterowanie = 255 ; //25 kHz10100000

....
....

...Sterowanie przechodzi tylko jako postać dziesiętna....

Nie rozumiem co miałeś na myśli z tą postacią dziesiętną..
Ale po kolei..

Wytłumacz mi, dlaczego Fpom ma wartość 1 ?

Sterowanie zadeklaruj jako uint8_t. Typ int jest tu bardzo na wyrost, a na dodatek jest to typ ze znakiem. Nie potrzeba w tym przypadku marnować pamięci.
Na dodatek zdajesz sobie sprawę, że wartość dziesiętna 255 to nie jest to samo co 0b10100000. Chyba, że komentarz został przez przypadek...

0b10100000 = 0xA0 = 160

Znasz sposoby zapisu w C liczb w postaci binarnej i szesnastkowej ?

zapis szesnastkowy poprzedzamy 0x,
zapis binarny - 0b,
oraz dziesiętny - bez żadnych dodatków.

Tak więc :
255 dzisiętnie, to 0xFF szesnastkowo oraz 0b11111111 w postaci binarnej.

73 Paweł
(Ten post był ostatnio modyfikowany: 25-02-2017 19:35 przez SQ8MVY.)
25-02-2017 19:35
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP7EZG Offline
Artur
***

Liczba postów: 195
Dołączył: 06-12-2015
Post: #15
RE: Sterowanie syntezą LM7001 z Arduino
Nie nie, nie sugeruj się zupełnie.

W komentarzu była wartość taka jak być powinna dla 25kHz, ale obie wartości były typowo dla próby. Podłączyłem w miejsce linii diody tak, by móc obserwować i liczyć bity.

255 binarnie to 11111111, więc od 17 bitu linia Data powinna świecić ciurkiem, i tak też się dzieje. CL ma 10 ms przesunięcia tak jak być powinno wg noty katalogowej.

Póki co wszystko jest okej, zaczynam się wdrażać w temat ustawiania kroku i częstotliwości.
Nie mogę sobie poradzić z hardware'owym problemem debouncingu enkodera, musze chyba wykorzystać inną bibliotekę.

Kod:
uint8_t Sterowanie = 0b10100000; //25 kHz10100000
]for( uint8_t idy=0; idy<8; idy++ ) //wysyłanie 14 bitów częstotliwości
{
   if ( ( Sterowanie << idy ) & 0x0001 )
   {
      digitalWrite(DATA, HIGH);        
   } else
   {
      digitalWrite(DATA, LOW) ;        
   }
   zegarek();
   digitalWrite(DATA, LOW);
}
  
   digitalWrite(CE, LOW);


Wygląda na to, że wartość nie jest zapisywana poprawnie. Na pin jest podawana jakby od najmłodszego bitu do najstarszego.



Pozdrówki.

Pozdrawiam, Artur
(Ten post był ostatnio modyfikowany: 25-02-2017 21:08 przez SP7EZG.)
25-02-2017 20:34
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SQ8MVY Offline
Paweł
****

Liczba postów: 724
Dołączył: 30-07-2011
Post: #16
RE: Sterowanie syntezą LM7001 z Arduino
(25-02-2017 20:34)SP7EZG napisał(a):  
Kod:
.......
   if ( ( Sterowanie << idy ) & 0x0001 )
......

Wygląda na to, że wartość nie jest zapisywana poprawnie.

Wcale się nie dziwię. Masz w wyrażeniu babola. Dlaczego przestawiłeś kierunek przesuwania bitów << w lewo ?? Jakiś konkretny cel miałeś ??

Jeżeli chcesz bity przesuwać w lewo to powinno to wyglądać tak:
Kod:
if( ( Sterowanie << idy ) & 0x8000 )
{....

Napisałem coś takiego na podstawie dokumentacji LM7001. Sprawdź sobie, bo mogą być błędy.
Kod:
#define DATA 7
#define CL 6
#define CE 5

#define KROK_100K 0b00000000
#define KROK_50K  0b00000100
#define KROK_25K  0b00000010
#define KROK_5K   0b00000110

#define StartFreq       5394        //StartFreq=(145550-10700)/25=5394


void setup()
{
  pinMode(DATA, OUTPUT);
  pinMode(CL, OUTPUT);
  pinMode(CE, OUTPUT);

  digitalWrite(CL, LOW);
  digitalWrite(CE, LOW);
  digitalWrite(DATA, LOW);

  synteza( StartFreq, KROK_25K );
}


void loop() {

}


void synteza( uint16_t Fpom, uint8_t krok )
{
  Fpom &= 0x3fff;  // Tu zadbamy o to, by bity 15 i 14 były zawsze wyzerowane

  uint32_t sterowanie = ( (uint32_t)1<<23 ) | ( (uint32_t)krok<<20 ) | ( (uint32_t)7<<16 ) | Fpom ;
  
  digitalWrite(CE, HIGH);

  for( uint8_t idx=0; idx<24; idx++ )
  {
    if( ( sterowanie >> idx ) & 0x00000001 )
    {
      digitalWrite(DATA, HIGH);        
    } else
    {
      digitalWrite(DATA, LOW) ;        
    }
    zegarek();
  }
  digitalWrite(CE, LOW);
  digitalWrite(DATA, LOW);
}


void zegarek()
{
  delay(10);
  digitalWrite(CL, HIGH);
  delay(10);
  digitalWrite(CL, LOW);
  delay(10);
}

Nie posiadam tego LM-a, więc są to moje przemyślenia. Kompiluje się prawidłowo. Działać chyba też powinno.

Funkcja synteza przyjmuje 2 parametry. Obliczony dzielnik dla częstotliwości, oraz krok strojenia.
W środku jest składana kompletna ramka, która jest wysyłana..

Co do enkodera. Tu najlepiej użyć przerwań, tak jak to jest zrobione w oryginale i koniecznie trzeba podłączyć enkoder poprzez prosty filtr RC.
Odpadnie wówczas problem z drganiem styków - jeżeli to enkoder mechaniczny.
Nie zapomnij oglądnąć i poczytać ten poradnik dotyczący enkodera

Gorąco polecam również pozostałe poradniki Pana Kardasia, bo widzę, że jesteś na samym początku drogi nauki programowania....

73 Paweł
(Ten post był ostatnio modyfikowany: 25-02-2017 21:59 przez SQ8MVY.)
25-02-2017 21:59
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP7EZG Offline
Artur
***

Liczba postów: 195
Dołączył: 06-12-2015
Post: #17
RE: Sterowanie syntezą LM7001 z Arduino
Witaj,


Na chwilę obecną funkcja sterująca syntezą wygląda tak


Kod:
void synteza(int frequency_to_dds){
  
  uint8_t Sterowanie;

switch (step_value)
{
  case 100:
  Sterowanie = 0b00000001;
  break;
  
  case 25:
  Sterowanie = 0b00000101;
  break;

   case 1:
  Sterowanie = 0b00001001;
  break;
}

pinMode(DATA, OUTPUT);
pinMode(CL, OUTPUT);
pinMode(CE, OUTPUT);
digitalWrite(CE, HIGH);
for( uint8_t idx=0; idx<14; idx++ ) //wysyłanie 14 bitów częstotliwości
{
   if ( ( frequency_to_dds >> idx ) & 0x0001 )
   {
      digitalWrite(DATA, HIGH);         // Pin DATA ustawiamy na 1
   } else
   {
      digitalWrite(DATA, LOW) ;         // Pin DATA ustawiamy na 0
   }
   zegarek(); // Generujemy impuls na linii CL
}
    digitalWrite(DATA, LOW); //wysłanie T0
    zegarek();
    digitalWrite(DATA, LOW); //wysłanie T1
    zegarek();
    
for( uint8_t idy=0; idy<8; idy++ ) //wysyłanie 8 bitów konfigu
{
   if ( ( Sterowanie >> idy ) & 0x0001 )
   {
      digitalWrite(DATA, HIGH);        
   } else
   {
      digitalWrite(DATA, LOW) ;        
   }
   zegarek();
   digitalWrite(DATA, LOW);
}
  
   digitalWrite(CE, LOW);

  
  
}

void zegarek(){
  digitalWrite(CL, LOW);
  delayMicroseconds(3);
  digitalWrite(CL, HIGH);
  delayMicroseconds(3);
  digitalWrite(CL, LOW);
  delayMicroseconds(3);
}


Została wypisana do Złomka z forum, głównie dlatego, że miałem podobną infrastrukturę, oraz chciałem złożyć próbny układ
Oczywiście się nie synchronizował.

Rzecz jasna książkę Pana Kardasia zamawiam jeszcze w tym tygodniu.

Pozdrawiam, Artur
(Ten post był ostatnio modyfikowany: 26-02-2017 12:27 przez SP7EZG.)
26-02-2017 12:26
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SQ8MVY Offline
Paweł
****

Liczba postów: 724
Dołączył: 30-07-2011
Post: #18
RE: Sterowanie syntezą LM7001 z Arduino
Witaj,

Widzisz, już powoli coś powstaje. Klocuszek po klocuszku.
Najważniejsze przy tym jest logiczne myślenie.

Złomek więc dostaje obsługę nowego VCO....

Co do kroku strojenia. Domyślną częstotliwością dla LM7001 jest chyba 7.2MHz. Aby uzyskać krok 8.33kHz trzeba ustawić krok w LM7001 na 9kHz i obniżyć odrobinę częstotliwość kwarcu. O jaką wartość trzeba obniżyć - metoda prób i błędów.

73 Paweł
26-02-2017 12:47
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
SP7EZG Offline
Artur
***

Liczba postów: 195
Dołączył: 06-12-2015
Post: #19
RE: Sterowanie syntezą LM7001 z Arduino
Tak! Póki co rozmontowałem układ (płytka stykowa) Niestety, jedyny dostępny pod ręką 5 MHz. Nie mam pewności, czy to czasami nie dlatego...
Zmontuję porządnie cały układ, uruchomię generator na NE602, i będę próbował, bo docelowo ma to pracować z heterodyną prostego odbiornika Airband.

Dziękuję Ci serdecznie za pomoc, naprawdę zmotywowałeś mnie do nauki C.

Pozdrawiam, Artur
26-02-2017 15:35
Znajdź wszystkie posty użytkownika Odpowiedz cytując ten post
Odpowiedz 


Skocz do:


Użytkownicy przeglądający ten wątek: 3 gości