cancel
Showing results for 
Search instead for 
Did you mean: 

Unexpected timing with nops

tompa
Associate II

Hi,

I am confused with pin toggle timings, why I am getting non equal pulse widths like in the picture, I turn off all compiler optimizations and disable all of the interrupts, code is simple pin toggling. My controller is STM32L431 running on 80MHz.

Thank you very much for any advice!

__disable_irq();
  while(1) {
	  GPIOB->BSRR = GPIO_BSRR_BS15;	
	  __NOP();
	  __NOP();
	  GPIOB->BSRR = GPIO_BSRR_BR15;	
	  __NOP();
	  __NOP();
  }

  pic2.png

4 REPLIES 4
KnarfB
Principal III

Are you using one of those cheap logic analyzers with a sample rate of 24 MHz or lower?

Perhaps stop doing things this way..

First up, use HW resources, like the TIM to do stuff that is immune to the processor operating in saturation mode. Perhaps have that output as a direct constrast to the two methods, so you're sure you're observing what you think you're observing. As KnarfB points out, this could be a bandwidth/shannon/nyquist issue, some odd beat frequency because you're not observing it with enough bandwidth.

If you're doing saturation mode, at least look at the generated code, or write it all in assembler.

Unwind the loop, use registers/pointers for the interactions.

Watch for how the pipelining, the write-buffers, and the FLASH line reading/caching interact.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi KnarfB,

Thank you for your reply, Yes I am using Saleae Logic with 24Ms/s and my signal is 500KHz so I don't think it is a problem. I also check the signal with 70MHz and 2GSa/s Keysight oscilloscope and result is the same... 

Hi Tesla DeLorean,

Thank you for your replay,

I tried to use DWT but still having unequal pulsee widths.

CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;

__disable_irq();
uint32_t start = DWT->CYCCNT;
while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
	  GPIOB->BSRR = GPIO_BSRR_BS12;  
	  start += 200;                 
	  while (DWT->CYCCNT < start);   

	  GPIOB->BSRR = GPIO_BSRR_BR12;  
	  start += 200;                  
	  while (DWT->CYCCNT < start);   
  }

 Can you please explain this a little bit more:
"Watch for how the pipelining, the write-buffers, and the FLASH line reading/caching interact."
Thanks a lot