Jak podłączyć ADC HX711 do NRF52832

1. Wprowadzenie

W porządku obrad znalazło się zadanie opracowania protokołu komunikacyjnego dla mikrokontrolera nrf52832 z dwoma półmostkowymi chińskimi tensometrami.

Zadanie okazało się niełatwe, gdyż borykałem się z brakiem jakichkolwiek zrozumiałych informacji. Bardziej prawdopodobne jest, że „korzeń zła” znajduje się w pakiecie SDK samego Nordic Semiconductor – ciągłe aktualizacje wersji, pewna redundancja i myląca funkcjonalność. Musiałem wszystko napisać od zera.

Myślę, że ten temat jest dość istotny, biorąc pod uwagę fakt, że ten chip ma stos BLE i cały zestaw „gadżetów” do trybu oszczędzania energii. Ale nie będę się zagłębiał w część techniczną, ponieważ na ten temat napisano wiele artykułów.

2. Opis projektu

Jak podłączyć ADC HX711 do NRF52832

Żelazo:

  • Adafruit Feather nRF52 Bluefruit LE (co akurat było pod ręką)
  • HX711 ADC
  • Tensometry chińskie 2 szt. (50x2kg)
  • Programista ST-LINK V2

Oprogramowanie:

  • IDE VSCODE
  • NRF SDK 16
  • OtwórzOCD
  • Programista ST-LINK V2

Wszystko jest w jednym projekcie, wystarczy zmodyfikować plik Makefile (określić lokalizację pakietu SDK).

3. Opis kodu

Wykorzystamy moduł GPIOTE do współpracy z urządzeniami peryferyjnymi w oparciu o wiązanie zadań i zdarzeń, a także moduł PPI do przesyłania danych z jednego urządzenia peryferyjnego na drugie bez udziału procesora.

ret_code_t err_code;
   err_code = nrf_drv_gpiote_out_init(PD_SCK, &config);//настраеваем на выход
   nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false);//будем передергивать пин для импульса
   err_code = nrf_drv_gpiote_out_init(PD_SCK, &config);//настраеваем на выход

Linię synchronizacyjną PD_SCL konfigurujemy na wyjściu tak, aby generowała impulsy o czasie trwania 10 μs.

   nrf_drv_gpiote_in_config_t  gpiote_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);// переход уровня с высокого на низкий
   nrf_gpio_cfg_input(DOUT, NRF_GPIO_PIN_NOPULL);// на вход без подтяжки
   err_code = nrf_drv_gpiote_in_init(DOUT, &gpiote_config, gpiote_evt_handler); 

static void gpiote_evt_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    nrf_drv_gpiote_in_event_disable(DOUT);//отключаем прерывание
    nrf_drv_timer_enable(&m_timer0);//включаем таймер
}
 

Konfigurujemy linię danych DOUT do odczytu stanu gotowości HX711; jeśli poziom jest niski, uruchamiana jest procedura obsługi, w której wyłączamy przerwanie i uruchamiamy timer w celu wygenerowania impulsów zegarowych na wyjściu PD_SCL.

 err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channel1);
   APP_ERROR_CHECK(err_code);
   err_code = nrf_drv_ppi_channel_assign(m_ppi_channel1,                                         nrf_drv_timer_event_address_get(&m_timer0, NRF_TIMER_EVENT_COMPARE0),                                           nrf_drv_gpiote_out_task_addr_get(PD_SCK));// подключаем таймер к выходу
   APP_ERROR_CHECK(err_code);
   err_code = nrf_drv_ppi_channel_enable(m_ppi_channel1);// включаем канал
   APP_ERROR_CHECK(err_code);
   nrf_drv_gpiote_out_task_enable(PD_SCK); 

// włącz gpiote

Następnie inicjujemy moduł PPI i podłączamy nasz timer do wyjścia PD_SCL, aby w przypadku wystąpienia zdarzenia porównawczego generować impulsy o czasie trwania 10 μs, a także włączamy moduł GPIOTE.


nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;// по умолчанию
   timer_cfg.frequency = NRF_TIMER_FREQ_1MHz;// тактируем на частоте 1Мгц
   ret_code_t err_code = nrf_drv_timer_init(&m_timer0, &timer_cfg, timer0_event_handler);
   APP_ERROR_CHECK(err_code);
   nrf_drv_timer_extended_compare(&m_timer0,
                                  NRF_TIMER_CC_CHANNEL0,
                                  nrf_drv_timer_us_to_ticks(&m_timer0,
                                                            10),
                                  NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK,
                                  true);// срабатывает по сравнению

Inicjujemy licznik zerowy i jego procedurę obsługi.

  if(m_counter%2 != 0 && m_counter<=48){
       buffer <<= 1;// переменная считанных даных
        c_counter++;// счетчик положительных  импульсов
           if(nrf_gpio_pin_read(DOUT))buffer++;//считываем состояние входа
   }

Najciekawsza rzecz dzieje się w procedurze obsługi timera. Okres impulsu wynosi 20 μs. Nas interesują impulsy nieparzyste (wzdłuż zbocza narastającego) i pod warunkiem, że ich liczba nie przekracza 24, a zdarzeń jest 48. Dla każdego zdarzenia nieparzystego odczytywany jest DOUT

Z arkusza danych wynika, że ​​liczba impulsów musi wynosić co najmniej 25, co odpowiada wzmocnieniu 128 (w kodzie użyłem 25 impulsów), co odpowiada 50 zdarzeniom timera, co oznacza koniec ramki danych.

 ++m_counter;// счетчик событий
if(m_counter==50){
      nrf_drv_timer_disable(&m_timer0);// отключаем таймер
       m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED;//
       buffer = buffer ^ 0x800000;
       hx711_stop();//jотключаем hx711
       }
   

Następnie wyłączamy timer, przetwarzamy dane (zgodnie z arkuszem danych) i przełączamy HX711 w tryb niskiego zużycia energii.


static void repeated_timer_handler(void * p_context)
{
   nrf_drv_gpiote_out_toggle(LED_2);
   if(m_simple_timer_state == SIMPLE_TIMER_STATE_STOPPED){
      	hx711_start();// включаем hx711
       nrf_drv_gpiote_out_toggle(LED_1);
       m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
   }
  
}
/**@brief Create timers.
*/
static void create_timers()
{
   ret_code_t err_code;
 
   // Create timers
   err_code = app_timer_create(&m_repeated_timer_id,
                               APP_TIMER_MODE_REPEATED,
                               repeated_timer_handler);
   APP_ERROR_CHECK(err_code);
}

Oczekujemy zdarzeń z timera RTC w odstępie 10 s (to zależy od Twojego uznania) i uruchamiamy HX711 w procedurze obsługi, powodując przerwanie na linii DOUT.

Jest jeszcze jeden punkt, logi są wyprowadzane przez UART (szybkość transmisji 115200, TX - 6 pinów, RX - 8 pinów) wszystkie ustawienia są w sdk_config.h

Jak podłączyć ADC HX711 do NRF52832

odkrycia

Dziękuję wszystkim za uwagę, mam nadzieję, że ten artykuł będzie przydatny i skróci cenny czas programistów na znalezienie rozwiązania. Chcę powiedzieć, że podejście techniczne, które Nordic stosuje w swoich platformach, jest dość interesujące z punktu widzenia efektywności energetycznej.

PS

Projekt jest jeszcze w fazie rozwoju, więc jeśli ten temat Cię zainteresuje, w kolejnym artykule postaram się opisać algorytm kalibracji czujników masy, a także podłączenia stosu BLE.

materiały

Źródło: www.habr.com

Dodaj komentarz