I am using nRF51822 to generate 3K HZ PWM signal for a buzzer. I read other people's question and try it.But as far i can't solve this issue.Please help.
At first i use the simplest way,use for loop and delay. Someone said that when softdevice enable,in some interval time will be effected(i forget the word, sorry). It's look like the same circumstances.The PWM signal sometimes display wrong period,like something have affect the waveform.I guess ,it will be some relation with BLE?
SO i try another way.I copy the code from the example project pwm_example and do some change.It works's well.But when i use it with softdevice ,here comes the same trouble. It uses PPI ,i think it can avoid BLE or other effect,but it's not.
Could someone give me some suggestion?Thank you. Below it's my code.Please help. Use S110 .keil
void TIMER2_IRQHandler(void) { static bool cc0_turn = false; /**< Keeps track of which CC register to be used. */
if ((NRF_TIMER2->EVENTS_COMPARE[1] != 0) &&
((NRF_TIMER2->INTENSET & TIMER_INTENSET_COMPARE1_Msk) != 0))
{
// Sets the next CC1 value
NRF_TIMER2->EVENTS_COMPARE[1] = 0;
//NRF_TIMER2->CC[1] = (NRF_TIMER2->CC[1] + MAX_SAMPLE_LEVELS);
NRF_TIMER2->CC[1] = (NRF_TIMER2->CC[1] + 83);
// Every other interrupt CC0 and CC2 will be set to their next values.
uint32_t next_sample = 40;
if (cc0_turn)
{
NRF_TIMER2->CC[0] = NRF_TIMER2->CC[1] + next_sample;
}
else
{
NRF_TIMER2->CC[2] = NRF_TIMER2->CC[1] + next_sample;
}
// Next turn the other CC will get its value.
cc0_turn = !cc0_turn;
}
}
/** @brief Function for initializing the Timer 2 peripheral. */ void timer2_init(void) { // Start 16 MHz crystal oscillator .
NRF_TIMER2->MODE = TIMER_MODE_MODE_Timer;
NRF_TIMER2->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
NRF_TIMER2->PRESCALER = TIMER_PRESCALERS;
// Clears the timer, sets it to 0.
NRF_TIMER2->TASKS_CLEAR = 1;
// Load the initial values to TIMER2 CC registers.
N RF_TIMER2->CC[0] = MAX_SAMPLE_LEVELS + next_sample_get(); NRF_TIMER2->CC[1] = MAX_SAMPLE_LEVELS;
// CC2 will be set on the first CC1 interrupt.
NRF_TIMER2->CC[2] = 0;
// Interrupt setup.
NRF_TIMER2->INTENSET = (TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos);
}
/** @brief Function for initializing the GPIO Tasks/Events peripheral. */ void gpiote_init(void) { // Connect GPIO input buffers and configure PWM_OUTPUT_PIN_NUMBER as an output.
nrf_gpio_cfg_output(22);
// @note Only one GPIOTE task can be connected to an output pin.
nrf_gpiote_task_config(0, 22, \
NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
}
/** @brief Function for initializing the Programmable Peripheral Interconnect peripheral. */ void ppi_init(void) {
sd_ppi_channel_assign(0, &(NRF_TIMER2->EVENTS_COMPARE[0]), &(NRF_GPIOTE->TASKS_OUT[0]));
sd_ppi_channel_assign(1, &(NRF_TIMER2->EVENTS_COMPARE[1]), &(NRF_GPIOTE->TASKS_OUT[0]));
sd_ppi_channel_assign(3, &(NRF_TIMER2->EVENTS_COMPARE[2]), &(NRF_GPIOTE->TASKS_OUT[0]));
sd_ppi_channel_enable_set(PPI_CHEN_CH0_Msk);
sd_ppi_channel_enable_set(PPI_CHEN_CH1_Msk);
sd_ppi_channel_enable_set(PPI_CHEN_CH2_Msk);
}
gpiote_init();
ppi_init();
timer2_init();
sd_nvic_SetPriority(TIMER2_IRQn,3);
sd_nvic_EnableIRQ(TIMER2_IRQn);
leds_init();//BLE LED
timers_init();
buttons_init();
uart_init();
ble_stack_init();
gap_params_init();
services_init();
advertising_init();
conn_params_init();
sec_params_init();
adc_init();
advertising_start();