本人想通过定时器来捕获频率已知(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;//清空中断标志位
}
|