This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How to get 3MHz~5MHz clock signal out from GPIO of nRF51822

I want to use nRF51822 to read smart card signal, and smart card need clock signal input. Thanks.

  • You can use a timer and toggle a gpio. The following example will generate a 4MHz signal on a gpio. It uses only HW peripherals.

    Alternatively, you can configure the SPI to output a 4 MHz clock signal, but then you need to constantly write dummy data to the TXD register.

    #include "nrf.h"
    #include "nrf_gpiote.h"
    #include "bsp.h"
    
    #define OUTPUT_PIN_NUMBER (1)
    
    int main(void)
    {
    	// Configure OUTPUT_PIN_NUMBER as an output.
        nrf_gpio_cfg_output(OUTPUT_PIN_NUMBER);
    
        // Configure GPIOTE channel 0 to toggle the pin state
        nrf_gpiote_task_config(0, OUTPUT_PIN_NUMBER, \
                               NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    	
        // Configure PPI channel 0 to toggle OUTPUT_PIN on every TIMER2 COMPARE[0] match.
        NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TIMER2->EVENTS_COMPARE[0];
        NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[0];
    		
    	// Enable PPI channel 0
        NRF_PPI->CHEN = (PPI_CHEN_CH0_Enabled << PPI_CHEN_CH0_Pos);
    	
        // Start 16 MHz crystal oscillator .
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_HFCLKSTART    = 1;
    
        // Wait for the external oscillator to start up.
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0){}
    		
    	// Configure timer 2
        NRF_TIMER2->MODE      = TIMER_MODE_MODE_Timer;
        NRF_TIMER2->BITMODE   = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
        NRF_TIMER2->PRESCALER = 0;
    	NRF_TIMER2->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
    
        // Clears the timer, sets it to 0.
        NRF_TIMER2->TASKS_CLEAR = 1;
    
        // Load the initial values to TIMER2 CC registers.
        NRF_TIMER2->CC[0] = 2;
    		
    	// Start the timer
    	NRF_TIMER2->TASKS_START = 1;
    		
    	for(;;){}
    }
    
  • Thanks for the example but I think the PPI task needs to be enabled otherwise it wouldn't work. I think you need the following:

    nrf_gpiote_task_configure(0, OUTPUT_PIN_NUMBER, \
                               NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
    nrf_gpiote_task_enable(OUTPUT_PIN_NUMBER); // add this
    
Related