So verbinden Sie den HX711 ADC mit NRF52832

1. Einleitung



Auf der Tagesordnung stand die Entwicklung eines Kommunikationsprotokolls für den Mikrocontroller nrf52832 mit zwei chinesischen Halbbrücken-Dehnungsmessstreifen.



Die Aufgabe stellte sich als nicht einfach heraus, da ich mit dem Mangel an verständlichen Informationen konfrontiert war. Es ist wahrscheinlicher, dass die "Wurzel des Bösen" im SDK selbst von Nordic Semiconductor liegt - dies sind ständige Versionsaktualisierungen, Redundanz und Verwirrung der Funktionalität. Ich musste alles von Grund auf neu schreiben.



Ich denke, dieses Thema ist ziemlich relevant, wenn man bedenkt, dass dieser Chip einen BLE-Stapel und eine ganze Reihe von "Süßigkeiten" des Energiesparmodus hat. Ich werde jedoch nicht weiter auf den technischen Teil eingehen, da viele Artikel zu diesem Thema verfasst wurden.



2. Beschreibung des Projekts



Bild



Eisen:



  • Adafruit Feather nRF52 Bluefruit LE (was zufällig zur Hand war)
  • ADC HX711
  • Chinesische Dehnungsmessstreifen 2 Stk. (50 x 2 kg)
  • ST-LINK V2 Programmierer


Software:



  • IDE VSCODE
  • NRF SDK 16
  • OpenOCD
  • ST-LINK V2 Programmierer




Alles ist in einem Projekt, Sie müssen nur Makefile schamanisieren (geben Sie den Speicherort Ihres SDK an).



3. Beschreibung des Codes



Wir werden das GPIOTE-Modul für die Arbeit mit Peripheriegeräten verwenden, die auf der Bindung von Aufgaben und Ereignissen basieren, sowie das PPI-Modul für die Übertragung von Daten von einem Peripheriegerät zu einem anderen ohne Beteiligung des Prozessors.





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


Wir konfigurieren die PD_SCL-Synchronisationsleitung zum Ausgang, um Impulse mit einer Dauer von 10 μs zu erzeugen.



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


Wir konfigurieren die DOUT-Datenleitung so, dass sie den Bereitschaftszustand des HX711 liest. Wenn ein niedriger Pegel vorliegt, wird der Handler ausgelöst, in dem wir den Interrupt deaktivieren und den Timer starten, um Taktimpulse am PD_SCL-Ausgang zu erzeugen.



 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 aktivieren

Danach initialisieren wir das PPI-Modul und schalten unseren Timer auf den PD_SCL-Ausgang, um Impulse mit einer Dauer von 10 μs zu erzeugen, wenn das Vergleichsereignis auftritt, und schalten auch das GPIOTE-Modul ein.




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


Wir initialisieren den Null-Timer und seinen Handler.





  if(m_counter%2 != 0 && m_counter<=48){
       buffer <<= 1;//   
        c_counter++;//    
           if(nrf_gpio_pin_read(DOUT))buffer++;//  
   }


Das Interessanteste passiert im Timer-Handler. Die Pulsperiode beträgt 20 μs. Wir sind an ungeraden Impulsen (an der ansteigenden Flanke) interessiert und vorausgesetzt, dass ihre Anzahl nicht mehr als 24 beträgt und es 48 Ereignisse gibt. Für jedes ungerade Ereignis wird DOUT gelesen



, 25, 128 ( 25 ), 50 , .



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


( ) HX711 .




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 10 ( ) HX711, DOUT.



, UART (baud rate 115200, TX — 6 , RX — 8 ) sdk_config.h



Bild





Vielen Dank für Ihre Aufmerksamkeit. Ich hoffe, dieser Artikel ist nützlich und spart Entwicklern, die nach einer Lösung suchen, wertvolle Zeit. Ich möchte sagen, dass der technische Ansatz, den Nordic auf seinen Plattformen verwendet, im Hinblick auf die Energieeffizienz sehr interessant ist.



PS



Das Projekt befindet sich noch in der Entwicklung. Wenn dieses Thema im nächsten Artikel von Interesse ist, werde ich versuchen, den Algorithmus zum Kalibrieren von Gewichtssensoren sowie zum Anschließen des BLE-Stapels zu beschreiben.



Materialien






All Articles