1. Inledning
Det fanns en uppgift att utveckla ett kommunikationsprotokoll för mikrokontrollern nrf52832 med tvÄ halvbro Chinese tensedata-sensorer.
Uppgiften visade sig vara svĂ„r, eftersom jag stötte pĂ„ bristen pĂ„ tydlig information. Troligen ligger "roten till problemet" i sjĂ€lva SDK:n frĂ„n Nordic Semiconductor â de kontinuerliga versionuppdateringarna, viss överflödighet och förvirring i funktionaliteten. Jag var tvungen att skriva allt frĂ„n början.
Jag tycker att detta Àmne Àr ganska aktuellt med tanke pÄ att denna chip har en BLE-stack och en hel uppsÀttning av "godbitar" i energisparlÀget. Men jag kommer inte att gÄ djupt in i den tekniska delen, eftersom det har skrivits mÄnga artiklar om detta Àmne.
2. Projektbeskrivning

HÄrdvara:
- Adafruit Feather nRF52 Bluefruit LE (det som fanns tillgÀngligt)
- ADC HX711
- Kinesiska tensedata-sensorer 2 st. (50x2 kg)
- Programmerare ST-LINK V2
Mjukvara:
- IDE VSCODE
- NRF SDK 16
- OpenOCD
- Programmerare ST-LINK V2
Allt finns i ett projekt, det kommer bara att krÀvas lite justering av Makefile (ange placeringen av din SDK).
3. Kodbeskrivning
Vi kommer att anvÀnda GPIOTE-modulen för att arbeta med periferiutrustningen baserat pÄ uppgift och hÀndelse, samt PPI-modulen för att överföra data frÄn en periferieenhet till en annan utan processorinblandning.
ret_code_t err_code;
err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // stÀller in som utgÄng
nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); // vi kommer att aktivera pinnen för impulsen
err_code = nrf_drv_gpiote_out_init(PD_SCK, &config); // stÀller in som utgÄng
Vi stÀller in synkroniseringslinjen PD_SCL som utgÄng för att generera impulser med en varaktighet av 10 ”s.
nrf_drv_gpiote_in_config_t gpiote_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false); // nivÄövergÄng frÄn hög till lÄg
nrf_gpio_cfg_input(DOUT, NRF_GPIO_PIN_NOPULL); // ingÄng utan dragning
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); // stÀnger av avbrottet
nrf_drv_timer_enable(&m_timer0); // aktiverar timern
}
Vi stÀller in datalinjen DOUT för att lÀsa tillstÄndet av HX711:s beredskap, dÀr ett lÄg nivÄ utlöser en hanterare dÀr vi stÀnger av avbrottet och startar timern för att generera synkroniserande impulser pÄ utgÄngen 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)); // kopplar timer till utgÄng
APP_ERROR_CHECK(err_code);
err_code = nrf_drv_ppi_channel_enable(m_ppi_channel1); // aktiverar kanal
APP_ERROR_CHECK(err_code);
nrf_drv_gpiote_out_task_enable(PD_SCK); // ĐČĐșĐ»ŃŃĐ°Đ”ĐŒ gpiote
DÀrefter initierar vi PPI-modulen och kopplar vÄr timer till utgÄngen PD_SCL för att generera impulser av 10 ”s vid jÀmförelsehÀndelse, samt aktiverar GPIOTE-modulen.
nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG; // som standard
timer_cfg.frequency = NRF_TIMER_FREQ_1MHz; // takta vid 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); // utlöses vid jÀmförelseVi initierar den nollade timern och dess hanterare.
if(m_counter%2 != 0 && m_counter<=48){
buffer <<= 1; // variabel för lÀsta data
c_counter++; // rÀknare för positiva impulser
if(nrf_gpio_pin_read(DOUT))buffer++; // lÀser in ingÄngens tillstÄnd
}
Det mest intressanta sker i timerhanteraren. Perioden för impulserna Àr 20 ”s. Vi Àr intresserade av udda impulser (vid stigande front) och under förutsÀttning att deras antal inte överstiger 24 och hÀndelser - 48. Vid varje udda hÀndelse sker en avlÀsning av DOUT.
FrÄn databladen framgÄr att antalet impulser mÄste vara minst 25, vilket motsvarar en förstÀrkningsfaktor pÄ 128 (i koden anvÀnde jag 25 impulser), vilket Àr ekvivalent med 50 timerhÀndelser som indikerar slutet av dataram.
++m_counter; // rÀknare för hÀndelser
if(m_counter==50){
nrf_drv_timer_disable(&m_timer0); // stÀnger av timern
m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED; //
buffer = buffer ^ 0x800000;
hx711_stop(); // stÀnger av hx711
}
DÀrefter stÀnger vi av timern och bearbetar data (enligt databladen) och sÀtter HX711 i lÄgenergilÀge.
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(); // startar hx711
nrf_drv_gpiote_out_toggle(LED_1);
m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
}
}
/**@brief Skapa timers.
*\/
static void create_timers()
{
ret_code_t err_code;
\/\/ Skapa timers
err_code = app_timer_create(&m_repeated_timer_id,
APP_TIMER_MODE_REPEATED,
repeated_timer_handler);
APP_ERROR_CHECK(err_code);
}
VÀnta pÄ hÀndelse frÄn RTC-timer med ett intervall pÄ 10 sek (detta Àr upp till dig) i hanteraren startar vi HX711 genom att utlösa en avbrott via DOUT-linjen.
Det finns en annan aspekt, loggarna skrivs ut via UART (baud rate 115200, TX â pin 6, RX â pin 8) alla instĂ€llningar finns i sdk_config.h.

Slutsatser
Tack alla för uppmÀrksamheten, jag hoppas att denna artikel kommer att vara anvÀndbar och spara vÀrdefull tid för utvecklare som letar efter lösningar. Jag vill sÀga att den tekniska ansatsen som Nordic anvÀnder i sina plattformar Àr ganska intressant ur ett energieffektivitetsperspektiv.
P.S.
Projektet Àr fortfarande under utveckling, sÄ om detta Àmne vÀcker intresse kommer jag i nÀsta artikel att försöka beskriva algoritmen för kalibrering av viktgivare samt anslutning av BLE-stacken.
Material
KĂ€lla: habr.com
