SPI経由で外部ADCからデータを受信し、ADCからのデータに依存するデューティサイクルでPWM信号を出力するNetbeans IDEのcで、NRF52832マイクロコントローラでプログラムを開発しています。
SPI ドライバーと PWM ドライバーが別々のプロジェクトで動作するサンプル コードを取得しましたが、現在、この 2 つを結合しようとしています。ただし、PWM ドライバーから SPI ドライバーに関数を挿入し、対応するインクルード ファイルを SPI ドライバーに挿入すると、サンプル コードの一部として含まれているソース ファイルの if ループでスタックします。トラブルシューティングを開始する方法さえわからなくなったので、提案や洞察をいただければ幸いです。
現在、main.c に次のコードを追加するまで正常に動作している SPI ドライバーで作業しています。
ret_code_t err_code;
/* 1-channel PWM, 100000 microseconds period = 0.1 second , output on pin 5. */
app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(125L, 5);
/* Switch the polarity of the second channel. */
pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
/* Initialize and enable PWM. */
err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
APP_ERROR_CHECK(err_code);
app_pwm_enable(&PWM1);
app_pwm_channel_duty_set(&PWM1, 0, Duty);
デバッグすると、機能に到達するまですべて問題ありません
err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
この関数をステップ実行すると、舞台裏で一連の初期化が行われ、次の関数でスタックします。
/**
* Function examines current header and omits pushed strings and packets which are in progress.
*/
static bool invalid_packets_pushed_str_omit(nrf_log_header_t const * p_header, uint32_t * p_rd_idx)
{
bool ret = false;
if ((p_header->base.generic.type == HEADER_TYPE_PUSHED) || (p_header->base.generic.in_progress == 1))
{
if (p_header->base.generic.in_progress == 1)
{
switch (p_header->base.generic.type)
{
case HEADER_TYPE_STD:
*p_rd_idx += (HEADER_SIZE + p_header->base.std.nargs);
break;
case HEADER_TYPE_HEXDUMP:
*p_rd_idx += (HEADER_SIZE + p_header->base.hexdump.len);
break;
default:
ASSERT(0);
break;
}
}
else
{
*p_rd_idx +=
(PUSHED_HEADER_SIZE + p_header->base.pushed.len + p_header->base.pushed.offset);
}
ret = true;
}
return ret;
}
これが残りの main.c コードです (pwm に関係するものはすべて私が追加したもので、残りは SPI ドライバーのサンプル コードです):
#include "nrf_drv_spi.h"
#include "app_util_platform.h"
#include "nrf_gpio.h"
#include "nrf_delay.h"
#include "boards.h"
#include "app_error.h"
#include <string.h>
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "/Users/tom/opt/nRF5_SDK_15.0.0/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h"
#define SPI_INSTANCE 0 /**< SPI instance index. */
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE); /**< SPI instance. */
static volatile bool spi_xfer_done; /**< Flag used to indicate that SPI instance completed the transfer. */
#define TEST_STRING "Nordic"
static uint8_t m_tx_buf[] = TEST_STRING; /**< TX buffer. */
static uint8_t m_rx_buf[sizeof(TEST_STRING) + 1]; /**< RX buffer. */
static const uint8_t m_length = sizeof(m_tx_buf); /**< Transfer length. */
//PWM INITIALIZATION (Added)
uint32_t Duty = 90;
APP_PWM_INSTANCE(PWM1,1); // Create the instance "PWM1" using TIMER1.
static volatile bool ready_flag; // A flag indicating PWM status.
void pwm_ready_callback(uint32_t pwm_id) // PWM callback function
{
ready_flag = true;
}
//End added
/**
* @brief SPI user event handler.
* @param event
*/
void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
void * p_context)
{
spi_xfer_done = true;
NRF_LOG_INFO("Transfer completed.");
if (m_rx_buf[0] != 0)
{
NRF_LOG_INFO(" Received:");
NRF_LOG_HEXDUMP_INFO(m_rx_buf, strlen((const char *)m_rx_buf));
}
}
int main(void)
{
//Added
ret_code_t err_code;
/* 1-channel PWM, 100000 microseconds period = 0.1 second , output on pin 5. */
app_pwm_config_t pwm1_cfg = APP_PWM_DEFAULT_CONFIG_1CH(125L, 5);
/* Switch the polarity of the second channel. */
pwm1_cfg.pin_polarity[1] = APP_PWM_POLARITY_ACTIVE_HIGH;
/* Initialize and enable PWM. */
err_code = app_pwm_init(&PWM1,&pwm1_cfg,pwm_ready_callback);
APP_ERROR_CHECK(err_code);
app_pwm_enable(&PWM1);
app_pwm_channel_duty_set(&PWM1, 0, Duty);
//End Added
// bsp_board_init(BSP_INIT_LEDS);
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();
nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
spi_config.ss_pin = SPI_SS_PIN;
spi_config.miso_pin = SPI_MISO_PIN;
spi_config.mosi_pin = SPI_MOSI_PIN;
spi_config.sck_pin = SPI_SCK_PIN;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
NRF_LOG_INFO("SPI example started.");
while (1)
{
// Reset rx buffer and transfer done flag
memset(m_rx_buf, 0, m_length);
spi_xfer_done = false;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, m_tx_buf, m_length, m_rx_buf, m_length));
while (!spi_xfer_done)
{
__WFE();
}
NRF_LOG_FLUSH();
// bsp_board_led_invert(BSP_BOARD_LED_0);
// nrf_delay_ms(200);
}
}
どんな提案でも大歓迎です!重要な情報を省略した場合は、明確化を求めてください。できる限り提供します。
アップデート
やあみんな、たくさんの反応に感謝します。画像の画面の左側にあるすべての関連変数とその値を (うまくいけば) デバッグしながら、ループの Imgur アルバムを作成しました: https://imgur.com/a/HYah1yC
アルバムでわかるように、ポインターは*p_rd_idx
内部で際限なく増加nrf_log_frontend.c
し、何らかの理由で関数の最後に到達しません。
@Yunnosch: の定義を見つけましたASSERT
:
#define ASSERT(expr)
expr
しかし、の値がでありOUT_OF_SCOPE
、右クリックして の宣言に移動しようとしてexpr
も、何も起こらないため、役に立たないと思います。