电子工程师技术服务社区
公告
登录
|
注册
首页
技术问答
厂商活动
正点原子
板卡试用
资源库
下载
文章
社区首页
问答
移植的一个超声波测距程序有问题
已解决
73482
个问题
已帮助
5993
位优秀工程师
移植的一个超声波测距程序有问题
Gwvfbukn
2018-10-06
浏览量:975
大概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_Timeba
seInitTypeDef TIM_Timeba
seStructure;
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_Timeba
seStructure.TIM_Period = arr; //设定计数器自动重装值 65535 400cm时高电平约为23.529ms
TIM_Timeba
seStructure.TIM_Prescaler =psc; //预分频器 72 - 1 时钟1Mhz
TIM_Timeba
seStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
TIM_Timeba
seStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式
TIM_Timeba
seInit(TIM4 &TIM_Timeba
seStructure); //根据TIM_Timeba
seInitStruct中指定的参数初始化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;//清除中断标志位
}
哪里有问题呢??。。。。。。
显示全部
关注问题
写回答
0
0
收起
我来回答
上传资料:
选择文件
文件大小不超过15M(格式支持:doc、ppt、xls、pdf、zip、rar、txt)
最佳答案
进阶小菜鸟
这个模块我原来也遇到过有问题,主要是电压的问题,首先不能用3.3v,其次你用5v,也得保证你这个5v是真的,意思就是有的板子上虽然标的5v,其实只有3v,测一下。
发布于
2018-10-11
举报
评论 0
1
0
其他答案
数量:
9
lichangle
应该是测量接收的时间超时了 会显示一个很大的数
发布于
2018-10-10
举报
评论 0
0
0
Gwvfbukn
太粗心了,是电源接错了,3.3v这个模块不能用,不过奇怪的是定时器依旧可以捕获高电平,并且数值达到明显是错误的。
发布于
2018-10-10
举报
评论 0
0
0
chen0000009
这种应该测一下电平的电压,看看是否匹配
发布于
2018-10-12
举报
评论 0
0
0
凉城小呆呆
这种要检查你的模块供电是不是正常还有对应的电压是不是正常
发布于
2018-10-27
举报
评论 0
0
0
yhj416606438
你直接用例程就完了,如果例程不行肯定硬件问题,先排除硬件
发布于
2018-10-29
举报
评论 0
0
0
Angel_YY
注意看模块的说明,5V模块使用3.3V时工作会异常,所以首先要确保供电电压正确。
发布于
2018-10-29
举报
评论 0
0
0
Harriet
你的模块的电平是不是程序的电平匹配,不然不能通信的
发布于
2018-10-30
举报
评论 0
0
0
drepa
既然数据不变那就说明程序肯定有问题,可以参考一下stm32使用定时器输入捕获采集hcsr04的程序,网上非常多。
发布于
2018-10-31
举报
评论 0
0
0
最帅的廖先生
注意供电,要用5V供电,用3.3V的话会出现异常
发布于
2018-11-06
举报
评论 0
0
0
相关问题
问题达人
换一批
文章
知识经验换现金
换一批
移植的一个超声波测距程序有问题
写回答
关注问题
×
我要举报该内容,理由是:
内容质量差:
内容太水、伸手党
垃圾广告信息:
广告、招聘、推广、测试内容等
偏离问答主题:
与技术无关、讨论类
与社区已有内容重复:
违规内容:
色情、暴力、血腥、敏感信息等
不友善内容:
人事攻击、挑衅辱骂、恶意行为
以上选项都不是: