1.はじめに
議題には、2つのハーフブリッジ中国ひずみゲージを備えたnrf52832マイクロシステム用の通信プロトコルを開発するタスクがありました。
わかりやすい情報がないことに直面したため、この作業は簡単ではないことがわかりました。「悪の根源」はNordicSemiconductorのSDK自体にある可能性が高いです。これは、バージョンの定期的な更新、冗長性、機能の混乱です。私はすべてを一から書かなければなりませんでした。
このチップにはBLEスタックと省電力モードの「スイーツ」のセット全体があることを考えると、このトピックは非常に関連性があると思います。しかし、このトピックについて多くの記事が書かれているので、技術的な部分については深く掘り下げません。
2.プロジェクトの説明
鉄:
- Adafruit Feather nRF52 Bluefruit LE(たまたま手元にあったもの)
- ADC HX711
- 中国のひずみゲージ2個 (50x2 kg)
- ST-LINKV2プログラマー
ソフトウェア:
- IDE VSCODE
- NRF SDK 16
- OpenOCD
- ST-LINKV2プログラマー
すべてが1つのプロジェクトにあり、Makefileをシャーマンするだけです(SDKの場所を指定します)。
3.コードの説明
タスクとイベントのバインドに基づいてペリフェラルを操作するためのGPIOTEモジュールと、プロセッサの関与なしに1つのペリフェラルから別のペリフェラルにデータを転送するためのPPIモジュールを使用します。
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);
}
RTC 10 ( ) HX711, DOUT.
, UART (baud rate 115200, TX — 6 , RX — 8 ) sdk_config.h
ご清聴ありがとうございました。この記事がお役に立てば幸いです。解決策を探している開発者にとって貴重な時間を節約できます。Nordicがプラットフォームで使用している技術的アプローチは、エネルギー効率の点で非常に興味深いと言いたいです。
PS
プロジェクトはまだ開発中であるため、このトピックが次の記事で興味深い場合は、重量センサーを校正するためのアルゴリズムと、BLEスタックを接続するためのアルゴリズムについて説明します。