Guest User

Untitled

a guest
Jan 24th, 2017
122
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*Main code by Igor Krepsky - www.frompinskto.wordpress.com
  2. based on fragments of code by Richard Visokey AD7C - www.ad7c.com
  3. Rev. 2.2 - Spt., 2016  for AD9851 chip.
  4. */
  5. // Подключение библиотек
  6. #include <rotary.h>
  7. #include <SPI.h>
  8. #include <Wire.h>
  9. #include <OLED_I2C.h>
  10.  
  11. OLED  myOLED(SDA, SCL, 8);
  12.  
  13. extern uint8_t SmallFont[];
  14.  
  15.  
  16.  
  17. //Определения
  18. #define W_CLK A2     // A2 - connect to AD9851 module word load clock pin (CLK)
  19. #define FQ_UD A3     // A3 - connect to freq update pin (FQ)
  20. #define DATA A6      // A4 - connect to serial data load pin (DATA)
  21. #define RESET A7     // A5 - connect to reset pin (RST)
  22. #define ENC_A 2      // Pin 2 - 1 канал валкодера
  23. #define ENC_B 3      // Pin 3 - 2 канал валкодера
  24. #define ENC_KEY 4    // Pin 4 - кнопка валкодера
  25. #define MODE_1 0     // Pin 0 - переключатель mode vfo
  26. #define MODE_2 1     // Pin 1 - переключатель mode sweep
  27. #define KEY_1 5      // Pin 5 - доп. кнопка
  28.  
  29. #define pulseHigh(pin) {digitalWrite(pin, HIGH); digitalWrite(pin, LOW); }
  30.  
  31. Rotary r = Rotary(2,3); // Устанавливает пины для каналов энкодера.  Должны поддерживать прерывания.
  32.  
  33.  
  34.  
  35. // Переменные
  36. int_fast32_t rx=1000000;        // Стартовая частота VFO
  37. int_fast32_t rif=0;             // Значение IF
  38. int_fast32_t wif=450000;        // рабочее значение IF
  39. int_fast32_t rx2=1;             // переменная для сохранения обновлённой частоты
  40. int_fast32_t increment = 1000;  // начальный VFO инкремент в HZ.
  41. int_fast32_t delta=1000;        // Стартовая величина ширины качания sweep в Hz
  42. int_fast32_t sstep=1;           // Стартовая величина шага качания sweep в Hz
  43. int buttonstate = 0;            // Переменная для чтения состояния кнопки
  44. String hertz = "1 KHz";
  45. int  hertzPosition = 0;
  46. byte ones,tens,hundreds,thousands,tenthousands,hundredthousands,millions ;  //Разряды для частоты
  47. byte a_1, a_2;            // разряды для отображения IF
  48. String freq;              // string для получения частоты
  49. boolean mod_1;            // текущее значение переключателя mode vfo
  50. boolean mod_1_old;        // сохранённое значение переключателя mode vfo
  51. boolean mod_2;            // текущее значение переключателя mode sweep
  52. boolean mod_2_old;        // сохранённое значение переключателя mode sweep
  53.  
  54.  
  55. void setup()   {
  56.   Serial.begin(9600);
  57.   myOLED.begin();
  58.   myOLED.setFont(SmallFont);
  59.   myOLED.clrScr();
  60.  
  61.  
  62.  
  63.   myOLED.print("AD9851 IS LOADING...", CENTER, 16);
  64.   myOLED.update();
  65.     delay(500);
  66.   myOLED.clrScr();
  67.  
  68. }
  69.  
  70. void loop() {
  71.  
  72.  
  73. // ИЗМЕНЕНИЕ ИНКРЕМЕНТА (кнопка валкодера)
  74.       buttonstate = digitalRead(ENC_KEY); // если нажатие кнопки валкодера - изменить инкремент
  75.       if(buttonstate == LOW) {
  76.       setincrement();      
  77.       }
  78. // ВОЗВРАТ ШАГА ИЗМЕНЕНИЯ ЧАСТОТЫ к 1КГЦ в РЕЖИМЕ ГЕНЕРАТОРА
  79.       if ((mod_1 == 1)&&(mod_2 == 1)){
  80.       buttonstate = digitalRead(KEY_1);
  81.       if (buttonstate == LOW){increment = 1000; hertz="1 KHz"; hertzPosition=0;
  82.        myOLED.print(hertz, LEFT, 0);
  83.        myOLED.update();
  84.       delay(250); // Adjust this delay to speed up/slow down the button menu scroll speed.
  85.       }
  86.       }  
  87. // ПЕРЕКЛЮЧАТЕЛЬ MODE
  88.       mod_1 = digitalRead (MODE_1); // чтение значения переключателя mode vfo.
  89.       mod_2 = digitalRead (MODE_2); // чтение значения переключателя mode sweep.
  90.      
  91. // ДЕЙСТВИЯ ПОСЛЕ ПЕРЕКЛЮЧЕНИЯ MODE
  92.       if ((mod_1 != mod_1_old)||(mod_2 != mod_2_old)){// если произошло переключение mode
  93.       // и вывод на дисплей
  94.      
  95.       // 1.очистка
  96.      
  97.      
  98.            
  99.       // 2.вывод значения
  100.      
  101.       if ((mod_1 == 1)&&(mod_2 == 1)){// если режим генератора
  102.         rif=0;
  103.  
  104.         myOLED.print("OSC.MODE:", LEFT, 8);
  105.         myOLED.update();
  106.       }
  107.  
  108.       if ((mod_1 == 1)&&(mod_2 == 0)){// если режим генератора с ПЧ
  109.         rif=wif;
  110.         sendFrequency(rx+rif);// отправить частоту в синтезатор
  111.        
  112.        myOLED.print(hertz, LEFT, 8);
  113.        myOLED.print("IF:", RIGHT, 8);
  114.        myOLED.update();
  115.         if (wif < 1000000){                      
  116.         myOLED.print(wif/1000, LEFT, 16);
  117.         myOLED.print("KHz", RIGHT, 16);
  118.         myOLED.update();}
  119.         else{
  120.         a_1 = ((wif/1000)%10);
  121.         a_2 = ((wif/100)%10);
  122.           myOLED.print(a_1, LEFT, 24);
  123.           myOLED.print(".", RIGHT, 24);
  124.           myOLED.print(a_2, LEFT, 32);
  125.           myOLED.print("MHz ", RIGHT, 32);
  126.           myOLED.update();}
  127.      
  128.        } delay(1000); myOLED.clrScr();
  129.                                                                          
  130.       if ((mod_1 == 0)&&(mod_2 == 1)){// если режим SWEEP
  131.       rif=0;
  132.      
  133.  
  134.       myOLED.print(hertz, LEFT, 40);
  135.       if (delta < 10000){
  136.       myOLED.print("  SWP:", RIGHT, 40);
  137.       myOLED.print(delta/1000, LEFT, 48);
  138.       myOLED.print("KHz ", RIGHT, 48);
  139.      
  140.       }
  141.       else if (delta >= 100000){
  142.       myOLED.print("  SWP:", RIGHT, 40);
  143.       myOLED.print(delta/1000, LEFT, 48);
  144.       myOLED.print("KHz ", RIGHT, 48);
  145.       }
  146.       else
  147.       {
  148.       myOLED.print("  SWP:", RIGHT, 40);
  149.       myOLED.print(delta/1000, LEFT, 48);
  150.       myOLED.print("KHz ", RIGHT, 48);
  151.       }
  152.       myOLED.update();
  153.       delay(2000);
  154.       }
  155.      
  156. // ВЫВОД НА ДИСПЛЕЙ ЧАСТОТЫ И ПЕРЕДАЧА ЕЁ В DDS ПОСЛЕ ПЕРЕКЛЮЧЕНИЯ MODE    
  157.       showFreq();
  158.       sendFrequency(rx+rif);
  159.       rx2 = rx;
  160.       mod_1_old = mod_1;
  161.       mod_2_old = mod_2;
  162.       }
  163. // ОКОНЧАНИЕ ДЕЙСТВИЯ ПОСЛЕ ПЕРЕКЛЮЧЕНИЯ MODE
  164.      
  165. // ВЫЧИСЛЕНИЕ ЧАСТОТЫ ДЛЯ РЕЖИМА SWEEP
  166.       if ((mod_1 == 0)&&(mod_2 == 1)){
  167.       rif = rif + sstep;
  168.       if (rif > delta) {rif = 0;}
  169.       sendFrequency(rx+rif);// отправить частоту в синтезатор
  170.       // переключение delta
  171.       buttonstate = digitalRead(KEY_1);
  172.       if (buttonstate == LOW) {
  173.       if (delta == 1000){delta = 5000;}
  174.       else if (delta == 5000){delta = 10000; sstep = 2;}
  175.       else if (delta == 10000){delta = 50000; sstep = 5;}
  176.       else if (delta == 50000){delta = 100000; sstep = 10;}
  177.       else {delta = 1000; sstep = 1;}
  178.       myOLED.clrScr();
  179.       if (delta < 10000){
  180.       myOLED.print("  SWP:", RIGHT, 40);
  181.       myOLED.print(delta/1000, LEFT, 48);
  182.       myOLED.print("KHz ", RIGHT, 48);
  183.      
  184.       }
  185.       else if (delta == 100000){
  186.       myOLED.print("  SWP:", RIGHT, 40);
  187.       myOLED.print(delta/1000, LEFT, 48);
  188.       myOLED.print("KHz ", RIGHT, 48);
  189.      
  190.       }
  191.       else
  192.       {
  193.       myOLED.print("  SWP:", RIGHT, 40);
  194.       myOLED.print(delta/1000, LEFT, 48);
  195.       myOLED.print("KHz ", RIGHT, 48);
  196.      
  197.       }
  198.       myOLED.update();
  199.       delay(500);
  200.       myOLED.update();}
  201.       }
  202. // ВЫЧИСЛЕНИЕ ЧАСТОТЫ ДЛЯ РЕЖИМА УЧЁТА ПРОМЕЖУТОЧНОЙ ЧАСТОТЫ
  203.       if ((mod_1 == 1)&&(mod_2 == 0)){
  204.       rif = wif;
  205.      
  206.       // переключение wif
  207.       buttonstate = digitalRead(KEY_1);
  208.       if (buttonstate == LOW) {
  209.       // нужные значения промежуточных частот прописываются здесь. при желании - как угодно много.
  210.       if (wif == 450000){wif = 455000;}
  211.       else if (wif == 455000){wif = 460000;}
  212.       else if (wif == 460000){wif = 465000;}
  213.       else if (wif == 465000){wif = 1600000;}
  214.       else if (wif == 1600000){wif = 1800000;}
  215.       else if (wif == 1800000){wif = 5500000;}
  216.       else if (wif == 5500000){wif = 10700000;}
  217.       else if (wif == 10700000){wif = 21400000;}
  218.       else {wif = 450000;}
  219.       sendFrequency(rx+rif);// отправить частоту в синтезатор
  220.      
  221.       if (wif < 1000000){
  222.       myOLED.print(" IF:", LEFT, 56);
  223.       myOLED.print(wif/1000, CENTER, 56);
  224.       myOLED.print("KHz ", RIGHT, 56);
  225.       else{
  226.        myOLED.print(" IF:", LEFT, 56);
  227.       myOLED.print(wif/1000, CENTER, 56);
  228.       myOLED.print("K ", RIGHT, 56);
  229.       }  
  230.       myOLED.update();
  231.       delay(250);
  232.        
  233.       }
  234.       }
  235.      
  236. // ВЫВОД НА ДИСПЛЕЙ ЧАСТОТЫ И ПЕРЕДАЧА ЕЁ В DDS В ОБЩЕМ СЛУЧАЕ
  237.          
  238.         if (rx != rx2)
  239.         {
  240.         showFreq();// при изменении частоты вывести на дисплей
  241.         sendFrequency(rx+rif);// отправить частоту в синтезатор
  242.         rx2 = rx;
  243.         }
  244.            
  245. }// END LOOP
  246.  
  247. // ПОДПРОГРАММЫ
  248.  
  249. // Обработка прерывания
  250. ISR(PCINT2_vect) {
  251.  
  252.     // обработка энкодера
  253.     unsigned char result = r.process();
  254.     if (result) {  
  255.     if (result == DIR_CW){rx=rx+increment;}
  256.     else {rx=rx-increment;};      
  257.     // конец обработки валкодера
  258.     if ((rx+rif) >60000000){rx=(60000000-rif);}; // ВЕРХНИЙ VFO LIMIT
  259.     if (rx <5){rx=5;}; // НИЖНИЙ VFO LIMIT
  260.     }
  261.     }
  262.    
  263. // расчёт частоты на основе докумментации на микросхему = <sys clock> * <frequency tuning word>/2^32
  264. void sendFrequency(double frequency) {
  265.   int32_t freq = frequency * 4294967296./180000000;  // note 180 MHz clock on 9851.
  266.   for (int b=0; b<4; b++, freq>>=8)
  267.   {
  268.    tfr_byte(freq & 0xFF);
  269.   }
  270.   tfr_byte(0x001);   // Final control byte, LSB 1 to enable 6 x xtal multiplier on 9851 set to 0x000 for 9850
  271.   pulseHigh(FQ_UD);  // Сделано!  Должен увидеть выход.
  272.   }
  273.  
  274. // передаёт байт, по биту за раз, начиная с LSB  на 9851 через serial DATA line
  275. void tfr_byte(byte data)
  276. {
  277.   for (int i=0; i<8; i++, data>>=1) {
  278.     digitalWrite(DATA, data & 0x01);
  279.     pulseHigh(W_CLK);   //после передачи каждого бита, CLK is pulsed high
  280.   }
  281. }
  282.  
  283. void setincrement(){// установка значения инкремента частоты
  284.   if(increment == 1){increment = 10; hertz = "10 Hz"; hertzPosition=0;}
  285.   else if(increment == 10){increment = 100; hertz = "100 Hz"; hertzPosition=0;}
  286.   else if (increment == 100){increment = 1000; hertz="1 Khz"; hertzPosition=0;}
  287.   else if (increment == 1000){increment = 10000; hertz="10 Khz"; hertzPosition=0;}
  288.   else if (increment == 10000){increment = 100000; hertz="100Khz"; hertzPosition=0;}
  289.   else if (increment == 100000){increment = 1000000; hertz="1 Mhz"; hertzPosition=0;}
  290.   else{increment = 1; hertz = "1 Hz"; hertzPosition=0;};
  291.    myOLED.clrScr();
  292.    myOLED.print(hertz, LEFT, 64);
  293.    myOLED.update();
  294.    delay(500); // Adjust this delay to speed up/slow down the button menu scroll speed.
  295. };
  296.  
  297. void showFreq(){// вывод значения частоты на дисплей
  298.     millions = int(rx/1000000);
  299.     hundredthousands = ((rx/100000)%10);
  300.     tenthousands = ((rx/10000)%10);
  301.     thousands = ((rx/1000)%10);
  302.     hundreds = ((rx/100)%10);
  303.     tens = ((rx/10)%10);
  304.     ones = ((rx/1)%10);
  305.     myOLED.clrScr();
  306.  
  307.    //if (millions > 9){display.setCursor(1,0);}
  308.   // else{display.setCursor(2,0);}
  309.     myOLED.print(millions, LEFT, 0);
  310.     myOLED.print(".", CENTER, 0);
  311.     myOLED.print(hundredthousands, RIGHT, 0);
  312.     myOLED.print(tenthousands, LEFT, 8);
  313.     myOLED.print(thousands, CENTER, 8);
  314.     myOLED.print(".", RIGHT, 8);
  315.     myOLED.print(hundreds, LEFT, 16);
  316.     myOLED.print(tens, CENTER, 16);
  317.     myOLED.print(ones, RIGHT, 16);
  318.     myOLED.print(" Mhz ", LEFT, 24);
  319.     myOLED.update();
  320.     delay(500);
  321.  
  322.  
  323. };
RAW Paste Data