回复于:织女星开发板RISC-V内核实现微秒级精确延时

Home 论坛 开发和更新问题 织女星开发板RISC-V内核实现微秒级精确延时 回复于:织女星开发板RISC-V内核实现微秒级精确延时

#1994
chao wangwhik
参与者

更新RISC-V核延时函数

原文链接: 织女星开发板RISC-V内核SysTick实现精确延时

RISC-V RI5CY 和 ZERO Core的SysTick使用的定时器不一样,延时函数需要根据内核的不同来进行条件编译。

  • RISC-V RI5CY Core:LPIT0_CH0
  • RISC-V ZERO Core:LPIT1_CH0

delay.c文件内容

#include "delay.h"

/*
 * ZERO : LPIT1_CH0
 * RI5CY: LPIT0_CH0
 * */

static uint8_t  fac_us=0;
static uint16_t fac_ms=0;

#if defined(CPU_RV32M1_zero_riscy)

/*
 * RISC_V ZERO 使用 LPIT1_CH0作为SysTick,与RI5CY不同
 * */

void Delay_Init(void)
{
    CLOCK_SetIpSrc(kCLOCK_Lpit1, kCLOCK_IpSrcFircAsync);	//设置定时器时钟48MHz
    LOG("LPIT1时钟: %ld \r\n", CLOCK_GetIpFreq(kCLOCK_Lpit1));	//输出LPIT0时钟

    CLOCK_EnableClock(kCLOCK_Lpit1);	//使能时钟
    LPIT_Reset(LPIT1);					//复位定时器
    LPIT1->MCR = LPIT_MCR_M_CEN_MASK;	//使能定时器

    fac_us = CLOCK_GetIpFreq(kCLOCK_Lpit1)/1000000;
    fac_ms = fac_us*1000;
}

void Delay_us(uint32_t Nus)
{
    LPIT1->CHANNEL[kLPIT_Chnl_0].TVAL =  48 * Nus - 1;					//加载时间
    LPIT1->SETTEN |= (LPIT_SETTEN_SET_T_EN_0_MASK << kLPIT_Chnl_0);		//启动定时器
    while(LPIT1->CHANNEL[kLPIT_Chnl_0].CVAL);							//等待计数值到0
//	while((LPIT1->MSR & 0x0001) != 0x01);								//等待溢出
//	LPIT0->MSR |= (1U << kLPIT_Chnl_0);									//写1,清除中断
    LPIT1->CLRTEN |= (LPIT_CLRTEN_CLR_T_EN_0_MASK << kLPIT_Chnl_0);		//清除计数器
}

void Delay_ms(uint32_t Nms)
{
    LPIT1->CHANNEL[kLPIT_Chnl_0].TVAL = Nms * fac_ms  - 1;			//加载时间
    LPIT1->SETTEN |= (LPIT_SETTEN_SET_T_EN_0_MASK << kLPIT_Chnl_0);	//启动定时器
    while(LPIT1->CHANNEL[kLPIT_Chnl_0].CVAL);						//等待计数到0
//	while((LPIT1->MSR & 0x0001) != 0x0001);							//等待产生中断
//	LPIT0->MSR |= (1U << kLPIT_Chnl_0);								//向中断标志位写1,清除中断
    LPIT1->CLRTEN |= (LPIT_CLRTEN_CLR_T_EN_0_MASK << kLPIT_Chnl_0);	//清除计数器
}

#elif defined(CPU_RV32M1_ri5cy)

/*
 * RISC_V RI5CY 使用 LPIT0_CH0作为SysTick,与ZERO不同
 * */

void Delay_Init(void)
{
    CLOCK_SetIpSrc(kCLOCK_Lpit0, kCLOCK_IpSrcFircAsync);	//设置定时器时钟48MHz
    LOG("LPIT0时钟: %ld \r\n", CLOCK_GetIpFreq(kCLOCK_Lpit0));	//输出LPIT0时钟

    CLOCK_EnableClock(kCLOCK_Lpit0);	//使能时钟
    LPIT_Reset(LPIT0);					//复位定时器
    LPIT0->MCR = LPIT_MCR_M_CEN_MASK;	//使能定时器

    fac_us = CLOCK_GetIpFreq(kCLOCK_Lpit0)/1000000;
    fac_ms = fac_us*1000;
}

void Delay_us(uint32_t Nus)
{
    LPIT0->CHANNEL[kLPIT_Chnl_0].TVAL =  48 * Nus - 1;					//加载时间
    LPIT0->SETTEN |= (LPIT_SETTEN_SET_T_EN_0_MASK << kLPIT_Chnl_0);		//启动定时器
    while(LPIT0->CHANNEL[kLPIT_Chnl_0].CVAL);							//等待计数值到0
//	while((LPIT0->MSR & 0x0001) != 0x01);								//等待溢出
//	LPIT0->MSR |= (1U << kLPIT_Chnl_0);									//写1,清除中断
    LPIT0->CLRTEN |= (LPIT_CLRTEN_CLR_T_EN_0_MASK << kLPIT_Chnl_0);		//清除计数器
}

void Delay_ms(uint32_t Nms)
{
    LPIT0->CHANNEL[kLPIT_Chnl_0].TVAL = Nms * fac_ms  - 1;			//加载时间
    LPIT0->SETTEN |= (LPIT_SETTEN_SET_T_EN_0_MASK << kLPIT_Chnl_0);	//启动定时器
    while(LPIT0->CHANNEL[kLPIT_Chnl_0].CVAL);						//等待计数到0
//	while((LPIT0->MSR & 0x0001) != 0x0001);							//等待产生中断
//	LPIT0->MSR |= (1U << kLPIT_Chnl_0);								//向中断标志位写1,清除中断
    LPIT0->CLRTEN |= (LPIT_CLRTEN_CLR_T_EN_0_MASK << kLPIT_Chnl_0);	//清除计数器
}

#endif

delay.h文件内容

#ifndef __DELAY_H__
#define __DELAY_H__

#include "fsl_lpit.h"
#include "fsl_debug_console.h"
#include "sys.h"

/*
 * ZERO : LPIT1_CH0
 * RI5CY: LPIT0_CH0
 * */

void Delay_Init(void);

void Delay_ms(uint32_t Nms);
void Delay_us(uint32_t Nus);


#endif