1.はじめに
議題は、52832 つのハーフブリッジ中国製ひずみゲージを備えた nrfXNUMX マイクロコントローラーの通信プロトコルを開発するタスクでした。
わかりやすい情報が不足していたため、この作業は簡単ではないことがわかりました。 「諸悪の根源」は、Nordic Semiconductor 自体の SDK にある可能性が高くなります。つまり、定期的なバージョンの更新、いくつかの冗長性、および混乱を招く機能です。 すべてを一から書かなければなりませんでした。
このチップには BLE スタックと省エネ モード用の一連の「便利な機能」が備わっているという事実に基づいて、このトピックは非常に関連性があると思います。 ただし、このトピックについては多くの記事が書かれているため、技術的な部分にはあまり深く立ち入りません。
2. プロジェクトの説明
アイアン:
- Adafruit Feather nRF52 Bluefruit LE(たまたま手元にあったもの)
- HX711 ADC
- 中国製ひずみゲージ 2個(50×2kg)
- プログラマ ST-LINK V2
ソフトウェア:
- IDE VSCODE
- NRF SDK 16
- OpenOCD
- プログラマ ST-LINK V2
すべてが XNUMX つのプロジェクト内にあり、Makefile を調整するだけです (SDK の場所を指定します)。
3. コードの説明
GPIOTE モジュールを使用してタスクとイベントのバインディングに基づいてペリフェラルを操作し、PPI モジュールを使用してプロセッサの関与なしに XNUMX つのペリフェラルから別のペリフェラルにデータを転送します。
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);//настраеваем на выход
出力への PD_SCL 同期ラインを設定して、持続時間 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);//включаем таймер
}
HX711 の準備状態を読み取るように DOUT データ ラインを構成します。ロー レベルの場合、ハンドラーがトリガーされ、割り込みが無効になり、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);
// gpioteを有効にする
その後、PPI モジュールを初期化し、タイマーを PD_SCL 出力に接続して、比較イベントが発生したときに持続時間 10 μs のパルスを生成し、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);// срабатывает по сравнению
ゼロ タイマーとそのハンドラーを初期化します。
if(m_counter%2 != 0 && m_counter<=48){
buffer <<= 1;// переменная считанных даных
c_counter++;// счетчик положительных импульсов
if(nrf_gpio_pin_read(DOUT))buffer++;//считываем состояние входа
}
最も興味深いことはタイマー ハンドラーで起こります。 パルス周期は20μsです。 奇数パルス (立ち上がりエッジに沿った) に興味があり、その数が 24 以下で、イベントが 48 個あると仮定します。奇数イベントごとに、DOUT が読み取られます。
データシートから、パルス数は少なくとも 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);
}
10 秒間隔で RTC タイマーからのイベントを予期し (これはユーザーの判断による)、ハンドラーで HX711 を起動し、DOUT ラインで割り込みを発生させます。
もう 115200 つポイントがあります。ログは UART 経由で出力されます (ボーレート 6、TX - 8 ピン、RX - XNUMX ピン)。すべての設定は sdk_config.h にあります。
所見
ご清聴ありがとうございました。この記事がお役に立ち、開発者が解決策を見つけるための貴重な時間を短縮できることを願っています。 Nordic が自社のプラットフォームで使用している技術的アプローチは、エネルギー効率の観点から非常に興味深いものであると言いたいのです。
PS
このプロジェクトはまだ開発中であるため、このトピックに興味がある場合は、次の記事で重量センサーの校正と BLE スタックの接続のアルゴリズムについて説明します。
材料
出所: habr.com