STM32 使用中断模拟计算频率
测试环境
stm32f105rc。
main.c
LibTIM1_SysTimerInit(20,7200); //Init 2MS 系统计时器初始化 ((arr+1)*(psc+1))/Tclk;
LibTimer.c
/*******************************************************************************
* 定时器1中断服务程序
*******************************************************************************/
void TIM1_UP_IRQHandler(void) //TIM1中断
{
u8 i=0;
if (TIM_GetITStatus(TIM1, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM1, TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
//系统运行逻辑定时器10个
LibVarSystemIntTimer2Ms[0]++;
LibVarSystemIntTimer2Ms[1]++;
LibVarSystemIntTimer2Ms[2]++;
LibVarSystemIntTimer2Ms[3]++;
LibVarSystemIntTimer2Ms[4]++;
LibVarSystemIntTimer2Ms[5]++;
LibVarSystemIntTimer2Ms[6]++;
LibVarSystemIntTimer2Ms[7]++;
LibVarSystemIntTimer2Ms[8]++;
LibVarSystemIntTimer2Ms[9]++;
LibVarSystemIntTimer2Ms[10]++;
//系统时间
LibVarSystemTimer2Ms++;
LibVarSystemTimer10Ms = LibVarSystemTimer2Ms/5;
//50MS
if((LibVarSystemTimer2Ms%25)==0)
{
LibVarPiCounterArray[19] = LibVarPiCounterArray[18];
LibVarPiCounterArray[18] = LibVarPiCounterArray[17];
LibVarPiCounterArray[17] = LibVarPiCounterArray[16];
LibVarPiCounterArray[16] = LibVarPiCounterArray[15];
LibVarPiCounterArray[15] = LibVarPiCounterArray[14];
LibVarPiCounterArray[14] = LibVarPiCounterArray[13];
LibVarPiCounterArray[13] = LibVarPiCounterArray[12];
LibVarPiCounterArray[12] = LibVarPiCounterArray[11];
LibVarPiCounterArray[11] = LibVarPiCounterArray[10];
LibVarPiCounterArray[10] = LibVarPiCounterArray[9];
LibVarPiCounterArray[9] = LibVarPiCounterArray[8];
LibVarPiCounterArray[8] = LibVarPiCounterArray[7];
LibVarPiCounterArray[7] = LibVarPiCounterArray[6];
LibVarPiCounterArray[6] = LibVarPiCounterArray[5];
LibVarPiCounterArray[5] = LibVarPiCounterArray[4];
LibVarPiCounterArray[4] = LibVarPiCounterArray[3];
LibVarPiCounterArray[3] = LibVarPiCounterArray[2];
LibVarPiCounterArray[2] = LibVarPiCounterArray[1];
LibVarPiCounterArray[1] = LibVarPiCounterArray[0];
LibVarPiCounterArray[0] = LibVarPiCounterOrg;
LibVarPiCounterOrg = 0;
switch(LibVarPiSampleTime[0])
{
case 1000:
LibVarPiFreNow = LibVarPiCounterArray[0];
LibVarPiFreNow += LibVarPiCounterArray[1];
LibVarPiFreNow += LibVarPiCounterArray[2];
LibVarPiFreNow += LibVarPiCounterArray[3];
LibVarPiFreNow += LibVarPiCounterArray[4];
LibVarPiFreNow += LibVarPiCounterArray[5];
LibVarPiFreNow += LibVarPiCounterArray[6];
LibVarPiFreNow += LibVarPiCounterArray[7];
LibVarPiFreNow += LibVarPiCounterArray[8];
LibVarPiFreNow += LibVarPiCounterArray[9];
LibVarPiFreNow += LibVarPiCounterArray[10];
LibVarPiFreNow += LibVarPiCounterArray[11];
LibVarPiFreNow += LibVarPiCounterArray[12];
LibVarPiFreNow += LibVarPiCounterArray[13];
LibVarPiFreNow += LibVarPiCounterArray[14];
LibVarPiFreNow += LibVarPiCounterArray[15];
LibVarPiFreNow += LibVarPiCounterArray[16];
LibVarPiFreNow += LibVarPiCounterArray[17];
LibVarPiFreNow += LibVarPiCounterArray[18];
LibVarPiFreNow += LibVarPiCounterArray[19];
LibVarPiFreNow /= 2;
break;
case 500:
LibVarPiFreNow = LibVarPiCounterArray[0];
LibVarPiFreNow += LibVarPiCounterArray[1];
LibVarPiFreNow += LibVarPiCounterArray[2];
LibVarPiFreNow += LibVarPiCounterArray[3];
LibVarPiFreNow += LibVarPiCounterArray[4];
LibVarPiFreNow += LibVarPiCounterArray[5];
LibVarPiFreNow += LibVarPiCounterArray[6];
LibVarPiFreNow += LibVarPiCounterArray[7];
LibVarPiFreNow += LibVarPiCounterArray[8];
LibVarPiFreNow += LibVarPiCounterArray[9];
break;
case 200:
LibVarPiFreNow = LibVarPiCounterArray[0];
LibVarPiFreNow += LibVarPiCounterArray[1];
LibVarPiFreNow += LibVarPiCounterArray[2];
LibVarPiFreNow += LibVarPiCounterArray[3];
LibVarPiFreNow *= 5;
LibVarPiFreNow /= 2;
break;
case 100:
LibVarPiFreNow = LibVarPiCounterArray[0];
LibVarPiFreNow += LibVarPiCounterArray[1];
LibVarPiFreNow *= 5;
break;
}
}
}
}
/* ******************************************************
** 函数名称:LibTIM1_SysTimerInit
** 功能描述:TIM1中断初始化配置--系统计时器
** 传入参数:无
** 返回数据:无
** *************************************************** */
void LibTIM1_SysTimerInit(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseStructure.TIM_Period = (arr - 1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler =(psc - 1); //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;//重复计数设置
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ClearFlag(TIM1, TIM_FLAG_Update);//清中断标志位
TIM_ITConfig(TIM1, TIM_IT_Update,ENABLE); //使能指定的TIM1中断,允许更新中断和触发中断
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; //TIM1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
TIM_Cmd(TIM1, ENABLE); //使能TIMx外设
}
LibPI.c
#include "LibVar.h"
#include "LibFun.h"
static u8 VarPB8StatusNow = 0;
static u8 VarPB8StatusLast = 0;
static void LibGpioConfig_DO(void);
static void LibTIM3_PiInit(u16 arr,u16 psc);
///* ******************************************************
//** 函数名称:TIM3_IRQHandler
//** 功能描述: 定时器3中断服务程序
//** 传入参数:无
//** 返回数据:无
//** 创建时间:胡棕亮 2018-11-07
//** *************************************************** */
void TIM3_IRQHandler(void) //TIM4中断
{
LibVarSystemTimer200Us++;
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM3 , TIM_IT_Update); //清除TIMx的中断待处理位:TIM 中断源
VarPB8StatusNow = GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_2);
if(VarPB8StatusNow>0 && VarPB8StatusLast==0)
{
LibVarPiCounterOrg++;
}
else if(VarPB8StatusNow==0 && VarPB8StatusLast==1)
{
LibVarPiCounterOrg++;
}
VarPB8StatusLast = VarPB8StatusNow;
}
}
/* ******************************************************
** 函数名称:LibGpioConfig_DO
** 功能描述:DO GPIO配置
** 传入参数:无
** 返回数据:无
** *************************************************** */
static void LibGpioConfig_DO(void)
{
#ifndef __RCC_ENABLE_TIM3
#define __RCC_ENABLE_TIM3
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能TIM3
#endif
#ifndef __RCC_ENABLE_GPIOD
#define __RCC_ENABLE_GPIOD
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE); //使能GPIOD
#endif
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PI0:PD2
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_ResetBits(GPIOD,GPIO_Pin_2); //拉低
}
/* ******************************************************
** 函数名称:LibTimer4Init
** 功能描述:TIM4 配置
** 传入参数:arr:自动重装值,psc:时钟预分频数
** 返回数据:无
** *************************************************** */
static void LibTIM3_PiInit(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_TimeBaseStructure.TIM_Period = (arr - 1); //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms
TIM_TimeBaseStructure.TIM_Prescaler =(psc - 1); //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器
//TIM_ETRClockMode2Config(TIM3,TIM_ExtTRGPSC_OFF,TIM_ExtTRGPolarity_NonInverted,0);
//TIM_SetCounter(TIM3, 0); // 清零计数器CNT
TIM_Cmd(TIM3, ENABLE); //使能TIMx外设
}
/* ******************************************************
** 函数名称:LibPiInit
** 功能描述:PI初始化
** 传入参数:无。
** 返回数据:无。
** *************************************************** */
void LibPiInit(void)
{
LibGpioConfig_DO();
LibTIM3_PiInit(3600,4);//200us
}
/* ******************************************************
** 函数名称:LibPiSetSampleTime
** 功能描述:设置PI采样时间
** 传入参数:Channal,通道号,取值范围0;SampleTime,采样时间,单位毫秒,取值范围100/200/500/1000。
** 返回数据:为0则设置成功,为1则通道号错误。
** *************************************************** */
u16 LibPiSetSampleTime(u8 Channal,u16 SampleTime)
{
if(Channal<1)
{
switch(SampleTime)
{
case 1000:
case 500:
case 200:
case 100:
LibVarPiSampleTime[Channal] = SampleTime;
break;
}
return 0;
}
else
{
return 1;
}
}
/* ******************************************************
** 函数名称:LibPiReadFrequency
** 功能描述:读取当前PI采样频率
** 传入参数:无
** 返回数据:无
** *************************************************** */
u16 LibPiReadFrequency(u8 Channal)
{
return LibVarPiFreNow;
}
LibFun.c
/******************************************************************/
//PI操作函数
/******************************************************************/
extern void LibPiInit(void);
extern u16 LibPiSetSampleTime(u8 Channal,u16 SampleTime);
extern u16 LibPiReadFrequency(u8 Channal);
LibVar.c
/******************************************************************/
//PI变量
/******************************************************************/
u16 LibVarPiSampleTime[1]= {500};// PI采样时间,单位ms
u16 LibVarPiCounterOrg = 0; // PI计数值
u16 LibVarPiCounterArray[20]; // PI计数值
u16 LibVarPiFreNow = 0; //Hz
LibVar.h
/******************************************************************/
//PI变量
/******************************************************************/
extern u16 LibVarPiSampleTime[1];// PI采样时间,单位ms
extern u16 LibVarPiCounterOrg; // PI计数值
extern u16 LibVarPiCounterArray[20];
extern u16 LibVarPiFreNow; //Hz