110VCGQ/project/110VCGQV6/user/Src/user_stick.c
2024-11-18 10:09:39 +08:00

403 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* user_stick.c
*
* Created on: 2023年1月29日
* Author: wyf
*/
#include "user_stick.h"
//#include "TimeTriggerScheduling.h"
/*这两个全局变量专用于bsp_DelayMs()函数*/
static volatile uint32_t s_uiDelayCount = 0;
static volatile uint8_t s_ucTimeOutFlag = 0;
/* 定于软件定时器结构体变量 */
static SOFT_TMR s_tTmr[TMR_COUNT];
/*
全局运行时间单位1ms
最长可以表示 24.85天,如果你的产品连续运行时间超过这个数,则必须考虑溢出问题
*/
volatile uint32_t g_iRunTime = 0;
static void bsp_SoftTimerDec(SOFT_TMR *_tmr);
/*
*********************************************************************************************************
* 函 数 名: bsp_InitTimer
* 功能说明: 配置systick中断并初始化软件定时器变量
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitTimer(void)
{
uint8_t i;
/* 清零所有的软件定时器 */
for (i = 0; i < TMR_COUNT; i++)
{
s_tTmr[i].Count = 0;
s_tTmr[i].PreLoad = 0;
s_tTmr[i].Flag = 0;
s_tTmr[i].Mode = TMR_ONCE_MODE; /* 缺省是1次性工作模式 */
}
/*
配置systic中断周期为1ms并启动systick中断。
SystemCoreClock 是固件中定义的系统内核时钟对于STM32F4XX,一般为 168MHz
SysTick_Config() 函数的形参表示内核时钟多少个周期后触发一次Systick定时中断.
-- SystemCoreClock / 1000 表示定时频率为 1000Hz 也就是定时周期为 1ms
对于常规的应用我们一般取定时周期1ms。对于低速CPU或者低功耗应用可以设置定时周期为 10ms
*/
// if(SysTick_Config(SystemCoreClock / 1000))
// {
// /* Capture error */
// while (1);
// }
}
/*
*********************************************************************************************************
* 函 数 名: SysTick_ISR
* 功能说明: SysTick中断服务程序每隔1ms进入1次
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
//extern void bsp_RunPer1ms(void);
//extern void bsp_RunPer10ms(void);
void SysTick_ISR(void)
{
static uint8_t s_count = 0;
uint8_t i;
/* 每隔1ms进来1次 (仅用于 bsp_DelayMS */
if (s_uiDelayCount > 0)
{
if (--s_uiDelayCount == 0)
{
s_ucTimeOutFlag = 1;
}
}
/* 每隔1ms对软件定时器的计数器进行减一操作 */
for (i = 0; i < TMR_COUNT; i++)
{
bsp_SoftTimerDec(&s_tTmr[i]);
}
/* 全局运行时间每1ms增1 */
g_iRunTime++;
if (g_iRunTime == 0x7FFFFFFF) /* 这个变量是 int32_t 类型,最大数为 0x7FFFFFFF */
{
g_iRunTime = 0;
}
// bsp_RunPer1ms(); /* 每隔1ms调用一次此函数此函数在 bsp.c */
// 1ms调度一次
if (++s_count >= 10)
{
s_count = 0;
// bsp_RunPer10ms(); /* 每隔10ms调用一次此函数此函数在 bsp.c */
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_SoftTimerDec
* 功能说明: 每隔1ms对所有定时器变量减1。必须被SysTick_ISR周期性调用。
* 形 参: _tmr : 定时器变量指针
* 返 回 值: 无
*********************************************************************************************************
*/
static void bsp_SoftTimerDec(SOFT_TMR *_tmr)
{
if (_tmr->Count > 0)
{
/* 如果定时器变量减到1则设置定时器到达标志 */
if (--_tmr->Count == 0)
{
_tmr->Flag = 1;
/* 如果是自动模式,则自动重装计数器 */
if(_tmr->Mode == TMR_AUTO_MODE)
{
_tmr->Count = _tmr->PreLoad;
}
}
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_StartTimer
* 功能说明: 启动一个定时器,并设置定时周期。
* 形 参: _id : 定时器ID值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID以避免定时器ID冲突。
* _period : 定时周期单位1ms
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_StartTimer(uint8_t _id, uint32_t _period)
{
if (_id >= TMR_COUNT)
{
/* 打印出错的源代码文件名、函数名称 */
// BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__);
while(1); /* 参数异常,死机等待看门狗复位 */
}
DISABLE_INT(); /* 关中断 */
s_tTmr[_id].Count = _period; /* 实时计数器初值 */
s_tTmr[_id].PreLoad = _period; /* 计数器自动重装值,仅自动模式起作用 */
s_tTmr[_id].Flag = 0; /* 定时时间到标志 */
s_tTmr[_id].Mode = TMR_ONCE_MODE; /* 1次性工作模式 */
ENABLE_INT(); /* 开中断 */
}
/*
*********************************************************************************************************
* 函 数 名: bsp_StartAutoTimer
* 功能说明: 启动一个自动定时器,并设置定时周期。
* 形 参: _id : 定时器ID值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID以避免定时器ID冲突。
* _period : 定时周期单位10ms
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_StartAutoTimer(uint8_t _id, uint32_t _period)
{
if (_id >= TMR_COUNT)
{
/* 打印出错的源代码文件名、函数名称 */
// BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__);
while(1); /* 参数异常,死机等待看门狗复位 */
}
DISABLE_INT(); /* 关中断 */
s_tTmr[_id].Count = _period; /* 实时计数器初值 */
s_tTmr[_id].PreLoad = _period; /* 计数器自动重装值,仅自动模式起作用 */
s_tTmr[_id].Flag = 0; /* 定时时间到标志 */
s_tTmr[_id].Mode = TMR_AUTO_MODE; /* 自动工作模式 */
ENABLE_INT(); /* 开中断 */
}
/*
*********************************************************************************************************
* 函 数 名: bsp_StopTimer
* 功能说明: 停止一个定时器
* 形 参: _id : 定时器ID值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID以避免定时器ID冲突。
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_StopTimer(uint8_t _id)
{
if (_id >= TMR_COUNT)
{
/* 打印出错的源代码文件名、函数名称 */
// BSP_Printf("Error: file %s, function %s()\r\n", __FILE__, __FUNCTION__);
while(1); /* 参数异常,死机等待看门狗复位 */
}
DISABLE_INT(); /* 关中断 */
s_tTmr[_id].Count = 0; /* 实时计数器初值 */
s_tTmr[_id].Flag = 0; /* 定时时间到标志 */
s_tTmr[_id].Mode = TMR_ONCE_MODE; /* 自动工作模式 */
ENABLE_INT(); /* 开中断 */
}
/*
*********************************************************************************************************
* 函 数 名: bsp_CheckTimer
* 功能说明: 检测定时器是否超时
* 形 参: _id : 定时器ID值域【0,TMR_COUNT-1】。用户必须自行维护定时器ID以避免定时器ID冲突。
* _period : 定时周期单位1ms
* 返 回 值: 返回 0 表示定时未到, 1表示定时到
*********************************************************************************************************
*/
uint8_t bsp_CheckTimer(uint8_t _id)
{
if (_id >= TMR_COUNT)
{
return 0;
}
if (s_tTmr[_id].Flag == 1)
{
s_tTmr[_id].Flag = 0;
return 1;
}
else
{
return 0;
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_GetRunTime
* 功能说明: 获取CPU运行时间单位1ms。最长可以表示 24.85天,如果你的产品连续运行时间超过这个数,则必须考虑溢出问题
* 形 参: 无
* 返 回 值: CPU运行时间单位1ms
*********************************************************************************************************
*/
int32_t bsp_GetRunTime(void)
{
int32_t runtime;
DISABLE_INT(); /* 关中断 */
runtime = g_iRunTime; /* 这个变量在Systick中断中被改写因此需要关中断进行保护 */
ENABLE_INT(); /* 开中断 */
return runtime;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_CheckRunTime
* 功能说明: 计算当前运行时间和给定时刻之间的差值。处理了计数器循环。
* 形 参: _LastTime 上个时刻
* 返 回 值: 当前时间和过去时间的差值单位1ms
*********************************************************************************************************
*/
int32_t bsp_CheckRunTime(int32_t _LastTime)
{
int32_t now_time;
int32_t time_diff;
DISABLE_INT(); /* 关中断 */
now_time = g_iRunTime; /* 这个变量在Systick中断中被改写因此需要关中断进行保护 */
ENABLE_INT(); /* 开中断 */
if (now_time >= _LastTime)
{
time_diff = now_time - _LastTime;
}
else
{
time_diff = 0x7FFFFFFF - _LastTime + now_time;
}
return time_diff;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_DelayMS
* 功能说明: ms级延迟延迟精度为正负1ms
* 形 参: n : 延迟长度单位1 ms。 n 应大于2
* 返 回 值: 无
*********************************************************************************************************
*/
void delay_ms(uint32_t n)
{
if (n == 0)
{
return;
}
else if (n == 1)
{
n = 2;
}
DISABLE_INT(); /* 关中断 */
s_uiDelayCount = n;
s_ucTimeOutFlag = 0;
ENABLE_INT(); /* 开中断 */
while (1)
{
/*
等待延迟时间到
注意:编译器认为 s_ucTimeOutFlag = 0所以可能优化错误因此 s_ucTimeOutFlag 变量必须申明为 volatile
*/
if (s_ucTimeOutFlag == 1)
{
break;
}
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_DelayUS
* 功能说明: us级延迟。 必须在systick定时器启动后才能调用此函数。
* 形 参: n : 延迟长度单位1 us
* 返 回 值: 无
*********************************************************************************************************
*/
void delay_us(uint32_t n)
{
uint32_t ticks;
uint32_t told;
uint32_t tnow;
uint32_t tcnt = 0;
uint32_t reload;
reload = SysTick->LOAD;
ticks = n * (SystemCoreClock / 1000000); /* 需要的节拍数 */
tcnt = 0;
told = SysTick->VAL; /* 刚进入时的计数器值 */
while (1)
{
tnow = SysTick->VAL;
if (tnow != told)
{
/* SYSTICK是一个递减的计数器 */
if (tnow < told)
{
tcnt += told - tnow;
}
/* 重新装载递减 */
else
{
tcnt += reload - tnow + told;
}
told = tnow;
/* 时间超过/等于要延迟的时间,则退出 */
if (tcnt >= ticks)
{
break;
}
}
}
}
/*
*********************************************************************************************************
* 函 数 名: SysTick_Handler
* 功能说明: 系统嘀嗒定时器中断服务程序。启动文件中引用了该函数。
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
/*****************************END OF FILE*********************************/