Arm 为什么我不能同时使用Systick和Timer1

Arm 为什么我不能同时使用Systick和Timer1,arm,embedded,stm32,cortex-m,Arm,Embedded,Stm32,Cortex M,我使用Systick定时器创建延迟,Systick处理器每微秒(1µs)发生一次 此外,我使用的是TIM1,它的处理程序每秒发生一次(1s)。 在计时器1处理程序中,我正在切换LED 在while循环中的main函数中,我切换另一个LED(与计时器1处理程序中的LED不同),这里的延迟函数使用Systick 计时器1处理程序按预期执行,但问题是主函数中的while循环从未执行 有什么帮助吗 volatile uint32_t i=0; void TIM1_UP_TIM10_IRQHandler

我使用Systick定时器创建延迟,Systick处理器每微秒(1µs)发生一次

此外,我使用的是TIM1,它的处理程序每秒发生一次(1s)。 在计时器1处理程序中,我正在切换LED

在while循环中的main函数中,我切换另一个LED(与计时器1处理程序中的LED不同),这里的延迟函数使用Systick

计时器1处理程序按预期执行,但问题是主函数中的while循环从未执行

有什么帮助吗

volatile uint32_t i=0;

void TIM1_UP_TIM10_IRQHandler(void)
{
    NVIC_ClearPendingIRQ(TIM1_UP_TIM10_IRQn);   
    i ^= 1;
    if(i == 1)
        LED_On(0);
    else
        LED_Off(0);
    TIM1->SR &= ~(1 << 0); 
}

int main(void)
{
    NVIC_SetPriority(TIM1_UP_TIM10_IRQn, 32);
    NVIC_EnableIRQ(TIM1_UP_TIM10_IRQn);

    LED_Initialize();
    RCC->APB2ENR |= (1 << 0); // Enable Timer1 clock

    TIM1->CR1 &= ~(1 << 4);  // Set the direction of timer to be upcounter
    TIM1->DIER |= (1 << 0);  // Enable tim1 interrupt request

    TIM1->PSC = 15999;  // each count takes 1 msec 
    TIM1->ARR = 1000;   //each 1 sec an overflow update event occurs
    TIM1->CR1 |= (1 << 0);

    SysTick_Init(16000000/1000000);

    while(1)
    {       
        LED_On(1);
        Delay_MS(5000);
        LED_Off(1);
        Delay_MS(5000);
    }

    return 0;
}
volatile uint32\u t i=0;
无效TIM1\U UP\U TIM10\U IRQHandler(无效)
{
NVIC清算组(第1个清算组和第10个清算组);
i^=1;
如果(i==1)
发光二极管(0);
其他的
LED_关闭(0);
TIM1->SR&=~(1 APB2ENR)|=(1 CR1&=~(1 DIER)|=(1 PSC=15999;//每次计数需要1毫秒
TIM1->ARR=1000;//每1秒发生一次溢出更新事件

TIM1->CR1 |=(1这是我的usec延迟fct

//==============================================================================
static  uint32_t    timeMicroSecDivider = 0;
extern  uint32_t    uwTick;

//==============================================================================
//  The SysTick->LOAD match the uC Speed / 1000.
//  If the uC clock is 80MHz, the the LOAD is 80000
//  The SysTick->VAL is the decrement counter from (LOAD-1) to 0
//==============================================================================
uint64_t getTimeMicroSec()
{
  if ( timeMicroSecDivider == 0)
  {
    //  Number of clock by micro second
    timeMicroSecDivider = SysTick->LOAD  / 1000;
  }
  return( (uwTick * 1000) + ((SysTick->LOAD - SysTick->VAL) / timeMicroSecDivider));
}

//==============================================================================
void delayTimeMicroSec(uint32_t delay)
{
  uint64_t tickstart = getTimeMicroSec();

  while ((getTimeMicroSec() - tickstart) < delay)
    ;
}
//==============================================================================
静态uint32_t timeMicroSecDivider=0;
外部uint32_t uwTick;
//==============================================================================
//SysTick->LOAD与uC速度/1000匹配。
//如果uC时钟为80MHz,则负载为80000
//SysTick->VAL是从(LOAD-1)到0的递减计数器
//==============================================================================
uint64_t getTimeMicroSec()
{
if(timeMicroSecDivider==0)
{
//微秒时钟数
timeMicroSecDivider=SysTick->LOAD/1000;
}
返回((uwTick*1000)+((SysTick->LOAD-SysTick->VAL)/timeMicroSecDivider);
}
//==============================================================================
无效延迟时间微秒(uint32\u t延迟)
{
uint64_t tickstart=getTimeMicroSec();
while((getTimeMicroSec()-tickstart)
这是我的usec延迟fct

//==============================================================================
static  uint32_t    timeMicroSecDivider = 0;
extern  uint32_t    uwTick;

//==============================================================================
//  The SysTick->LOAD match the uC Speed / 1000.
//  If the uC clock is 80MHz, the the LOAD is 80000
//  The SysTick->VAL is the decrement counter from (LOAD-1) to 0
//==============================================================================
uint64_t getTimeMicroSec()
{
  if ( timeMicroSecDivider == 0)
  {
    //  Number of clock by micro second
    timeMicroSecDivider = SysTick->LOAD  / 1000;
  }
  return( (uwTick * 1000) + ((SysTick->LOAD - SysTick->VAL) / timeMicroSecDivider));
}

//==============================================================================
void delayTimeMicroSec(uint32_t delay)
{
  uint64_t tickstart = getTimeMicroSec();

  while ((getTimeMicroSec() - tickstart) < delay)
    ;
}
//==============================================================================
静态uint32_t timeMicroSecDivider=0;
外部uint32_t uwTick;
//==============================================================================
//SysTick->LOAD与uC速度/1000匹配。
//如果uC时钟为80MHz,则负载为80000
//SysTick->VAL是从(LOAD-1)到0的递减计数器
//==============================================================================
uint64_t getTimeMicroSec()
{
if(timeMicroSecDivider==0)
{
//微秒时钟数
timeMicroSecDivider=SysTick->LOAD/1000;
}
返回((uwTick*1000)+((SysTick->LOAD-SysTick->VAL)/timeMicroSecDivider);
}
//==============================================================================
无效延迟时间微秒(uint32\u t延迟)
{
uint64_t tickstart=getTimeMicroSec();
while((getTimeMicroSec()-tickstart)
对于SYSTICK中断而言,一微秒的速度是不合理的;特别是在仅以16MHz运行时。您的系统很可能将其近100%的时间花费在中断处理程序的计时上

即使它可以维持1MHz的中断频率,如果
Delay_MS(5000)
是5000个SYSTICK周期的延迟,则您将切换LED和100Hz,并且不会感觉到任何闪烁,只会看到更暗的照明

似乎更可能是您想要一毫秒,这是一个更合理的滴答间隔:

SysTick_Init( 16000000 / 1000 ) ;
尽管事实上我建议:

SysTick_Init( SystemCoreClock / 1000 ) ;
因此,您的代码将适应时钟频率的变化-因为16MHz是运行STM32的一个相当适中的频率


在任何情况下,SYSTICK处理程序和
Delay_MS()也可能
实现有故障,但在看不到该代码的情况下无法猜测。如果两者都提供了库代码,则不太可能出现这种情况。

对于SYSTICK中断而言,一微秒的速度是不合理的;特别是在仅以16MHz运行时。您的系统很可能将其近100%的时间花费在中断h中安德勒在数滴答声

即使它可以维持1MHz的中断频率,如果
Delay_MS(5000)
是5000个SYSTICK周期的延迟,则您将切换LED和100Hz,并且不会感觉到任何闪烁,只会看到更暗的照明

似乎更可能是您想要一毫秒,这是一个更合理的滴答间隔:

SysTick_Init( 16000000 / 1000 ) ;
尽管事实上我建议:

SysTick_Init( SystemCoreClock / 1000 ) ;
因此,您的代码将适应时钟频率的变化-因为16MHz是运行STM32的一个相当适中的频率

在任何情况下,您的SYSTICK处理程序和
Delay\MS()
实现都有可能出现故障,但如果没有看到该代码,就无法进行猜测。如果两者都提供了库代码,则可能性较小

  • 如果您的时钟为16MHz,并且您希望每16个时钟发生一次中断,那么它现在就可以工作。在最佳停止方案(从RAM运行代码等)中,您需要至少11个时钟进入中断处理程序,6个时钟退出中断处理程序,这超过了中断之间的时间

  • 即使你运行得更快,让我们每个人都中断也是个坏主意。168MHz设备在中断之间只有168个时钟。假设你的处理程序将运行20个时钟+11+6=~40个时钟。这意味着25%的处理器时间将用于增加变量!!!不要这样做。在许多其他情况下(最大时钟72或80MHz)情况会更糟

  • 如果您希望我们延迟,请执行类似的操作(如果您重新加载计数器,则需要将其考虑在内)。代码仅用于显示想法

  • #定义滴答声80
    无效延迟(uint32)
    {
    uint32\u t endCnt=SysTick->VAL+uS*滴答声;
    而(SysTick->VAL
  • 如果您的时钟是16MHz,并且您希望每16个时钟发生一次中断,那么它现在就可以工作了