¿Por qué el pin del MCU no llega a tiempo?

1

Tengo un STM32F103 y descargué este programa en él (un simple programa de parpadeo):

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"

#define SYSCLK_FREQ_72MHz

/* Private functions ---------------------------------------------------------*/

GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

void GPIO_Configuration(void);

void delay(uint32_t a){
    while(a){
        --a;
    }
}

/*******************************************************************************
* Function Name  : main
* Description    : Main Programme
* Input          : None
* Output         : None
* Return         : None
* Attention      : None
*******************************************************************************/


int main(void)
{
    GPIO_Configuration();


    /* Infinite loop */
    while (1)
    {
        delay(0x44AA200);
        GPIOB->ODR ^= GPIO_Pin_0;

  }
}

/*******************************************************************************
* Function Name  : GPIO_Configuration
* Description    : Configure GPIO Pin
* Input          : None
* Output         : None
* Return         : None
* Attention      : None
*******************************************************************************/
void GPIO_Configuration(void)
{
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB , ENABLE);                        
/**
 *  LED1 -> PB0
 */                  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 
  GPIO_Init(GPIOB, &GPIO_InitStructure);

}

Esperaba que delay(0x44AA200); funcione para 1s pero, pero cuando lo ejecuto, ¡este retardo toma 6s!

¿Por qué ?

¿Está relacionado con la canalización mejorada de 3 etapas?

esta es la configuración de RCC y creo que todo está bien:

yesteeselcódigodeensamblaje:

    
pregunta Roh

2 respuestas

1

Está ejecutando su bucle 72000000 veces.

Parece que piensas que cada ciclo tomará un ciclo de reloj. Sin embargo, como mínimo, incluso el bucle más simple con un contador realizará múltiples operaciones: Desincremento, comparación, salto condicional.

Además, no todas las operaciones de ensamblaje toman solo un ciclo.

En este caso, tiene dos operaciones de ensamblaje en su bucle:

0x080000562 SUBS  r0, r0, #1
0x080000564 BNE   0x080000562

La marca SUBS resta, ( SUB fragmento), y establece banderas condicionales ( S fragmento). La BNE hace una rama ( B fragmento) si no es igual ( NE fragmento).

El STM32F103 es un procesador basado en Cortex M3, lo que significa que usa la arquitectura ARMv7-M . Buscando el Cortex M3 lista de ensamblaje de arquitectura, vemos:

Operation   Description   Assembler           Cycles  
Subtract    Subtract      SUB Rd, Rn, <op2>   1  
Branch      Conditional   B<cc> <label>       1 or 1 + P

Entonces, la operación de resta toma 1 ciclo, y la rama toma 1 (si no se toma la rama), o 1 + P si lo es. P en este caso es:

  

"La cantidad de ciclos requeridos para una recarga de tubería. Esto va desde   1 a 3 según la alineación y el ancho de la instrucción de destino,   y si el procesador logra especular la dirección antes "

En total, asumiendo que P es 3 en este caso, esto solo da como resultado 5 operaciones, por lo que asumo que o bien estás viendo un retardo de cinco segundos, no seis, o es posible que la adición del fragmento S a SUB haga que tome otro ciclo de reloj (pero supongo que allí).

    
respondido por el Connor Wolf
0

Con su CPU funcionando a 72MHz y su valor de retardo 0x44aa200 (72 000 000), está asumiendo que el bucle en su función de retardo solo requiere un ciclo de reloj de la CPU para ejecutarse.

Pero mire el desmontaje: allí hay mucho más que una sola instrucción.

Ha pasado un tiempo desde la última vez que utilicé un STM32, por lo que no puedo recordar exactamente cómo la frecuencia del reloj se traduce en la velocidad de ejecución de instrucciones o si hay alguna canalización o algo similar a considerar.

A juzgar por su observación de que su demora parece tardar 6 segundos en lugar de 1, parece que cada iteración de su bucle de demora en realidad toma 6 ciclos de reloj. Entonces, lo que deberá hacer es dividir su valor de retardo objetivo entre 6.

    
respondido por el brhans

Lea otras preguntas en las etiquetas