首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Arduino millis()在stm32中

Arduino millis()在stm32中
EN

Stack Overflow用户
提问于 2016-05-22 14:28:34
回答 8查看 20.4K关注 0票数 10

我正在尝试将一些Arduino库移植到stm32。在Arduino中,millis()返回自引导以来的毫秒数。在stm32中有等效的函数吗?我使用的是stm32f0单片机。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2016-06-04 08:12:14

SysTick是为此目的提供的ARM核心外围设备。根据您的需要调整如下:

首先,初始化它

代码语言:javascript
复制
// Initialise SysTick to tick at 1ms by initialising it with SystemCoreClock (Hz)/1000

volatile uint32_t counter = 0;
SysTick_Config(SystemCoreClock / 1000);

提供中断处理程序。您的编译器可能需要使用附加属性来修饰中断处理程序。

代码语言:javascript
复制
SysTick_Handler(void) {
  counter++;
}

下面是您的millis()函数,非常简单:

代码语言:javascript
复制
uint32_t millis() {
  return counter;
}

一些需要注意的注意事项。

  1. SysTick是一个24位计数器。它会被溢出。当您比较值或实现延迟方法时,请注意这一点。
  2. SysTick是从处理器核心时钟导出的。如果你扰乱核心时钟,例如放慢它的速度以节省电力,那么SysTick的频率也必须手动调整。
票数 15
EN

Stack Overflow用户

发布于 2016-05-23 08:11:47

你可以用HAL_GetTick(): this function gets current SysTick counter value (incremented in SysTick interrupt) used by peripherals drivers to handle timeouts.

票数 17
EN

Stack Overflow用户

发布于 2017-11-08 11:36:43

我建议用计时器来做。这样你也可以得到1U的步长,只需控制你的时间步长。无论如何,大多数的STM32单片机有8个或更多的计时器,所以在大多数情况下,你可以自由地拿一个。我将展示非常简单的基本概念,如何去做。

只需创建计时器:

代码语言:javascript
复制
uint32_t time = 0;

void enable_timer(void){
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM16, ENABLE);
    TIM_TimeBaseInitTypeDef timerInitStructure;

    /* if MCU frequency 48 MHz, prescaler of value 48 will make 1us counter steps
    timerInitStructure.TIM_Prescaler = 48;

    timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
    /*how often you'll get irq*/
    timerInitStructure.TIM_Period = 0xFFFF; // will get irq each 65535us on TIMx->CNT overflow
    timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM16, &timerInitStructure);
    TIM_Cmd(TIM16, ENABLE);
    NVIC_InitTypeDef NVIC_InitStruct;
    NVIC_InitStruct.NVIC_IRQChannel = TIM16_IRQn;
    /*for more accuracy irq priority should be higher, but now its default*/
    NVIC_InitStruct.NVIC_IRQChannelPriority = 0;
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
    TIM_ClearITPendingBit(TIM16,TIM_IT_Update);
    NVIC_Init(&NVIC_InitStruct);
    TIM_ITConfig(TIM16,TIM_IT_Update,ENABLE);
}

在IRQ,您必须控制计时器计数器的溢出,并更新您的全局时间。

代码语言:javascript
复制
void TIM16_IRQHandler(void){
if (TIM_GetITStatus(TIM16, TIM_IT_Update) != RESET){
    TIM_ClearITPendingBit(TIM16, TIM_IT_Update);
    time +=65535;
}

}

实时将是:

代码语言:javascript
复制
uint32_t real_time_us = time + (uint32_t)TIM16->CNT;

但是如果你可以自由使用32位计时器,你甚至可以不使用IRQ,只需使用time= TIMx->CNT即可。是的,它取决于计时器配置和您的需要,您还必须知道uint32_t时间变量也可能溢出,但这是一个细节,它可以很容易地管理。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37375602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档