历史上的今天
返回首页

历史上的今天

今天是:2024年10月05日(星期六)

正在发生

2018年10月05日 | STM32f4输入捕获实验代码

2018-10-05 来源:eefocus

我们来看看 timer.c文件中,我们添加的两个函数的内容:

TIM_ICInitTypeDef  TIM5_ICInitStructure;

//定时器 5通道1 输入捕获配置

//arr:自动重装值(TIM2,TIM5 是 32位的!!)        psc:时钟预分频数

void TIM5_CH1_Cap_Init(u32 arr,u16 psc)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  TIM_TimeBaseInitTypeDef   TIM_TimeBaseStructure;

  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);  //TIM5时钟使能     

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟

  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  //速度 100MHz

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉

  GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0

 

  GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0复用位定时器5

   

  TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频

  TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式

  TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值

  TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;  

  TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);

  

  TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //选择输入端  IC1 映射到TI1上

     TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;  //上升沿捕获

     TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到 TI1 上

     TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;    //配置输入分频,不分频  

     TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波

      TIM_ICInit(TIM5, &TIM5_ICInitStructure); //初始化 TIM5输入捕获参数

    

  TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新和捕获中断 

      TIM_Cmd(TIM5,ENABLE );    //使能定时器 5

 

       NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级2

  NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;//响应优先级0

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  //IRQ 通道使能

  NVIC_Init(&NVIC_InitStructure);  //根据指定的参数初始化VIC 寄存器、

}

//捕获状态

//[7]:0,没有成功的捕获;1,成功捕获到一次.

//[6]:0,还没捕获到低电平;1,已经捕获到低电平了.

//[5:0]:捕获低电平后溢出的次数(对于32位定时器来说,1us计数器加1,溢出时间:4294秒)

u8  TIM5CH1_CAPTURE_STA=0;  //输入捕获状态                 

u32  TIM5CH1_CAPTURE_VAL;  //输入捕获值(TIM2/TIM5是 32位)

//定时器 5中断服务程序    

void TIM5_IRQHandler(void)

{  

    if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获  

  {

    if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)//溢出

    {        

      if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了

      {

        if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了

        {

          TIM5CH1_CAPTURE_STA|=0X80;    //标记成功捕获了一次

          TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;

        }else TIM5CH1_CAPTURE_STA++;

      }    

    }

    if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//捕获 1发生捕获事件

    {  

      if(TIM5CH1_CAPTURE_STA&0X40)  //捕获到一个下降沿      

      {           

         TIM5CH1_CAPTURE_STA|=0X80;  //标记成功捕获到一次高电平脉宽

         TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//获取当前的捕获值.

           TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //设置上升沿捕获

      }else                 //还未开始,第一次捕获上升沿

      {

         TIM5CH1_CAPTURE_STA=0;  //清空

         TIM5CH1_CAPTURE_VAL=0;

         TIM5CH1_CAPTURE_STA|=0X40;//标记捕获到了上升沿

         TIM_Cmd(TIM5,ENABLE );    //使能定时器 5

           TIM_SetCounter(TIM5,0); //计数器清空

           TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling);//设置下降沿捕获

         TIM_Cmd(TIM5,ENABLE );    //使能定时器 5

      }         

    }                                 

    }

  TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //清除中断标志位

}

此部分代码包含两个函数,其中TIM5_CH1_Cap_Init函数用于 TIM5通道 1的输入捕获设置,其设置和我们上面讲的步骤是一样的,这里就不多说,特别注意:TIM5 是 32 位定时器,所以 arr是u32 类型的。接下来,重点来看看第二个函数。

TIM5_IRQHandler 是 TIM5 的中断服务函数,该函数用到了两个全局变量,用于辅助实现高电平捕获。其中TIM5CH1_CAPTURE_STA,是用来记录捕获状态,该变量类似我们在usart.c里面自行定义的USART_RX_STA 寄存器(其实就是个变量,只是我们把它当成一个寄存器那样来使用)。TIM5CH1_CAPTURE_STA各位描述如表15.3.1所示:

TIM5CH1_CAPTURE_STA

bit7  bit6  bit5~0

捕获完成标志  捕获到高电平标志  捕获高电平后定时器溢出的次数

表15.3.1 TIM5CH1_CAPTURE_STA各位描述

  另外一个变量TIM5CH1_CAPTURE_VAL,则用来记录捕获到下降沿的时候,TIM5_CNT的值。

  现在我们来介绍一下,捕获高电平脉宽的思路:首先,设置TIM5_CH1 捕获上升沿,这在TIM5_Cap_Init函数执行的时候就设置好了,然后等待上升沿中断到来, 当捕获到上升沿中断,此时如果TIM5CH1_CAPTURE_STA的第6 位为 0,则表示还没有捕获到新的上升沿,就先把TIM5CH1_CAPTURE_STA、TIM5CH1_CAPTURE_VAL和计数器值TIM5->CNT 等清零,然后再设置TIM5CH1_CAPTURE_STA的第6 位为1, 标记捕获到高电平, 最后设置为下降沿捕获,等待下降沿到来。如果等待下降沿到来期间,定时器发生了溢出(对 32 位定时器来说,很难溢出) ,就在TIM5CH1_CAPTURE_STA 里面对溢出次数进行计数,当最大溢出次数来到的时候,就强制标记捕获完成(虽然此时还没有捕获到下降沿)。当下降沿到来的时候,先设置TIM5CH1_CAPTURE_STA 的第 7 位为1,标记成功捕获一次高电平,然后读取此时的定时器值到TIM5CH1_CAPTURE_VAL里面,最后设置为上升沿捕获,回到初始状态。

  这样,我们就完成一次高电平捕获了,只要TIM5CH1_CAPTURE_STA的第7位一直为1,那么就不会进行第二次捕获,我们在main函数处理完捕获数据后,将TIM5CH1_CAPTURE_STA置零,就可以开启第二次捕获。

  timer.h头文件内容比较简单,主要是函数申明,这里我们不做过多讲解。   

接下来,我们看看main函数内容

extern u8  TIM5CH1_CAPTURE_STA;    //输入捕获状态               

extern u32  TIM5CH1_CAPTURE_VAL;  //输入捕获值   

int main(void)

{  

  long long temp=0;   

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2

  delay_init(168);  //初始化延时函数

  uart_init(115200);//初始化串口波特率为115200

    TIM14_PWM_Init(500-1,84-1);  

//84M/84=1Mhz的计数频率计数到500,频率为1M/500=2Khz      

    TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1);//以 84M/84=1Mhz的频率计数  

      while(1)

  {    delay_ms(10);

    TIM_SetCompare1(TIM14,TIM_GetCapture1(TIM14)+1);  

    if(TIM_GetCapture1(TIM14)==300)TIM_SetCompare1(TIM14,0);        

      if(TIM5CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平

    {

      temp=TIM5CH1_CAPTURE_STA&0X3F;  

      temp*=0XFFFFFFFF;          //溢出时间总和

      temp+=TIM5CH1_CAPTURE_VAL;    //得到总的高电平时间

      printf("HIGH:%lld us\r\n",temp);//打印总的高点平时间

      TIM5CH1_CAPTURE_STA=0;      //开启下一次捕获

    }

  }

}

该 main 函数是在 PWM 实验的基础上修改来的,我们保留了 PWM 输出,同时通过设置TIM5_Cap_Init(0XFFFFFFFF,84-1),将 TIM5_CH1 的捕获计数器设计为 1us 计数一次,并设置重装载值为最大以达到不让定时器溢出的作用(溢出时间为 232-1 us),所以我们的捕获时间精度为 1us。主函数通过 TIM5CH1_CAPTURE_STA 的第 7 位,来判断有没有成功捕获到一次高电平,如果成功捕获,则将高电平时间通过串口输出到电脑。至此,我们的软件设计就完成了。


推荐阅读

史海拾趣

Dover Corporation公司的发展小趣事

Dover Corporation的电梯业务始于1955年,当时Dover Elevator从Rotary Lift中分离出来,成为一家独立运营的公司。此后,公司通过一系列的收购,如谢泼德华纳电梯公司、Acme Elevator等,迅速扩大了其电梯业务。这些收购不仅使Dover成为美国第三大电梯公司,也为其在电梯行业中的持续领先地位奠定了基础。

EREM公司的发展小趣事

近年来,随着科技的快速发展和电子行业的变革,EREM公司也面临着巨大的挑战。为了应对这些变革,EREM积极调整战略方向,加大研发投入,推出了一系列符合市场需求的新产品。同时,EREM还注重人才培养和团队建设,打造了一支高效、专业的团队,为公司的发展提供了有力保障。

FDI [Future Designs , Inc.]公司的发展小趣事

在电子行业的早期,FDI(Future Designs, Inc.)还只是一家名不见经传的小公司。创始人李明,凭借其对电子技术的热爱和敏锐的商业洞察力,带领团队研发出了一款具有革命性的电子芯片。这款芯片不仅性能卓越,而且成本较低,迅速在市场上获得了认可。正是这款产品,为FDI公司赢得了第一桶金,也为公司后续的发展奠定了坚实的基础。

全鹏(CHAMPION)公司的发展小趣事

全鹏公司一直重视研发和创新。为了不断满足市场需求,公司投入大量资源用于新技术和新产品的研发。通过引进高素质、高学历的研发人员,建立先进的研发实验室和测试中心,全鹏公司在产品研发方面取得了显著成果。这些新技术和新产品的推出不仅提升了全鹏公司的市场竞争力,也为客户带来了更好的使用体验。

国芯佳品公司的发展小趣事

全鹏公司一直重视研发和创新。为了不断满足市场需求,公司投入大量资源用于新技术和新产品的研发。通过引进高素质、高学历的研发人员,建立先进的研发实验室和测试中心,全鹏公司在产品研发方面取得了显著成果。这些新技术和新产品的推出不仅提升了全鹏公司的市场竞争力,也为客户带来了更好的使用体验。

Fagor Electrónica公司的发展小趣事

如今,Fagor Electrónica已经成为电子和数字领域的领军企业之一。展望未来,公司将继续秉承创新驱动的发展理念,加大在人工智能、物联网等新兴领域的投入。同时,Fagor Electrónica还将积极参与全球市场竞争,拓展更广阔的市场空间。相信在不久的将来,Fagor Electrónica将会创造更加辉煌的业绩。

问答坊 | AI 解惑

PADS2007有中文版的吗

那位大哥能告诉我PADS2007有中文版的吗,那里有中文版的下载?…

查看全部问答>

步进程序(急需解决的疑问)

老师以上是我们这一组编写的与步进有关的程序,其中让两个步进电机同步的程序有问题。问题是:a电机正常转动,b电机只发出声音,但不转动。 老师,我是按你的方法写的,你帮我分析一下问题的所在。…

查看全部问答>

中兴通讯硬件一部巨作-信号完整性

中兴通讯硬件一部巨作-信号完整性 近年来,通讯技术、计算机技术的发展越来越快,高速数字电路在设计中的运用越来越多,数字接入设备的交换能力已从百兆、千兆发展到几十千兆。高速数字电路设计对信号完整性技术的需求越来越迫切。 在中、大规模 ...…

查看全部问答>

造型请教:有没有可以查询FPGA/CPLD芯片的价格查询网址?

现在在选型FPGA,要用到161个IO,编数组功能单元。 公司没有BGA焊接设备,只能焊引脚能看到的封装 打算用Virtex的,两个TQ144封装的(IO=2*98),或者一个PQ240的(IO=166) 不知道这几种贵不贵,考虑成本,想用几百元的! …

查看全部问答>

搞嵌入式需要哪些基础知识,请指教!!

小弟是计算机网络工程专业学生,和一个团队做了一年的单片机项目(主要是用凌阳61开发物品管理器),一年做下来发现有很多时候需要扎实的电路知识,而我对电路方面不太感兴趣也没什么基础,感觉现在基本上只能做单纯的软件开发(在项目里写了简单文件系统, ...…

查看全部问答>

RTC时钟问题

                                 手里有一块板子,用以前写好的程序(RTC做万年历),在其他板子(开发板、自己设计的电路板)上,时钟都能正常使用 ...…

查看全部问答>

有没有人玩辉光电子钟吗,来吧,上资料

有没有人玩辉光电子钟吗,来吧,上资料  …

查看全部问答>

lm3s5956的jtag如何设计

lm3s5956的jtag如何设计…

查看全部问答>

请教关于msp430f149的io中断

请教各位 想用msp430f149的io中断 硬件上是这样的 用非自锁开关 即按下去又弹起的开关两端分别接有中断功能的P1或P2口、GND;将IO初始化为高电平,按下开关,IO会有一个高电平到低电平的过程,形成下降沿,利用下降沿中断,进行开关的触发。初始化 ...…

查看全部问答>

技术不过关就焊背光,果然悲剧了

不知道有没大神把背光点亮了?我技术不行,没弄好,反而把焊盘弄掉了。。。 申请来的芯片,太小了。 本想涂点助焊剂,先把芯片粘住 焊完发现怎么都点不亮,以为没焊好,想拆下来,这一拆就连焊盘一起都下来了(焊盘拆得太恶心就不拍了)。。。 ...…

查看全部问答>