OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9966|回复: 1

输入捕获求助

[复制链接]

7

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
76
金钱
76
注册时间
2012-9-18
在线时间
0 小时
发表于 2012-11-16 17:20:09 | 显示全部楼层 |阅读模式

本人想通过定时器来捕获频率已知(50hz)的pwm波形的脉宽,参照《STM32开发指南》上面的输入捕获例程写了如下代码,可是当我给IC1通道也就是PB6输入一个50HZ占空比为50%的波形式,答应出来的时间却是一致在变化,我计数是1US记忆次数,按理说打印出来的数应该是恒定不变的(10000us)呀,大家看看这代码有什么问题不?问题补充一下,原子哥的《SYM32开发指南》输入捕获是用的TIM5的CHI通道来捕获按键给的高电平的时间。
#include "buhuo.h"
#include "sys.h"
#include "usart.h"
#include "stdio.h"
#include "delay.h"
#include "pwm.h"
extern u16 IC1Value;//ch1通道脉宽测量值
extern u16 IC2Value;//ch2通道脉宽测量值
extern u16 IC3Value;//ch3通道脉宽测量值
extern u16 IC4Value;//ch4通道脉宽测量值
extern u8 IC1Sta;//IC1输入捕获状态
extern u8 IC2Sta;//IC2输入捕获状态
extern u8 IC3Sta;//IC3输入捕获状态
extern u8 IC4Sta;//IC4输入捕获状态
int main(void)

    u32 temp1=0;
 u32 temp2=0;
 u32 temp3=0;
 u32 temp4=0;
 Stm32_Clock_Init(9); //系统时钟设置
 delay_init(72);      //延时初始化
 uart_init(72,9600);  //串口初始化
 WM_Init(10000,143,5000,8000,7500,500);  
   Capture_Init(0xffff,71);
 while(1)
    {
       delay_ms(10);
    if((IC1Sta&0x80)|(IC2Sta&0x80)|(IC3Sta&0x80)|(IC4Sta&0x80))//各通道成功捕获到一次高电平
       {
      temp1=IC1Sta&0x3F;
      temp1*=65535;//溢出时间中和
      temp1+=IC1Value;//得到CC1通道总的高电平时间
      //temp1=IC1Value;//得到CC1通道总的高电平时间
      printf("IC1Value:%d us\r\n",temp1);//打印总的高电平时间
      IC1Sta=0;//开启下一次捕获
      temp2=IC1Sta&0x3F;
      temp2*=65535;//溢出时间中和
      temp2+=IC2Value;//得到CC2通道总的高电平时间
      //temp2=IC2Value;//得到CC1通道总的高电平时间
      printf("IC2Value:%d us\r\n",temp2);//打印总的高电平时间
      IC2Sta=0;//开启下一次捕获
      temp3=IC1Sta&0x3F;
      temp3*=65535;//溢出时间中和
      temp3+=IC3Value;//得到CC3通道总的高电平时间
      printf("IC3Value:%d us\r\n",temp3);//打印总的高电平时间
      IC3Sta=0;//开启下一次捕获
      temp4=IC4Sta&0x3F;
      temp4*=65535;//溢出时间中和
      temp4+=IC4Value;//得到CC1通道总的高电平时间
      printf("IC4Value:%d us\r\n",temp4);//打印总的高电平时间
      IC4Sta=0;//开启下一次捕获

    }
    }

#include <stm32f10x_lib.h>
#include "sys.h"
#include "usart.h"  
#include "delay.h"
#include "buhuo.h" 
u16 IC1Value;//ch1通道脉宽测量值
u16 IC2Value;//ch2通道脉宽测量值
u16 IC3Value;//ch3通道脉宽测量值
u16 IC4Value;//ch4通道脉宽测量值
u8 IC1Sta=0;//IC1输入捕获状态
u8 IC2Sta=0;//IC2输入捕获状态
u8 IC3Sta=0;//IC3输入捕获状态
u8 IC4Sta=0;//IC4输入捕获状态

//********************************************************************************************
//* 输入捕获初始化函数
//* 传入参数: arr 输入计数器的最大值,psc 输入每计一个数的时间为(系统时钟/(psc+1))
//* 返回值: 无
void SystemInit (void){}
void Capture_Init(u16 arr,u16 psc)
{
   //RCC->APB2ENR|=1<<0; //辅助时钟使能
   RCC->APB2ENR|=1<<3; //PB时钟使能
   RCC->APB1ENR|=1<<2; //TIM4时钟使能
   TIM4->ARR=arr;      //设定计数器自动装载值
   TIM4->SC=psc;      //预分频器
   GPIOB->CRL&=0X00FFFFFF;
   GPIOB->CRL|=0X88000000;
   GPIOB->CRH&=0XFFFFFF00;
   GPIOB->CRH|=0X00000088;//设置PB6\7\8\9输入
   GPIOB->ODR&=~(15<<6); //设置PB6\7\8\9下拉
   TIM4->CCMR1|=1<<0; //CC1通道设置为输入模式映射到TI1
   TIM4->CCMR1|=1<<8;//CC2通道设置为输入模式映射到TI2
   TIM4->CCMR2|=1<<0;//CC3通道设置为输入模式映射到TI3
   TIM4->CCMR2|=1<<8;//CC4通道设置为输入模式映射到TI4
   TIM4->CCMR1|=0<<4;//配置CC1滤波器|不滤波
   TIM4->CCMR1|=0<<12;//配置CC2滤波器。。。
   TIM4->CCMR2|=0<<4;//配置CC3滤波器。。。
   TIM4->CCMR2|=0<<12;//配置CC4滤波器。。。
   TIM4->CCER|=0<<1;//捕获发生在CC1的上升沿
   TIM4->CCER|=0<<5;//捕获发生在CC2的上升沿
   TIM4->CCER|=0<<9;//捕获发生在CC3的上升沿
   TIM4->CCER|=0<<13;//捕获发生在CC4的上升沿
   TIM4->CCMR1|=0<<2;//CC1通道不分频
   TIM4->CCMR1|=0<<10;//CC2通道不分频
   TIM4->CCMR2|=0<<2;//CC3通道不分频
   TIM4->CCMR2|=0<<10;//CC4通道不分频
  

   TIM4->CCER|=1<<0;//允许1通道捕获计数器的值到捕获寄存器
   TIM4->CCER|=1<<4;//允许2通道捕获计数器的值到捕获寄存器
   TIM4->CCER|=1<<8;//允许3通道捕获计数器的值到捕获寄存器
   TIM4->CCER|=1<<12;//允许4通道捕获计数器的值到捕获寄存器
   TIM4->DIER|=1<<1;//允许1通道捕获中断
   TIM4->DIER|=1<<2;//允许2通道捕获中断
   TIM4->DIER|=1<<3;//允许3通道捕获中断
   TIM4->DIER|=1<<4;//允许4通道捕获中断
   TIM4->DIER|=1<<0;//允许更新中断
   TIM4->CR1|=0x01;//使能定时器4
   MY_NVIC_Init(2,3,TIM4_IRQChannel,2);
}
//********************************************************************************************
//* 输入捕获中断函数
//* 传入参数: 无
//* 返回值: 无

void TIM4_IRQHandler(void)
{
   u16 tsr;
   tsr=TIM4->SR;
   if((IC1Sta&0x80)|(IC2Sta&0x80)|(IC3Sta&0x80)|(IC4Sta&0x80)==0)//还未成功捕获
      {
    if(tsr&0x01)//溢出
     {
        if((IC1Sta&0x40)|(IC2Sta&0x40)|(IC3Sta&0x40)|(IC4Sta&0x40))//已经捕获到高电平
         {
         if(((IC1Sta&0x3F)|(IC2Sta&0x3F)|(IC3Sta&0x3F)|(IC4Sta&0x3F))==0x3F)//高电平太长
         {
         IC1Sta|=0x80;//标记成功捕获一次
         IC1Value=0xFFFF;
         IC2Sta|=0x80;//标记成功捕获一次
         IC2Value=0xFFFF;
         IC3Sta|=0x80;//标记成功捕获一次
         IC3Value=0xFFFF;
         IC4Sta|=0x80;//标记成功捕获一次
         IC4Value=0xFFFF;
      }
       else
           {
         IC1Sta++;
         IC2Sta++;
         IC3Sta++;
         IC4Sta++;
        }
      }
     }
   if(tsr&0x1E)//IC1;IC2;IC3;IC4发生捕获事件
      {
     if((IC1Sta&0x40)|(IC2Sta&0x40)|(IC3Sta&0x40)|(IC4Sta&0x40))//捕获到一个下降沿
        {
             IC1Sta|=0x80;//标记成功捕获到一次高电平脉宽
         IC1Value=TIM4->CCR1;//获取当前的捕获值
         IC2Sta|=0x80;//标记成功捕获到一次高电平脉宽
         IC2Value=TIM4->CCR2;//获取当前的捕获值
         IC3Sta|=0x80;//标记成功捕获到一次高电平脉宽
         IC3Value=TIM4->CCR3;//获取当前的捕获值
         IC4Sta|=0x80;//标记成功捕获到一次高电平脉宽
         IC4Value=TIM4->CCR4;//获取当前的捕获值
                           TIM4->CCER|=0<<1;//CC1P=0设置为上升沿捕获
         TIM4->CCER|=0<<5;//CC2P=0设置为上升沿捕获
         TIM4->CCER|=0<<9;//CC3P=0设置为上升沿捕获
         TIM4->CCER|=0<<13;//CC4P=0设置为上升沿捕获
     }
      else//还未开始,第一次捕获上升沿
        {
               IC1Sta=0;   //清空
         IC1Value=0;
         IC2Sta=0;   //清空
         IC2Value=0;
         IC3Sta=0;   //清空
         IC3Value=0;
         IC4Sta=0;   //清空
         IC4Value=0;
         IC1Sta|=0x40;//标记捕获到上升沿
         IC2Sta|=0x40;//标记捕获到上升沿
         IC3Sta|=0x40;//标记捕获到上升沿
         IC4Sta|=0x40;//标记捕获到上升沿
         TIM4->CNT=0;   //计数器清空
         TIM4->CCER|=(1<<1);//CC1P=1设置为下升沿捕获
         TIM4->CCER|=(1<<5);//CC2P=1设置为下升沿捕获
         TIM4->CCER|=(1<<9);//CC3P=1设置为下升沿捕获
         TIM4->CCER|=(1<<13);//CC4P=1设置为下升沿捕获
     }
   }

   }
 TIM4->SR=0;//清空中断标志位
  
  
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2012-11-16 20:38:18 | 显示全部楼层
你这一下就4个通道,先一个通道调通,再2个通道,慢慢增加.
一下子来四个通道,不好处理.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-7-18 22:19

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表