Gwvfbukn
获得 35 次赞
帮助过29人
大概50ms读取一次距离,但输出的值一直在1000上下浮动,明显是有问题的,代码如下:#include "distance.h"#include "delay.h"#include "stdio.h"/**************************************************************************函数功能:定时器4通道1输入捕获初始化入口参数:入口参数:arr:自动重装值 psc:时钟预分频数 返回 值:无pb0 控制端口检测 pb6 timer4 ch1 **************************************************************************/u8 TIM4CH1_CAPTURE_STA = 0; //通道1输入捕获标志,高两位做捕获标志,低6位做溢出标志 u16 TIM4CH1_CAPTURE_VAL; //记录捕获值/**************************************************************************函数功能:定时器4通道1输入捕获初始化入口参数:arr:自动重装值 psc:时钟预分频数 返回 值:无**************************************************************************/void TIM4_Cap_Init(u16 arru16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimebaseInitTypeDef TIM_TimebaseStructure; NVIC_InitTypeDef NVIC_InitStructure; TIM_ICInitTypeDef TIM_ICInitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 ENABLE); //使能TIM4时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB ENABLE); //使能GPIOB时钟 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PB0 输入 GPIO_Mode_IPD GPIO_Mode_IN_FLOATING GPIO_Init(GPIOB &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //PB0输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB &GPIO_InitStructure); TIM_TimebaseStructure.TIM_Period = arr; //设定计数器自动重装值 65535 400cm时高电平约为23.529ms TIM_TimebaseStructure.TIM_Prescaler =psc; //预分频器 72 - 1 时钟1Mhz TIM_TimebaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimebaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimebaseInit(TIM4 &TIM_TimebaseStructure); //根据TIM_TimebaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ICInitStructure.TIM_Channel = TIM_Channel_1; 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 = 0x00;//配置输入滤波器 不滤波 TIM_ICInit(TIM4 &TIM_ICInitStructure); NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM4中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //先占优先级2级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //从优先级0级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 TIM_ITConfig(TIM4TIM_IT_Update|TIM_IT_CC1ENABLE);//允许更新中断 允许CC1IE捕获中断 TIM_Cmd(TIM4ENABLE ); //使能定时器4 }/**************************************************************************函数功能:超声波接收回波函数入口参数:无返回 值:无**************************************************************************/void Read_Distane(void){ PBout(0)=1; delay_us(15); PBout(0)=0; if(TIM4CH1_CAPTURE_STA&0X80)//成功捕获到了一次高电平 { Distance=TIM4CH1_CAPTURE_STA&0X3F; Distance*=65536; //溢出时间总和 Distance+=TIM4CH1_CAPTURE_VAL; //得到总的高电平时间 Distance=Distance*170/1000; //单位转换为mm TIM4CH1_CAPTURE_STA=0; //开启下一次捕获 } }/**************************************************************************函数功能:超声波回波脉宽读取中断入口参数:无返回 值:无**************************************************************************/void TIM4_IRQHandler(void){ u16 tsr; tsr=TIM4->SR; //状态寄存器 if((TIM4CH1_CAPTURE_STA&0X80)==0)//还未成功捕获 { if(tsr&0X01)//溢出 即更新 { if(TIM4CH1_CAPTURE_STA&0X40)//已经捕获到高电平了 { if((TIM4CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了 { TIM4CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次 TIM4CH1_CAPTURE_VAL=0XFFFF; } else TIM4CH1_CAPTURE_STA++; } } if(tsr&0x02)//捕获1发生捕获事件 0000 0010 { if(TIM4CH1_CAPTURE_STA&0X40) //捕获到一个下降沿 0100 0000 { TIM4CH1_CAPTURE_STA|=0X80; //标记成功捕获到一次高电平脉宽 1100 0000 TIM4CH1_CAPTURE_VAL=TIM4->CCR1; //获取当前的捕获值. TIM4->CCER&=~(1<<1); //CC1P=0 设置为上升沿捕获 } else //还未开始第一次捕获上升沿 TIM4CH1_CAPTURE_STA初始为0000 0000 { TIM4CH1_CAPTURE_STA=0; //清空 TIM4CH1_CAPTURE_VAL=0; TIM4CH1_CAPTURE_STA|=0X40; //标记捕获到了上升沿 TIM4->CNT=0; //计数器清空 TIM4->CCER|=1<<1; //设置为下降沿捕获 } } } TIM4->SR=0;//清除中断标志位 }哪里有问题呢??。。。。。。
电源三节18650,控制的两个12v1.2a42步进电机,a4988驱动;电机转速很慢时单片机正常;速度稍微一快,程序就卡死了;主循环液晶显示数据卡死不动,过几秒又有反应,循环卡死;单片机和电机同电源共地;是硬件问题吗?这个怎么处理??
通用定时器比较输出翻转模式怎么输出脉宽为0,到达最大周期65535后就是最小频率了吗?或者怎么配置让该端口暂停脉冲输出,稳定为低电平,然后等待下次配置比较值后再输出脉冲