MSP432P401R SysTick实现延时函数delay

发布时间 2023-07-22 06:53:10作者: wegret

  在准备电赛时计划移植代码到MSP432P401R上,并用SysTick同时实现一个全局时钟、微秒延时delay_us和毫秒延时delay_us。

  一开始计划通过配置微秒级的时钟周期来实现delay_us,但是很快发现这种方式很容易阻塞主程序,并且SysTick确实一般只用于毫秒计时器……因为我需要用到微秒延时的地方并不要求微秒延时特别精确(在线性CCD中发SI信号),因此我的方案是,先配一个精确的毫秒计时器,然后通过校正每微秒计算次数,来实现微秒延时。

  最后发现效果还不错,相对比较精确,串口输出看看,跑了几分钟,一分钟误差差不多3毫秒,已经达到我需要的精度。

   代码:SysTick.h

#ifndef SYSTICK_H
#define SYSTICK_H

#include "sysinit.h"

void SysTick_Init();
void microsecond_check();

extern volatile uint32_t time_ms;

void delay_ms(uint32_t time_ms);
void delay_us(uint32_t time_us);

#endif

 

  SysTick.c

#include "systick.h"
#include "usart.h"

uint32_t fac_us;

void SysTick_Handler(){
    time_ms++;
}

void SysTick_Init(){
    SysTick->LOAD=CS_getMCLK()/1000-1;
    SysTick->VAL=0;
    SysTick->CTRL=SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk;
    
    microsecond_check();
}
#define MICROCHECK_INTERVAL (100)
void microsecond_check(){
    fac_us=0;
    uint32_t final_time=time_ms+MICROCHECK_INTERVAL;
    while (time_ms<=final_time)
        fac_us++;
    fac_us=fac_us/MICROCHECK_INTERVAL/1000;
    printf("fac_us = %u\n",fac_us);
}

void delay_ms(uint32_t ms){
    static uint32_t end_time;
    end_time=ms+time_ms;
    while (time_ms<end_time);
}
void delay_us(uint32_t time_us){
    static int i;
    i=0;
    while (time_us>0){
        for (i=0;i<fac_us;i++);
        time_us--;
    }
}