1. Einführung
Auf der Tagesordnung stand die Aufgabe, ein Kommunikationsprotokoll für den Mikrocontroller nrf52832 mit zwei halben Brücken chinesischen Dehnmesstechnik-Sensoren zu entwickeln.
Die Aufgabe stellte sich als nicht einfach heraus, da ich mit dem Mangel an klaren Informationen konfrontiert war. Wahrscheinlich liegt der "Ursprung des Übels" im SDK von Nordic Semiconductor – den ständigen Versionsupdates, einem gewissen Überfluss und der Verwirrung bezüglich der Funktionalitäten. Ich musste alles von Grund auf neu schreiben.
Ich denke, dieses Thema ist ziemlich relevant, da dieser Chip über einen BLE-Stack und eine ganze Reihe von "Leckerbissen" im Energiesparmodus verfügt. Aber in die technische Details werde ich nicht zu sehr eintauchen, da zu diesem Thema bereits zahlreiche Artikel geschrieben wurden.
2. Projektbeschreibung

Hardware:
- Adafruit Feather nRF52 Bluefruit LE (das, was zur Hand war)
- ADC HX711
- Chinesische Dehnmesstechnik-Sensoren 2 Stück (50x2 kg)
- Programmiergerät ST-LINK V2
Software:
- IDE VSCODE
- NRF SDK 16
- OpenOCD
- Programmiergerät ST-LINK V2
Alles befindet sich in einem Projekt, ich werde nur das Makefile anpassen müssen (den Speicherort Ihres SDK angeben).
3. Codebeschreibung
Wir werden das GPIOTE-Modul zur Steuerung der Peripherie verwenden, basierend auf der Zuordnung von Aufgaben und Ereignissen, sowie das PPI-Modul zur Datenübertragung von einer Peripherie zur anderen ohne die Beteiligung des Prozessors.
ret_code_t err_code;
err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // konfigurieren wir als Ausgang
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); // wir werden den Pin für das Signal umschalten
err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // konfigurieren wir als Ausgang
Wir konfigurieren die Synchronisationslinie PD_SCL als 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); // Übergang des Pegels von hoch zu niedrig
nrf_gpio_cfg_input(DOUT, NRF_GPIO_PIN_NOPULL); // als Eingang ohne Pull-up
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); // unterbrechen deaktivieren
nrf_drv_timer_enable(&m_timer0); // Timer aktivieren
}
Wir konfigurieren die Datenlinie DOUT, um den Status der Bereitschaft des HX711 auszulesen. Bei niedrigem Pegel wird der Handler ausgelöst, bei dem wir das Interrupt deaktivieren und den Timer zur Generierung synchronisierender Impulse am Ausgang PD_SCL starten.
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)); // verbinden Sie den Timer mit dem Ausgang
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_enable(m_ppi_channel1); // aktivieren Sie den Kanal
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_out_task_enable(PD_SCK); // включаем gpiote
Danach initialisieren wir das PPI-Modul und verbinden unseren Timer mit dem Ausgang PD_SCL, um Impulse von 10 μs Dauer bei Auftreten des Vergleichsereignisses zu erzeugen, und aktivieren das GPIOTE-Modul.
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; // standardmäßig
timer_cfg.frequency = NRF_TIMER_FREQ_1MHz; // takten bei 1 MHz
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); // wird bei Vergleich ausgelöstWir initialisieren den Null-Timer und dessen Handler.
if(m_counter%2 != 0 && m_counter<=48){
buffer <<= 1; // Variable der gelesenen Daten
c_counter++; // Zähler der positiven Impulse
if(nrf_gpio_pin_read(DOUT)) buffer++; // den Zustand des Eingangs lesen
}
Das Interessanteste passiert im Timer-Handler. Der Impulszyklus beträgt 20 μs. Wir interessieren uns für die ungeraden Impulse (steigende Flanke), vorausgesetzt ihre Anzahl überschreitet nicht 24, während es insgesamt 48 Ereignisse gibt. Bei jedem ungeraden Ereignis wird DOUT gelesen.
Aus dem Datenblatt geht hervor, dass die Anzahl der Impulse mindestens 25 betragen sollte, was einem Verstärkungsfaktor von 128 entspricht (im Code habe ich 25 Impulse verwendet). Dies entspricht 50 Timer-Ereignissen, was das Ende des Datenrahmens anzeigt.
++m_counter; // Zähler der Ereignisse
if(m_counter==50){
nrf_drv_timer_disable(&m_timer0); // Timer deaktivieren
m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED; //
buffer = buffer ^ 0x800000;
hx711_stop(); // hx711 deaktivieren
}
Danach schalten wir den Timer aus und verarbeiten die Daten (laut Datenblatt) und versetzen den HX711 in den Energiesparmodus.
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 einschalten
nrf_drv_gpiote_out_toggle(LED_1);
m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
}
}
/**@brief Timer erstellen.
*\
static void create_timers()
{
ret_code_t err_code;
// Timer erstellen
err_code = app_timer_create(&m_repeated_timer_id,
APP_TIMER_MODE_REPEATED,
repeated_timer_handler);
APP_ERROR_CHECK(err_code);
}
Wir warten auf ein Ereignis vom RTC-Timer mit einem Intervall von 10s (dies liegt bereits in Ihrem Ermessen), in der Handler wird HX711 gestartet, indem ein Interrupt über die DOUT-Leitung ausgelöst wird.
Es gibt noch einen weiteren Punkt, die Protokolle werden über UART ausgegeben (Baudrate 115200, TX — Pin 6, RX — Pin 8), alle Einstellungen befinden sich in sdk_config.h.

Das DBMS Tarantool ist ein attraktives, zukunftsträchtiges Produkt zur Erstellung von hochbelasteten Anwendungen.
Vielen Dank für Ihre Aufmerksamkeit, ich hoffe, dieser Artikel wird nützlich sein und die wertvolle Zeit der Entwickler bei der Lösungssuche verkürzen. Ich möchte sagen, dass der technische Ansatz, den Nordic in seinen Plattformen verwendet, aus Sicht der Energieeffizienz ziemlich interessant ist.
P.S.
Das Projekt befindet sich noch in der Entwicklungsphase, daher werde ich versuchen, in einem nächsten Artikel den Kalibrierungsalgorithmus für Wägezellen sowie die Anbindung des BLE-Stacks zu beschreiben, wenn dieses Thema von Interesse ist.
Materialien
Quelle: habr.com
