Arm 为什么我不能同时使用Systick和Timer1
我使用Systick定时器创建延迟,Systick处理器每微秒(1µs)发生一次 此外,我使用的是TIM1,它的处理程序每秒发生一次(1s)。 在计时器1处理程序中,我正在切换LED 在while循环中的main函数中,我切换另一个LED(与计时器1处理程序中的LED不同),这里的延迟函数使用Systick 计时器1处理程序按预期执行,但问题是主函数中的while循环从未执行 有什么帮助吗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
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个时钟发生一次中断,那么它现在就可以工作了