HX711 ADC'yi NRF52832'ye bağlama

1. Giriş

Gündemde, nrf52832 mikro denetleyicisi için iki yarım köprülü Çin gerinim ölçeri ile bir iletişim protokolü geliştirme görevi vardı.

Herhangi bir anlaşılır bilgi eksikliğiyle karşı karşıya kaldığım için görevin kolay olmadığı ortaya çıktı. "Kötülüğün kökü"nün Nordic Semiconductor'ın SDK'sında olması daha muhtemeldir - sürekli sürüm güncellemeleri, bir miktar fazlalık ve kafa karıştırıcı işlevsellik. Her şeyi sıfırdan yazmak zorunda kaldım.

Bu çipin bir BLE yığınına ve enerji tasarrufu modu için bir dizi "güzelliğe" sahip olduğu gerçeğine dayanarak bu konunun oldukça alakalı olduğunu düşünüyorum. Ancak bu konuyla ilgili pek çok makale yazıldığı için teknik kısma çok fazla girmeyeceğim.

2. Proje açıklaması

HX711 ADC'yi NRF52832'ye bağlama

Demir:

  • Adafruit Feather nRF52 Bluefruit LE (elinizde olan şey)
  • ADC HX711
  • Çin gerinim ölçerler 2 adet. (50x2kg)
  • Programcı ST-LINK V2

Yazılım:

  • IDE VSCODE
  • NRF SDK'sı 16
  • AçıkOCD
  • Programcı ST-LINK V2

Her şey tek bir projede, sadece Makefile'da ince ayar yapmanız gerekiyor (SDK'nızın konumunu belirtin).

3. Kodun açıklaması

Görevlerin ve olayların bağlanmasına dayalı olarak çevre birimleriyle çalışmak için GPIOTE modülünü ve ayrıca bir işlemcinin katılımı olmadan verileri bir çevre biriminden diğerine aktarmak için PPI modülünü kullanacağız.

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);//настраеваем на выход

Çıkışa PD_SCL senkronizasyon hattını 10 μs süreli darbeler üretecek şekilde yapılandırıyoruz.

   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);//включаем таймер
}
 

DOUT veri hattını HX711'in hazırlık durumunu okuyacak şekilde yapılandırıyoruz; düşük bir seviye varsa, kesmeyi devre dışı bıraktığımız ve PD_SCL çıkışında saat darbeleri oluşturmak için bir zamanlayıcı başlattığımız bir işleyici tetiklenir.

 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); 

// gpiote'u etkinleştir

Bundan sonra PPI modülünü başlatıyoruz ve zamanlayıcımızı bir karşılaştırma olayı oluştuğunda 10 μs süreli darbeler üretmek için PD_SCL çıkışına bağlıyoruz ve ayrıca GPIOTE modülünü açıyoruz.


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);// срабатывает по сравнению

Sıfır zamanlayıcıyı ve onun işleyicisini başlatıyoruz.

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

En ilginç şey zamanlayıcı işleyicisinde olur. Darbe periyodu 20 μs'dir. Tek darbelerle (yükselen kenar boyunca) ilgileniyoruz ve sayıları 24'ü geçmemesi ve 48 olay olması şartıyla, her tek olay için DOUT okunur.

Veri sayfasından, darbe sayısının en az 25 olması gerektiği anlaşılıyor, bu da 128'lik bir kazanca karşılık geliyor (kodda 25 darbe kullandım), bu, veri çerçevesinin sonunu gösteren 50 zamanlayıcı olayına eşdeğerdir.

 ++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
       }
   

Bundan sonra zamanlayıcıyı kapatıp verileri (veri sayfasına göre) işliyoruz ve HX711'i düşük güç tüketimi moduna geçiriyoruz.


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);
}

RTC zamanlayıcısından 10 saniyelik aralıklarla olaylar bekliyoruz (bu sizin takdirinize bağlıdır) ve işleyicide HX711'i başlatarak DOUT hattında kesintiye neden oluyoruz.

Bir nokta daha var, loglar UART üzerinden çıkıyor (baud hızı 115200, TX - 6 pin, RX - 8 pin) tüm ayarlar sdk_config.h'de.

HX711 ADC'yi NRF52832'ye bağlama

Bulgular

İlginiz için hepinize teşekkür ederim, umarım bu makale faydalı olur ve geliştiricilerin çözüm bulmaları için değerli zamanlarını azaltır. Nordic'in platformlarında uyguladığı teknik yaklaşımın enerji verimliliği açısından oldukça ilgi çekici olduğunu söylemek istiyorum.

PS

Proje hala geliştirilme aşamasındadır, bu nedenle bu konu ilginizi çekiyorsa, bir sonraki makalede ağırlık sensörlerini kalibre etmenin yanı sıra BLE yığınını bağlama algoritmasını açıklamaya çalışacağım.

malzemeler

Kaynak: habr.com

Yorum ekle