4662|9

7

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

stm32f10 TIM复位模式+DMA+中断 [复制链接]

最近在做曼切斯特的解码,用TIM2-ch2复位模式+输入捕获模式 来捕捉每2个上升沿间的计数值,并用DMA传输到指定数组(编码率1.5M,必须用DMA)。另外,由于一帧数据内的上升沿个数不定,需要检测一帧数据是否结束。我这么考虑的:一帧结束时,TIM2在接收下一帧的上升沿前,计数器肯定溢出,在溢出中断里修改标志位即可;而在接收数据时,TIM2被上升沿复位,不会有溢出。
    但是,程序跑下来发现,使能了TIM2的DMA请求后,TIM2的溢出中断标志位一直为1,清零语句无效。然后,我改用了TIM5-ch2(和TIM2-ch2共用PA1引脚)来做帧结束的检测,仍旧遇到TIM5中断溢出标志一直为1的问题,初始化完成后就直接进入TIM5中断,并且不能清楚中断标志位。用TIM5ch2的代码如下,希望懂的帮忙解答下~
 int main(void)
{
  RCC_Configuration();            
  GPIO_Configuration();
  NVIC_Configuration();   
   DMA_Configuration();
   TIM2_init(); //TIM2 捕捉曼切斯特码2个上升沿间时间,用于解码
   Tim5_init();   //用于超时检测,从触发器复位模式,会被上升沿不断复位 ,直到数据接收完毕,没有上升沿了
    while(1){
  while(decTag){} //decTag 一帧数据结束的标志位,在TIM5的中断函数里设置
   }
}
void RCC_Configuration(void){
  SystemInit();
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA  , ENABLE);
}
void GPIO_Configuration(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;
   
  /* TIM3 channel 2 pin (PA.07) configuration */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;    //PA1对应TIM2-CH2和 TIM5-ch2
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
   GPIO_Init(GPIOA, &GPIO_InitStructure);              
}
void NVIC_Configuration(void)
{
   NVIC_InitTypeDef NVIC_InitStructure;
   /* Enable the TIM3 global Interrupt */
   NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
/* */  
   NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);   
}
void DMA_Configuration(void)
{
   
  TIM_ICInitTypeDef  TIM_ICInitStructure;
  DMA_InitTypeDef  DMA_InitStructure;
     
   TIM_ClearFlag(TIM2, TIM_FLAG_Update);
   TIM_ClearFlag(TIM2, TIM_FLAG_CC2);
   TIM_ClearFlag(TIM2, TIM_FLAG_CC1OF);  
   TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;   //tim2-ch2 上升沿触发
   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
   TIM_ICInitStructure.TIM_ICFilter = 0x0;         
   
    DMA_DeInit(DMA1_Channel7);                     
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)0x40000038; // ((u32)TIM2->CCR2);   
    DMA_InitStructure.DMA_MemoryBaseAddr =(u32)data;           
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;           
    DMA_InitStructure.DMA_BufferSize = 100;   //137  270               数据个数
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;         
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word ; //一字节数据
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;  
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;// DMA_Mode_Circular;           
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                          
   
   TIM_ICInit(TIM2, &TIM_ICInitStructure);   
   TIM_SelectInputTrigger(TIM2, TIM_TS_TI2FP2 );   
   TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset); //  TIM2使用了从触发器,复位模式
   TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable); //启动定时器的被动触发
   TIM_SetCompare2(TIM2, 0); //设置捕获计数器初值

    TIM_DMACmd(TIM2,TIM_DMA_CC2,ENABLE);
    DMA_Init(DMA1_Channel7, &DMA_InitStructure);  
//  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);  
//  DMA_ClearITPendingBit(DMA1_IT_TC7|DMA1_IT_HT7|DMA1_IT_TE7);
     DMA_Cmd(DMA1_Channel7, ENABLE);     
}
void TIM2_init()
{
          //TIM2的设置代码 有部分移到DMA_init()了
  TIM_TimeBaseInitTypeDef  TIM2_TimeBaseStructure;  
  TIM2_TimeBaseStructure.TIM_Prescaler =0;
  TIM2_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //计数器向上计数模式
  TIM2_TimeBaseStructure.TIM_Period =0xFFFF;     
  TIM2_TimeBaseStructure.TIM_ClockDivision = 0x0;     
   
  TIM_TimeBaseInit(TIM2,&TIM2_TimeBaseStructure);
   TIM_ClearFlag(TIM2, TIM_IT_CC2);
    TIM_ARRPreloadConfig(TIM2, DISABLE);
// TIM_ITConfig(TIM2,TIM_IT_CC2,ENABLE);    //TIM2ch2不开中断使能
     TIM_Cmd(TIM2, ENABLE);   
} 

void Tim5_init()
{  
   TIM_ICInitTypeDef  TIM_ICInitStructure;
   TIM_TimeBaseInitTypeDef  TIM5_TimeBaseStructure;
   TIM5_TimeBaseStructure.TIM_Prescaler =0;   
   TIM5_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //计数器向上计数模式
   TIM5_TimeBaseStructure.TIM_Period =2000;//一帧数据结束时的超时
   TIM5_TimeBaseStructure.TIM_ClockDivision = 0x0;   
   TIM_TimeBaseInit(TIM5,&TIM5_TimeBaseStructure);
  
   TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;      
   TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;   //上升沿触发
   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;  //  每次检测到捕获输入就触发一次捕获
   TIM_ICInitStructure.TIM_ICFilter = 0x0;      
   TIM_ICInit(TIM5, &TIM_ICInitStructure);
   TIM_SelectInputTrigger(TIM5, TIM_TS_TI2FP2 );   
   TIM_SelectSlaveMode(TIM5, TIM_SlaveMode_Reset); //复位模式,被上升沿复位
   TIM_SelectMasterSlaveMode(TIM5, TIM_MasterSlaveMode_Enable);
   TIM_SetCompare1(TIM5, 0); //设置捕获计数器初值
      
   TIM_ClearFlag(TIM5, TIM_IT_CC2);
   TIM_ARRPreloadConfig(TIM5, DISABLE);
   TIM_ITConfig(TIM5,TIM_IT_CC2,ENABLE);   //使能 TIM5_ch2的通道2中断
   TIM_Cmd(TIM5, ENABLE);
}
void TIM5_IRQHandler(void)
{  
 if (TIM_GetITStatus(TIM5, TIM_IT_CC2) != RESET){
       DMA1_Channel7->CCR &= (uint16_t)(~DMA_CCR7_EN); // 关DMA
   TIM5->SR = (uint16_t)~TIM_IT_CC2;  //清中断标志
     decTag=1; // 一帧数据接收完,设置标志位
   
      }
}

[ 本帖最后由 Inownl 于 2013-12-5 15:20 编辑 ]
此帖出自stm32/stm8论坛

最新回复

把范围缩小一点, 你这样,先不管帧结束,先取上升沿扑获和dma这块儿行了没有? 信号给进去先看看dma有数据没有?  详情 回复 发表于 2013-12-5 16:32
点赞 关注
 

回复
举报

705

帖子

0

TA的资源

纯净的硅(中级)

沙发
 
好复杂啊
此帖出自stm32/stm8论坛

点评

额。。可能我表达得不清楚,只是想用定时器进行上升沿触发、等待超时能进入中断  详情 回复 发表于 2013-12-5 14:10
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

板凳
 

回复 沙发awarenessxie 的帖子

额。。可能我表达得不清楚,只是想用定时器进行上升沿触发、等待超时能进入中断
此帖出自stm32/stm8论坛
 
 

回复

4008

帖子

0

TA的资源

版主

4
 
程序太乱了,你dma里ccr3,中断又是tim5,设置时tim2ccr2,三个地方都不一样你是想玩连连看吗?
此帖出自stm32/stm8论坛

点评

不好意思啊,注释是用的原来程序的,现在改下~  详情 回复 发表于 2013-12-5 15:03
 
 
 

回复

4008

帖子

0

TA的资源

版主

5
 
复位定时器在哪里?
此帖出自stm32/stm8论坛

点评

tim5用来超时检测的,使用了复位模式,上升沿触发  详情 回复 发表于 2013-12-5 14:59
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

6
 

回复 5楼huo_hu 的帖子

tim5用来超时检测的,使用了复位模式,上升沿触发
此帖出自stm32/stm8论坛
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

7
 

回复 4楼huo_hu 的帖子

鏌ョ湅鏈笘鍏ㄩ儴璁ㄨ锛岃鐧诲綍鎴栬€�娉ㄥ唽
此帖出自stm32/stm8论坛
 
 
 

回复

4008

帖子

0

TA的资源

版主

8
 
鏌ョ湅鏈笘鍏ㄩ儴璁ㄨ锛岃鐧诲綍鎴栬€�娉ㄥ唽
此帖出自stm32/stm8论坛
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

9
 
鏌ョ湅鏈笘鍏ㄩ儴璁ㄨ锛岃鐧诲綍鎴栬€�娉ㄥ唽
此帖出自stm32/stm8论坛

点评

中断进不去的原因找到了,开发板的例程里的中断函数名和startup里定义的不一样,晕....  详情 回复 发表于 2013-12-8 21:36
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

10
 

回复 9楼Inownl 的帖子

鏌ョ湅鏈笘鍏ㄩ儴璁ㄨ锛岃鐧诲綍鎴栬€�娉ㄥ唽
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
福禄克有奖直播:高精度测温赋能电子制造 报名中!
直播时间:2025年2月28日(周五)上午10:00
直播主题:高精度测温赋能电子制造
小伙伴们儿快来报名直播吧~好礼等你拿!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表