1. Pambuka
Ing agenda kasebut ana tugas ngembangake protokol komunikasi kanggo mikrokontroler nrf52832 kanthi rong pengukur galur Cina setengah jembatan.
Tugas kasebut ora gampang, amarga aku ngadhepi kekurangan informasi sing bisa dingerteni. Luwih kamungkinan yen "root saka ala" ana ing SDK saka Nordic Semiconductor dhewe - nganyari versi konstan, sawetara redundansi lan fungsi sing mbingungake. Aku kudu nulis kabeh saka awal.
Aku topik iki cukup cocog adhedhasar kasunyatan sing chip iki wis tumpukan Ble lan pesawat kabèh "barang" kanggo mode hemat energi. Nanging aku ora bakal jero banget ing bagean teknis, amarga akeh artikel sing wis ditulis babagan topik iki.
2. Katrangan proyek

Wesi:
- Adafruit Feather nRF52 Bluefruit LE (apa sing kedadeyan)
- HX711 ADC
- Pengukur strain Cina 2 pcs. (50x2 kg)
- Programmer ST-LINK V2
Piranti lunak:
- IDE VSCODE
- NRF SDK 16
- OpenOCD
- Programmer ST-LINK V2
Kabeh ana ing siji proyek, sampeyan mung kudu ngapiki Makefile (nemtokake lokasi SDK sampeyan).
3. Katrangan kode
Kita bakal nggunakake modul GPIOTE kanggo karya karo peripheral adhedhasar naleni tugas lan acara, uga modul PPI kanggo transfer data saka siji peripheral liyane tanpa partisipasi prosesor.
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);//настраеваем на выход
Kita ngatur garis sinkronisasi PD_SCL menyang output kanggo ngasilake pulsa kanthi durasi 10 μs.
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);//включаем таймер
}
Kita ngatur baris data DOUT kanggo maca negara siyap HX711; yen ana tingkat kurang, handler micu kang mateni interupsi lan miwiti wektu kanggo generate pulsa jam ing output 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));// подключаем таймер к выходу
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); // ngaktifake gpiote
Sawisé iku, kita miwiti modul PPI lan sambungake timer menyang output PD_SCL kanggo ngasilake pulsa kanthi durasi 10 μs nalika ana acara perbandingan, lan uga nguripake modul GPIOTE.
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);// срабатывает по сравнениюKita miwiti timer nul lan panangane.
if(m_counter%2 != 0 && m_counter<=48){
buffer <<= 1;// переменная считанных даных
c_counter++;// счетчик положительных импульсов
if(nrf_gpio_pin_read(DOUT))buffer++;//считываем состояние входа
}
Sing paling menarik kedadeyan ing panangan wektu. Periode pulsa yaiku 20 μs. Kita kasengsem ing pulsa aneh (sadawane pinggiran munggah) lan kasedhiya yen nomer ora luwih saka 24, lan ana acara 48. Kanggo saben acara aneh, DOUT diwaca.
Saka lembar data kasebut, jumlah pulsa kudu paling sethithik 25, sing cocog karo gain 128 (ing kode sing digunakake 25 pulsa), iki padha karo 50 acara wektu, sing nuduhake pungkasan pigura data.
++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
}
Sawise iki, mateni wektu lan ngolah data (miturut lembar data) lan ngalih HX711 menyang mode konsumsi daya sing sithik.
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);
}
Kita ngarepake acara saka timer RTC kanthi interval 10 s (iki ing discretion sampeyan) lan miwiti HX711 ing handler, nyebabake gangguan ing garis DOUT.
Ana siji titik liyane, log output liwat UART (baud rate 115200, TX - 6 pin, RX - 8 pin) kabeh setelan ing sdk_config.h

temonan
Matur nuwun kanggo kabeh perhatian, muga-muga artikel iki migunani lan bakal nyuda wektu sing migunani kanggo para pangembang kanggo nemokake solusi. Aku pengin ujar manawa pendekatan teknis sing digunakake Nordic ing platform kasebut cukup menarik saka sudut pandang efisiensi energi.
PS
Proyek iki isih dikembangake, dadi yen topik iki menarik, ing artikel sabanjure aku bakal nyoba njlèntrèhaké algoritma kanggo kalibrasi sensor bobot, uga nyambungake tumpukan BLE.
Bahan
Source: www.habr.com
