I need to implement a 4kHz signal to drive a buzzer on a custom board of nRF51822 with external 16MHz and 32kHz crystal.
I am using Timer1+PPI+GPIOTE to generate this 4kHz signal.
Unfortunately there is sound distortion issue.
Measured by CRO, the 4kHz signal is jittering by 30us.
Below is the code I used to setup TIMER1 + PPI + GPIOTE.
Is there any thing I have missed to generate a stable 4kHz signal?
Thanks.
void timer_event_handler(nrf_timer_event_t event_type, void * p_context){ //For init only } void app_buzzer_init(){ uint32_t err_code; uint32_t ret; uint32_t time_ticks; nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(NRF_GPIOTE_INITIAL_VALUE_LOW); err_code = nrf_drv_gpiote_out_init(BUZZER_PIN_0, &config); APP_ERROR_CHECK(err_code); err_code = nrf_drv_timer_init(&timer1, NULL, timer_event_handler); APP_ERROR_CHECK(err_code); time_ticks = (16000000 / m_main_params.buzzer_freq) / 2; nrf_drv_timer_extended_compare(&timer1, NRF_TIMER_CC_CHANNEL0, time_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false); err_code = nrf_drv_ppi_init(); APP_ERROR_CHECK(err_code); // Configure 1nd available PPI channel err_code = nrf_drv_ppi_channel_alloc(&ppi_channel1); APP_ERROR_CHECK(err_code); err_code = nrf_drv_ppi_channel_assign(ppi_channel1, nrf_drv_timer_event_address_get(&timer1, NRF_TIMER_EVENT_COMPARE0), nrf_drv_gpiote_out_task_addr_get(BUZZER_PIN_0)); APP_ERROR_CHECK(err_code); // Enable both configured PPI channels err_code = nrf_drv_ppi_channel_enable(ppi_channel1); APP_ERROR_CHECK(err_code); nrf_drv_gpiote_out_task_enable(BUZZER_PIN_0); nrf_drv_timer_disable(&timer1); } void buzzer_service(){ if (m_main_flag.buzzer_flag){ //edited: 2018/8/22 //=========Adding this part seems no change========= NRF_CLOCK->TASKS_HFCLKSTART = 1; /* Wait for the external oscillator to start up */ while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; //================================================== nrf_drv_gpiote_out_task_enable(BUZZER_PIN_0); nrf_drv_timer_enable(&timer1); }else{ nrf_drv_gpiote_out_task_disable(BUZZER_PIN_0); nrf_drv_timer_disable(&timer1); } }
Board A, good sound and no jittering:
Board B, distorted sound with jittering (yellow marked = 30us):