完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
定时器配置:
#include "timer.h" #include "led.h" #include "STM32f10x.h" //通用定时器中断初始化 //这里时钟选择为APB1的2倍,而APB1为36M //arr:自动重装值。 //psc:时钟预分频数 //这里使用的是定时器3 void Timerx_Init(u16 arr,u16 psc) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能 TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值 计数到5000为500ms TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值 10Khz的计数频率 TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上计数模式 TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位 TIM_ITConfig(TIM3,TIM_IT_Update |TIM_IT_Trigger,ENABLE); TIM_ARRPreloadConfig(TIM3,ENABLE); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占优先级0级 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //从优先级3级 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 // TIM_Cmd(TIM2, ENABLE); //使能TIMx外设 } void TIM3_IRQHandler(void) //TIM2中断 { if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源 { TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx的中断待处理位:TIM 中断源 } } 超声波模块配置: #include "UltrasonicWave.h" #include "usart.h" #include "delay.h" #define TRIG_PORT GPIOC //TRIG #define ECHO_PORT GPIOA //ECHO #define TRIG_PIN GPIO_Pin_8 //TRIG #define ECHO_PIN GPIO_Pin_7 //ECHO float UltrasonicWave_Distance; //计算出的距离 /* * 函数名:UltrasonicWave_Configuration * 描述 :超声波模块的初始化 * 输入 :无 * 输出 :无 */ void UltrasonicWave_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); //关闭jtag RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStructure.GPIO_Pin = TRIG_PIN; //PC8接TRIG GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设为推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(TRIG_PORT, &GPIO_InitStructure); //初始化外设GPIO GPIO_InitStructure.GPIO_Pin = ECHO_PIN; //PC7接ECH0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //设为输入 GPIO_Init(ECHO_PORT,&GPIO_InitStructure); //初始化GPIOA //GPIOC.7 中断线以及中断初始化配置 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource7); EXTI_InitStructure.EXTI_Line=EXTI_Line7; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器 NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //使能按键所在的外部中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级2 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //子优先级2 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道 NVIC_Init(&NVIC_InitStructure); //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器 } void EXTI9_5_IRQHandler(void) { delay_us(60); //延时10us if(EXTI_GetITStatus(EXTI_Line7) != RESET) { TIM_SetCounter(TIM3,0); TIM_Cmd(TIM3, ENABLE); //开启时钟 while(GPIO_ReadInputDataBit(ECHO_PORT,ECHO_PIN)); //等待低电平 TIM_Cmd(TIM3, DISABLE); //定时器2失能 delay_ms(60); UltrasonicWave_Distance=TIM_GetCounter(TIM3)*5*34/200.0; //计算距离&&UltrasonicWave_Distance<150 // TIM_Cmd(TIM3, DISABLE); if(UltrasonicWave_Distance>0) { printf("distance:%f cmtn",UltrasonicWave_Distance); } EXTI_ClearITPendingBit(EXTI_Line7); //清除EXTI7线路挂起位 } else while(EXTI_GetITStatus(EXTI_Line7) == RESET); } /* * 函数名:UltrasonicWave_StartMeasure * 描述 :开始测距,发送一个>10us的脉冲,然后测量返回的高电平时间 * 输入 :无 * 输出 :无 */ void UltrasonicWave_StartMeasure(void) { GPIO_SetBits(TRIG_PORT,TRIG_PIN); //送>10US的高电平RIG_PORT,TRIG_PIN这两个在define中有? delay_us(20); //延时20US GPIO_ResetBits(TRIG_PORT,TRIG_PIN); } 主函数: #include "stm32f10x.h" #include "led.h" #include "delay.h" #include "sys.h" #include "usart.h" #include "exti.h" #include "timer.h" #include "UltrasonicWave.h" int main(void) { // SystemInit(); delay_init(); //延时初始化 // NVIC_Configuration(); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3); uart_init(115200); //串口初始化 LED_Init(); //LED端口初始化 Timerx_Init(4999,7199); //10Khz的计数频率,计数到5000为500ms UltrasonicWave_Configuration(); //对超声波模块初始化 while(1) { UltrasonicWave_StartMeasure(); //开始测距,发送一个>10us的脉冲,然后测量返回的高电平时间 // LED0=!LED0; // delay_ms(1000); } |
|
相关推荐
13个回答
|
|
我也是在准备中,不是很清楚,只是感觉这发送一个脉冲波形,就想测出距离,是不是有问题?
IO/中断这个得自己检查了,我只是好奇,声波1ms走0.3米,你中断里面有做延时60ms,也就是至少障碍物要距离>1.8米才行,而1.8米的话,超声波探测会不会有问题?你可以根据这个检查一下你的测试环境,再看看代码里面是否与之匹配。 |
|
|
|
survive_79 发表于 2017-1-3 14:13 60ms的延时是采样周期,是防止回响信号的影响(网上看的),其实我有把60ms去掉试过,但没用,一直都是0.85,就是在串口显示的速度快点,这程序是在网上找的然后我改了下TIM,我用过普通IO写,用过输入捕获,但都失败了!!输入捕获的话会在11~21cm间跳,但我都没碰过模块,数值都会变,不知道怎么回事?已经调试3天了,要是你写出来了希望可以指点下 |
|
|
|
仔细看了一下你贴出来的代码,好像不全。Distance不知道咋算出来的,所以爱莫能助了。
按照我的理解,你应该是在发射的时候记录下一个时间a,然后等待接收中断后记录一个时间b,两者相减乘以声波速度再除以2,就是距离了。 可我并未看见你在发射的时候有任何记录时间的操作。不行就先用示波器排查有无问题吧。示波器的波形时差已经能够估算出距离了。 |
|
|
|
survive_79 发表于 2017-1-3 15:57 Distance是个公式,用了340m/s换成cm算了的,其实主要问题是打印出来数据不变,至于时间的话我用TIM计时了,公式中用了个函数就是读取TIM时间的函数,我在TIM输出为高时开启定时器,为低时关闭定时器,就是把这段时间给读取出来了,这就是算距离的公式吧! |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
我的是这样的,换了个模块就没事了,其它情况不理解,程序错误也会这样,可以用示波器观察下! |
|
|
|
代码看起来没有问题啊,但是计算距离的公式有点不明白,贴上我的试试看
/** ****************************************************************************** * @file Ultrasound.c * @author xjg * @version V1.0 * @date 2017-4-26 * @brief 超声波模块控制函数接口 ****************************************************************************** * @attention * * 实验平台:STM32F103CB * ****************************************************************************** */ #include "Ultrasound.h" extern u8 overcnt; float RespondTime = 0; float SubTimeCnt = 0,Distance = 0,Predistance = 0; u8 js; static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* 嵌套向量中断控制器组选择 */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* 配置USART为中断源 */ NVIC_InitStructure.NVIC_IRQChannel = ULTRISOUND_ECHO_EXTI_IRQ; /* 抢断优先级*/ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; /* 子优先级 */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; /* 使能中断 */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* 初始化配置NVIC */ NVIC_Init(&NVIC_InitStructure); } static void ULTRISOUND_TRIG_ECHO_GPIO_INIT(void) { /*定义一个GPIO_InitTypeDef类型的结构体*/ GPIO_InitTypeDef GPIO_InitStructure; /*开启LED相关的GPIO外设时钟*/ RCC_APB2PeriphClockCmd( ULTRISOUND_TRIG_GPIO_CLK|ULTRISOUND_ECHO_GPIO_CLK , ENABLE); /*设置引脚速率为50MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*设置引脚模式为推挽输出*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*选择要控制的GPIO引脚*/ GPIO_InitStructure.GPIO_Pin = ULTRISOUND_TRIG_GPIO_PIN; /*调用库函数,初始化TRIG*/ GPIO_Init(ULTRISOUND_TRIG_GPIO_PORT, &GPIO_InitStructure); /*设置引脚模式为浮空输入*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; /*选择要控制的GPIO引脚*/ GPIO_InitStructure.GPIO_Pin = ULTRISOUND_ECHO_GPIO_PIN; /*调用库函数,初始化ECHO*/ GPIO_Init(ULTRISOUND_ECHO_GPIO_PORT, &GPIO_InitStructure); GPIO_EXTILineConfig(ULTRISOUND_ECHO_EXTI_PORTSOURCE,ULTRISOUND_ECHO_EXTI_PINSOURCE); } static void ULTRISOUND_TECHO_EXTI_INIT(void) { // EXTI_InitTypeDef EXTI_InitSturct; // // RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO , ENABLE); // // EXTI_InitSturct.EXTI_Line = ULTRISOUND_ECHO_EXTI_Line; // // EXTI_InitSturct.EXTI_LineCmd = ENABLE; // // EXTI_InitSturct.EXTI_Mode = EXTI_Mode_Interrupt; // // EXTI_InitSturct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;//EXTI_Trigger_Rising_Falling; // // EXTI_Init(&EXTI_InitSturct); // // EXTI_ClearITPendingBit(ULTRISOUND_ECHO_EXTI_Line); // // // // GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitStructure.EXTI_Line = ULTRISOUND_ECHO_EXTI_LINE; /* EXTI为中断模式 */ EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; /* 上升沿中断 */ EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; /* 使能中断 */ EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); } static void ULTRISOUND_TIM_INIT() { //定义基本定时器,比较输出定时器结构体 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitSturct; //初始化定时器的时钟 RCC_APB1PeriphClockCmd(ULTRISOUND_TIM_CLK,ENABLE); TIM_DeInit(ULTRISOUND_TIM); //配置基本定时器 TIM_TimeBaseInitSturct.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitSturct.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitSturct.TIM_Period = 0xffff; TIM_TimeBaseInitSturct.TIM_Prescaler = 72-1; TIM_TimeBaseInit(ULTRISOUND_TIM,&TIM_TimeBaseInitSturct); TIM_SetCounter(ULTRISOUND_TIM,0); } void ULTRISOUND_INIT(void) { ULTRISOUND_TRIG_ECHO_GPIO_INIT(); ULTRISOUND_TECHO_EXTI_INIT(); NVIC_Configuration(); ULTRISOUND_TIM_INIT(); } void Get_Distance(void) { u16 subcnt; subcnt = TIM_GetCounter(ULTRISOUND_TIM); printf("subcnt=%dn",subcnt); TIM_SetCounter(ULTRISOUND_TIM,0); RespondTime = (overcnt*0xffff+subcnt)*0.000001; // RespondTime = SubTimeCnt*0.000001; Distance = (RespondTime*314)/2*100; if(js < 1) { Predistance = Distance; js++; return; } else { if(Predistance > Distance) { Distance = Predistance; } js = 0; } // Distance = subcnt/58; overcnt = 0; printf("Distance=%2.fn",Distance); // SubTimeCnt = 0; } void ULTRISOUND_ECHO_IRQHandler(void) { // if(EXTI_GetITStatus(ULTRISOUND_ECHO_EXTI_Line) == SET) // { // printf("rn*********ccccccccccccccc***********rn"); OSIntEnter(); if((ULTRISOUND_ECHO_GPIO_PORT->IDR & ULTRISOUND_ECHO_GPIO_PIN) == 0) { TIM_Cmd(ULTRISOUND_TIM,DISABLE); // printf("停止计数n"); // EHO_START_CNT_FLAG = 0; Get_Distance(); } else { TIM_Cmd(ULTRISOUND_TIM,ENABLE);//开始计数 // printf("开始计数n"); // EHO_START_CNT_FLAG = 1; } // } EXTI_ClearITPendingBit(ULTRISOUND_ECHO_EXTI_LINE); OSIntExit(); } void ULTRISOUND_TIM_IRQHandl(void) { OSIntEnter(); if(TIM_GetITStatus(ULTRISOUND_TIM,TIM_IT_Update)!=RESET) { TIM_ClearITPendingBit(ULTRISOUND_TIM,TIM_IT_Update); //清除中断标志 overcnt++; } OSIntExit(); } |
|
|
|
HENHAO
|
|
|
|
把VCC换成5v就好了
|
|
|
|
中断源错误了吧
|
|
|
|
是不是中断源
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
STM32配合可编程加密芯片SMEC88ST的防抄板加密方案设计
657 浏览 0 评论
2334 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
2137 浏览 3 评论
4767 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
2282 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-30 01:44 , Processed in 0.707758 second(s), Total 68, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号