定时器中断问题。各位网友大家早上好,向大家请教一个定时器中断问题

2019-07-20 03:58发布

最近在做一个两路信号源,用的两片德州仪器的DAC8820,用定时器中断不断的往GPIOD和GPIOE送16位的并行数据。使用的定时器3和定时器4两个定时器。当我两路信号源都要输出的时候,也就是两个定时器都要不停的进入中断,两路信号都输出5KHz信号的时候,两路信号的频率都正常。定时时间我是这样计算的:信号频率小于等于10KHZ的时候,每个周期100个点,以5Khz为例,信号频率为5K,1S中需要5000*100的点,定时器时钟频率为42M,那么计数值就是42000000/(5000*100),以这种方式其中一路信号输出10K的时候,另一路信号的频率就不准了。这是什么情况啊,是优先级的问题还是什么问题啊?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
11条回答
PhinexZhang
1楼-- · 2019-07-20 06:14
追加一下代码

void Timer3_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);  ///使能TIM3时钟
       
  TIM_TimeBaseInitStructure.TIM_Period = arr-1;         //自动重装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc-1;  //定时器分频
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3
       
        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
        TIM_Cmd(TIM3,ENABLE); //使能定时器3
       
        NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x2; //抢占优先级1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x0; //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}

void Timer4_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);  ///使能TIM3时钟
       
  TIM_TimeBaseInitStructure.TIM_Period = arr-1;         //自动重装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc-1;  //定时器分频
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);//初始化TIM3
       
        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //允许定时器3更新中断
        TIM_Cmd(TIM4,ENABLE); //使能定时器3
       
        NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn; //定时器3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x2; //抢占优先级1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x1; //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}
void Timer4_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);  ///使能TIM3时钟
       
  TIM_TimeBaseInitStructure.TIM_Period = arr-1;         //自动重装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc-1;  //定时器分频
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);//初始化TIM3
       
        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //允许定时器3更新中断
        TIM_Cmd(TIM4,ENABLE); //使能定时器3
       
        NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn; //定时器3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x2; //抢占优先级1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x1; //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}

void Timer4_Init(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);  ///使能TIM3时钟
       
  TIM_TimeBaseInitStructure.TIM_Period = arr-1;         //自动重装载值
        TIM_TimeBaseInitStructure.TIM_Prescaler=psc-1;  //定时器分频
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
       
        TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);//初始化TIM3
       
        TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE); //允许定时器3更新中断
        TIM_Cmd(TIM4,ENABLE); //使能定时器3
       
        NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn; //定时器3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x2; //抢占优先级1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x1; //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}


void TIM3_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
        {
                GPIOD->ODR = Wave1_Buffer[cnt1++];
                if(cnt1>=BUFFER1_SIZE)        cnt1=0;       
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}

void TIM4_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET) //溢出中断
        {
                GPIOE->ODR = Wave2_Buffer[cnt2++];
                if(cnt2>=BUFFER2_SIZE)        cnt2=0;       
        }
        TIM_ClearITPendingBit(TIM4,TIM_IT_Update);  //清除中断标志位
}

void Setup_Frequency(uint8_t channel,uint16_t counter,uint8_t psc)
{
        switch(channel)
        {
                case CHANNEL1:Timer3_Init(counter,psc);break;
                case CHANNEL2:Timer4_Init(counter,psc);break;
                default:break;
        }
}
需要信号的时候开始初始化定时器及中断
cjsyrzy
2楼-- · 2019-07-20 11:58
 精彩回答 2  元偷偷看……
PhinexZhang
3楼-- · 2019-07-20 17:03
 精彩回答 2  元偷偷看……
PhinexZhang
4楼-- · 2019-07-20 18:14
cjsyrzy 发表于 2019-1-24 11:07
我的理解是5kHz时,每秒要进入timer中断500000次,两次中断间隔2us,10kHz时,两次中断间隔1us,太短了,必 ...

这个可以用DMA来传输吗,但是还是会用到定时器啊
PhinexZhang
5楼-- · 2019-07-20 19:36
cjsyrzy 发表于 2019-1-24 11:07
我的理解是5kHz时,每秒要进入timer中断500000次,两次中断间隔2us,10kHz时,两次中断间隔1us,太短了,必 ...

这个可以用DMA来传输吗,但是还是会用到定时器啊
PhinexZhang
6楼-- · 2019-07-20 22:36
 精彩回答 2  元偷偷看……

一周热门 更多>