Precauções para o uso de sistema de microcontrolador STM32

índice

1. Introdução

2. Precauções para configuração de systick


1. Introdução

O processamento do núcleo CM4 é igual ao do CM3. Inclui um temporizador SysTick interno . O SysTick é um temporizador de contagem regressiva de 24 bits. Quando a contagem chega a 0, ele recarrega automaticamente o valor inicial de temporização do registrador RELOAD. Enquanto não limpar o bit de habilitação no controle SysTick e registro de status, ele nunca irá parar. Desta forma, a systick pode ser usada para realizar a função de temporização de atraso, sem ocupar o temporizador do sistema. Systick também é usado como a batida do relógio do sistema, como freeRTOS e outros SO. Quando o agendador é iniciado, o systick é configurado como o relógio do sistema para fornecer ao sistema uma batida do coração. Existem 4 registros CTRL, LOAD, VAL, CALIB no systick

2. Precauções para configuração de systick

No código gerado usando a configuração CubeMX, uma função SystemClock_Config () será gerada automaticamente para configurar o relógio do microcomputador de chip único, e o systick será configurado

void SystemClock_Config()
{
    ...........
    LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
    LL_SetSystemCoreClock(32000000);
#ifndef SYSTICK_IRQ
    LL_Init1msTick(32000000); //使能systick但是不开启systick中断
#else
    SysTick_Config(SystemCoreClock / 1000);//使能systick同时开启systick中断
#endif
}

Mas o que precisa de atenção aqui é se é necessário habilitar a interrupção do systick! ! ! !

1. Se você deseja usar a systick apenas como um atraso e o programa não deseja ser interrompido por interrupções, você só precisa habilitar a systick em vez de habilitar as interrupções da systick e chamar LL_Init1msTick.

void LL_Init1msTick(uint32_t HCLKFrequency)
    ---> LL_InitTick(HCLKFrequency, 1000U);
        ---> __STATIC_INLINE void LL_InitTick(uint32_t HCLKFrequency, uint32_t Ticks)
            {
                  /* Configure the SysTick to have interrupt in 1ms time base */
                  SysTick->LOAD  = (uint32_t)((HCLKFrequency / Ticks) - 1UL);  /* set reload register */
                  SysTick->VAL   = 0UL;  /* Load the SysTick Counter Value */
                  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                                   SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */
            }

Mas você mesmo precisa escrever a função de atraso e não pode usar o HAL_Delay () fornecido pela biblioteca HAL. O motivo é o seguinte: A implementação de HAL_Delay depende de uma variável uwTickFreq, uwTickFreq é acumulada em HAL_IncTick e precisa ser chamada periodicamente na função de interrupção SysTick_Handler, de modo que HAL_Delay tenha um benchmark

__weak void HAL_IncTick(void)
{
  uwTick += uwTickFreq;
}
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}
__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick();
  uint32_t wait = Delay;

  /* Add a period to guaranty minimum wait */
  if (wait < HAL_MAX_DELAY)
  {
    wait += (uint32_t)(uwTickFreq);
  }

  while((HAL_GetTick() - tickstart) < wait)
  {
  }
}

Custom us delay

void my_delay_us(uint32_t nus)
{		
	uint32_t temp;	
	uint32_t fac_us = SystemCoreClock/1000000;	  //为系统时钟的1/1000000  	
	SysTick->LOAD   = nus*fac_us; 			      //时间加载	  		 
	SysTick->VAL    = 0x00;        			      //清空计数器
	SysTick->CTRL  |= SysTick_CTRL_ENABLE_Msk ;	  //开始倒数	  
	do
	{
		temp = SysTick->CTRL;
	}
	while((temp & 0x01) &&! (temp&(1 << 16)));	 //等待时间到达   
	SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;	 //关闭计数器
	SysTick->VAL = 0X00;      					 //清空计数器	 
}

2. Se você quiser usar a batida do relógio do sistema de assento da systick, você precisa ligar a interrupção da systick, você pode chamar diretamente SysTick_Config para configurar, ou você pode usar HAL_Init para configurar, a configuração HAL_Init irá eventualmente chamar a função SysTick_Config

 HAL_Init(void)
    ---> HAL_InitTick(uint32_t TickPriority)
        ---> SysTick_Config(uint32_t ticks)
            {
              if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
              {
                return (1UL);                                                   /* Reload value impossible */
              }
            
              SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* set reload register */
              NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
              SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
              SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                               SysTick_CTRL_TICKINT_Msk   |
                               SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
              return (0UL);                                                     /* Function successful */
            }

Depois que essa configuração for concluída, osSystickHandler e HAL_IncTick precisam ser chamados na interrupção do systick

void SysTick_Handler(void)
{
	osSystickHandler();//为OS提供系统时钟节拍
	HAL_IncTick();//为HAL库提供时钟基准
}

 

Acho que você gosta

Origin blog.csdn.net/m0_37845735/article/details/108439464
Recomendado
Clasificación