头文件:cs.h
#ifndef csb_h
#define csb_h
#include "sys.h"
void csb_init(u16 arr,u16 psc);
#endif
csb.c:
#include "csb.h"
#define TRIG PCout(3)
#define ECHO PAin(1)
void csb_init(u16 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitT;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitT;
TIM_ICInitTypeDef TIM_ICInitT;
NVIC_InitTypeDef NVIC_InitT;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE);
GPIO_InitT.GPIO_Mode =GPIO_Mode_Out_PP;
GPIO_InitT.GPIO_Pin =GPIO_Pin_3;
GPIO_InitT.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitT);
GPIO_ResetBits(GPIOC,GPIO_Pin_3);
GPIO_InitT.GPIO_Mode =GPIO_Mode_IN_FLOATING;
GPIO_InitT.GPIO_Pin =GPIO_Pin_1;
GPIO_Init(GPIOA,&GPIO_InitT);
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
TIM_TimeBaseInitT.TIM_ClockDivision =TIM_CKD_DIV1;
TIM_TimeBaseInitT.TIM_CounterMode =TIM_CounterMode_Up;
TIM_TimeBaseInitT.TIM_Period =arr;
TIM_TimeBaseInitT.TIM_Prescaler =psc;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitT);
TIM_ICInitT.TIM_Channel =TIM_Channel_2;
TIM_ICInitT.TIM_ICFilter =0X00;
TIM_ICInitT.TIM_ICPolarity =TIM_ICPolarity_Rising;
TIM_ICInitT.TIM_ICPrescaler =TIM_ICPSC_DIV1;
TIM_ICInitT.TIM_ICSelection =TIM_ICSelection_DirectTI;
TIM_ICInit(TIM5,&TIM_ICInitT);
NVIC_InitT.NVIC_IRQChannel =TIM5_IRQn;Ï
NVIC_InitT.NVIC_IRQChannelCmd =ENABLE;
NVIC_InitT.NVIC_IRQChannelPreemptionPriority =2;
NVIC_InitT.NVIC_IRQChannelSubPriority =0;
NVIC_Init(&NVIC_InitT);
TIM_ITConfig(TIM5,TIM_IT_Update | TIM_IT_CC2 ,ENABLE);
TIM_Cmd(TIM5,ENABLE);
}
u8 TIM_CH2_SR=0;
u16 TIM_VAL;
u16 TIM5_IRQHandler()
{
if((TIM_CH2_SR & 0x80)==0)
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update)!=RESET)
{
if(TIM_CH2_SR & 0x40)
{
if((TIM_VAL & 0x3f)==0x3f)
{
TIM_CH2_SR |=0x80;
TIM_VAL=0xffff;
}
else
{
TIM_CH2_SR++;
}
}
}
if(TIM_GetITStatus(TIM5,TIM_IT_CC2)!=RESET)
{
if(TIM_CH2_SR & 0x40)
{
TIM_CH2_SR|=0x80;
TIM_VAL=TIM_GetCapture2(TIM5);
TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Rising);
}
else
{
TIM_CH2_SR=0;
TIM_VAL=0;
TIM_CH2_SR|=0x40;
TIM_SetCounter(TIM5,0);
TIM_OC2PolarityConfig(TIM5,TIM_ICPolarity_Falling);
}
}
}
TIM_ClearITPendingBit(TIM5,TIM_IT_Update | TIM_IT_CC2);
}
主函数:
#include "csb.h"
#include "delay.h"
#include "usart.h"
extern u8 TIM_CH2_SR;
extern u16 TIM_VAL;
int main(void)
{
u16 time;
u8 i;
float sum=0;
float juli=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
delay_init();
uart_init(9600);
csb_init(65535,71);
while(1)
{
for(i=0;i<5;i++)
{
PCout(3)=1;
delay_us(25);
PCout(3)=0;
if(TIM_CH2_SR & 0x80)
{
time=TIM_CH2_SR &0x3f;
time=time*65535+TIM_VAL;
juli=((float)time/58.0);
sum=sum+juli;
delay_ms(60);
TIM_CH2_SR=0;
}
}
juli=sum/5.0;
printf("距离:%f cm\r\n",juli);
}
}
实验现象:即时我没有连接TRIG触发线,数值也是不断的向上增
实验现象:我复位后,不连接ECHO线,输出距离为0,这个正常可以理解,但是一旦接上ECHO不需要触发,数值就往上增
这个不需要定时器的捕获,只要检测接超声波回响信号的那个引脚高电平持续的时间就行了。你调试一下,看看程序卡在哪里了。如果非要使用捕获的,在你的while主循环里面加入if判断捕获事件是否发生,我看你的程序直接就计算了,没有的等待捕获中断的发生。
嗯,好的,中午回去就改下试试!我只是学了stm32,我就想用所学知识尽量去应用到所做的东西上!那么,我想问下,在实现的思路上有没有错呢?除了少了判断那个输入捕获
@Cherishkk: 思路上没有错误,就是给出一个20us 的高电平,然后开启输入捕获(先开启也可以),在捕获到一个上升沿后在中断里面记录数值并且把捕获模式改为下降沿捕获,然后再次捕获后记录数据。注意中断的溢出就行。一旦得到高电平的时间,后面就简单了。你可以先试着捕获到准确的高电平时间。在计算距离。
@Andrew_qian: 嗯,行的!谢谢
@Andrew_qian: 我修改了一下,但是结果还是错误的,出现的现象如上边所说,你抽空看下就好,打扰了这么长时间