Hogyan csatlakoztassuk a HX711 ADC-t az NRF52832-hez

1. Bevezetés

A feladat az nrf52832 mikrovezérlő kommunikációs protokolljának kidolgozása volt két kínai feszültségérzékelőn keresztül.

A feladat nem volt egyszerű, mivel szembe kellett nézni azzal, hogy nem volt egyértelmű információ. Valószínűleg a 'gonosz gyökere' magában a Nordic Semiconductor SDK-jában rejlik - a folyamatos verziófrissítések, a némi redundancia és a funkciók összezavarodottsága miatt. Mindennek nulláról kellett nekifutnom.

Azt hiszem, ez a téma elég aktuális, mivel ez a chip BLE stack-kel és számos 'finomsággal' rendelkezik az energiatakarékos üzemmódban. De a technikai részbe nem akarok túl mélyen belemerülni, mivel erről a témáról sok cikket írtak.

2. A projekt leírása

Hogyan csatlakoztassuk a HX711 ADC-t az NRF52832-hez

Hardver:

  • Adafruit Feather nRF52 Bluefruit LE (ami éppen kéznél volt)
  • HX711 ADC
  • 2 db kínai feszültségérzékelő (50x2 kg)
  • ST-LINK V2 programozó

Szoftver:

  • IDE VSCODE
  • NRF SDK 16
  • OpenOCD
  • ST-LINK V2 programozó

Minden egy projektben található, csak a Makefile-t kell kicsit módosítani (megadni a SDK elérési útját).

3. A kód leírása

A perifériával való munka során a GPIOTE modult fogjuk használni a feladatok és események kötése alapján, valamint a PPI modult az adatok egy perifériáról a másikra való átviteléhez a processzor közreműködése nélkül.

ret_code_t err_code;
   err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // kimenetre állítjuk
   nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); // a lábat fogjuk késleltetni az impulzusokhoz
   err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // kimenetre állítjuk

A PD_SCL szinkronizáló vonalat kimenetre állítjuk, hogy 10 μs hosszúságú impulzusokat generáljon.

   nrf_drv_gpiote_in_config_t gpiote_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false); // a magas szintről alacsony szintre való váltás
   nrf_gpio_cfg_input(DOUT, NRF_GPIO_PIN_NOPULL); // bemeneti állapot, felhúzás nélkül
   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); // az megszakítást letiltjuk
    nrf_drv_timer_enable(&m_timer0); // a timert bekapcsoljuk
}
 

A DOUT adatvonalat állítjuk be az HX711 készenlét állapotának ellenőrzésére, alacsony szintű jel esetén aktiválódik az eseménykezelő, amely letiltja az megszakítást és elindítja a timert a PD_SCL kimeneti szinkronizáló impulzusok generálásához.

 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));// kapcsoljuk a timert a kimenetre
   APP_ERROR_CHECK(err_code);
   err_code = nrf_drv_ppi_channel_enable(m_ppi_channel1);// engedélyezzük a csatornát
   APP_ERROR_CHECK(err_code);
   nrf_drv_gpiote_out_task_enable(PD_SCK); 

// включаем gpiote

Ezután inicializáljuk a PPI modult, és összekapcsoljuk a timerünket a PD_SCL kimenettel, hogy 10 µs hosszúságú impulzusokat generáljunk, amikor a hasonlítási esemény bekövetkezik, valamint engedélyezzük a GPIOTE modult.


nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;// alapértelmezett
   timer_cfg.frequency = NRF_TIMER_FREQ_1MHz;// 1 MHz-en működik
   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);// a hasonlítás alapján aktiválódik

Inicializáljuk a nulla timert és annak kezelőjét.

  if(m_counter%2 != 0 && m_counter<=48){
       buffer <<= 1;// a beolvasott adatok változója
        c_counter++;// pozitív impulzusok számlálója
           if(nrf_gpio_pin_read(DOUT))buffer++;// beolvassuk a bemenet állapotát
   }

A legérdekesebb dolog a timer kezelőben történik. Az impulzusok periódusa 20 µs. Azokat az páratlan impulzusokat keressük (felfelé átlépő élen), és annak a feltételnek megfelelően, hogy ezek száma nem haladja meg a 24, valamint az események száma 48. Minden páratlan eseménynél beolvassuk a DOUT-ot.

A datasheetből következik, hogy az impulzusok száma legalább 25 kell legyen, ami 128-as erősítési aránynak felel meg (a kódban 25 impulzust használtam), ez 50 timer eseménynek felel meg, ami a dátumkeret végét jelzi.

 ++m_counter;// az események számlálója
if(m_counter==50){
      nrf_drv_timer_disable(&m_timer0);// letiltjuk a timert
       m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED;//
       buffer = buffer ^ 0x800000;
       hx711_stop();// kikapcsoljuk az hx711-et
       }
   

Ezután leállítjuk a timert és feldolgozzuk az adatokat (a datasheet szerint), majd átkapcsoljuk az HX711-et alacsony energiafogyasztású módba.


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();// elindítjuk az hx711-et
       nrf_drv_gpiote_out_toggle(LED_1);
       m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
   }
  
}
/**@brief Időzítők létrehozása.
*//
static void create_timers()
{
   ret_code_t err_code;
 
   // Időzítők létrehozása
   err_code = app_timer_create(&m_repeated_timer_id,
                               APP_TIMER_MODE_REPEATED,
                               repeated_timer_handler);
   APP_ERROR_CHECK(err_code);
}

Várjuk az eseményeket az RTC időzítőtől 10 másodperces időközönként (ez már az Ön választása), az eseménykezelőben elindítjuk az HX711-et, megszakítást hívva a DOUT vonalon.

Van még egy dolog, a naplókat UART-on keresztül küldjük (baud rate 115200, TX — 6 pin, RX — 8 pin), minden beállítás a sdk_config.h fájlban található.

Hogyan csatlakoztassuk a HX711 ADC-t az NRF52832-hez

Következtetések

Köszönöm mindenkinek a figyelmet, remélem, hogy ez a cikk hasznos lesz, és értékes időt takarít meg a fejlesztők számára a megoldáskeresés során. Szeretném megemlíteni, hogy a Nordic által használt technikai megközelítés a platformjaikon nagyon érdekes az energiahatékonyság szempontjából.

P.S.

A projekt még fejlesztés alatt áll, így ha érdekli ez a téma, a következő cikkben megpróbálom leírni a súlymérők kalibrálásának algoritmusát, valamint a BLE verem csatlakozását.

Anyagok

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster