找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1237|回复: 1
打印 上一主题 下一主题
收起左侧

stm32驱动多个超声波程序 无法正常运行

[复制链接]
跳转到指定楼层
楼主
ID:927434 发表于 2021-12-23 16:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天做作品 单个的超声波模块解决了 但是当多个 修改代码后 编译没有问题 缺无法正常运行 不知道问题出在哪里 有大佬解答下吗?
可运行的csb0.c
#include "csb0.h"
#include "stm32f10x.h"
#include "delay.h"

/*记录定时器溢出次数*/
unsigned int overcount1 = 0;


/**
* Function       bsp_getUltrasonicDistance
* @brief         获取超声距离
* @param[in]     void
* @param[out]    void
* @return        距离浮点值
* @par History   无
*/

void Ultrasonic_GPIO_Init(void)
{

        /*定义一个GPIO_InitTypeDef类型的结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;
        /*开启外设时钟*/
        RCC_APB2PeriphClockCmd(TRIG_RCC0, ENABLE);
        //GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);  //禁能jtag
        /*TRIG触发信号*/                                                                                                                  
          GPIO_InitStructure.GPIO_Pin = TRIG_PIN0;        
        /*设置引脚模式为通用推挽输出*/
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
        /*设置引脚速率为50MHz */   
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        /*调用库函数,初始化*/
          GPIO_Init(TRIG_PORT0, &GPIO_InitStructure);                 

        /*开启外设时钟*/
          RCC_APB2PeriphClockCmd(ECHO_RCC0, ENABLE);
        /*ECOH回响信号*/                                                                                                                           
          GPIO_InitStructure.GPIO_Pin = ECHO_PIN0;        
        /*设置引脚模式为通用推挽输出*/
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   
        /*调用库函数,初始化PORT*/
          GPIO_Init(ECHO_PORT0, &GPIO_InitStructure);               
}

/**
* Function       bsp_Ultrasonic_Timer2_Init
* @brief         初始化定时器TIM2
* @param[in]     void
* @param[out]    void
* @return        距离浮点值
* @par History   无
*/

void bsp_Ultrasonic_Timer2_Init(void)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructer;
        NVIC_InitTypeDef NVIC_InitStructer;


        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
        
        /*定时器TIM2初始化*/
        TIM_DeInit(TIM2);
        TIM_TimeBaseInitStructer.TIM_Period = 999;//定时周期为1000
        TIM_TimeBaseInitStructer.TIM_Prescaler = 71; //分频系数72
        TIM_TimeBaseInitStructer.TIM_ClockDivision = TIM_CKD_DIV1;//不分频
        TIM_TimeBaseInitStructer.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructer);
        
        TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);//开启更新中断
        
        NVIC_InitStructer.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructer.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructer.NVIC_IRQChannel = TIM2_IRQn;
        NVIC_InitStructer.NVIC_IRQChannelCmd = ENABLE;
        
        NVIC_Init(&NVIC_InitStructer);
        TIM_Cmd(TIM2, DISABLE);//关闭定时器使能 使接收到信号后再计时

}

void TIM2_IRQHandler(void) //中断,当回响信号很长是,计数值溢出后重复计数,用中断来保存溢出次数
{
        if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
        {
                TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除中断标志
                overcount1++;        //统计计数器的计时周期
        }
}



float bsp_getUltrasonicDistance(void)
{
        float length1 = 0, sum1 = 0;
        u16 tim;
        unsigned int  i = 0;

        /*测5次数据计算一次平均值*/
        while(i != 5)
        {
                GPIO_SetBits(TRIG_PORT0, TRIG_PIN0);  //拉高信号,作为触发信号
                delay_us(20);                                                  //高电平信号超过10us
                GPIO_ResetBits(TRIG_PORT0, TRIG_PIN0);
                /*等待回响信号*/
                while(GPIO_ReadInputDataBit(ECHO_PORT0, ECHO_PIN0) == 0);
                TIM_Cmd(TIM2,ENABLE);//回响信号到来,开启定时器计数               
                i+=1; //每收到一次回响信号+1,收到5次就计算均值
                while(GPIO_ReadInputDataBit(ECHO_PORT0, ECHO_PIN0) == 1);//回响信号消失
                TIM_Cmd(TIM2, DISABLE);//关闭定时器               
                tim = TIM_GetCounter(TIM2);//获取计TIM2数寄存器中的计数值,一边计算回响信号时间               
                length1 = (tim + overcount1 * 1000) / 58.0;//通过回响信号计算距离               
                sum1 = length1 + sum1;
                TIM2->CNT = 0;  //将TIM2计数寄存器的计数值清零
                overcount1 = 0;  //中断溢出次数清零
                delay_ms(1);
        }
        length1 = sum1 / 5;
        return length1;                //距离作为函数返回值
}
csb0.h

#define  __BSP_ULTRASONIC_H__
#define  __BSP_ULTRASONIC_H__

#define TRIG_RCC0  RCC_APB2Periph_GPIOB
#define ECHO_RCC0  RCC_APB2Periph_GPIOB
#define TRIG_PIN0  GPIO_Pin_6
#define ECHO_PIN0  GPIO_Pin_7
#define TRIG_PORT0  GPIOB
#define ECHO_PORT0  GPIOB


//#define HC_GPIO_PIN GPIO_Pin_7
//#define HC_PORT GPIOB


void Ultrasonic_GPIO_Init(void);

extern float bsp_getUltrasonicDistance(void);
extern void bsp_Ultrasonic_Timer2_Init(void);

修改后 无法使用的 (定时器 打算使用3)
csb1.c
#include "csb1.h"
#include "stm32f10x.h"
#include "delay.h"

/*记录定时器溢出次数*/
unsigned int overcount2 = 0;


/**
* Function       bsp_getUltrasonicDistance
* @brief         获取超声距离
* @param[in]     void
* @param[out]    void
* @return        距离浮点值
* @par History   无
*/

void Ultrasonic_GPIO_Init2(void)
{

        /*定义一个GPIO_InitTypeDef类型的结构体*/
        GPIO_InitTypeDef GPIO_InitStructure;
        /*开启外设时钟*/
        RCC_APB2PeriphClockCmd(TRIG_RCC1, ENABLE);
        //GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);  //禁能jtag
        /*TRIG触发信号*/                                                                                                                  
          GPIO_InitStructure.GPIO_Pin = TRIG_PIN1;        
        /*设置引脚模式为通用推挽输出*/
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
        /*设置引脚速率为50MHz */   
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        /*调用库函数,初始化*/
          GPIO_Init(TRIG_PORT1, &GPIO_InitStructure);                 

        /*开启外设时钟*/
          RCC_APB2PeriphClockCmd(ECHO_RCC1, ENABLE);
        /*ECOH回响信号*/                                                                                                                           
          GPIO_InitStructure.GPIO_Pin = ECHO_PIN1;        
        /*设置引脚模式为通用推挽输出*/
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;   
        /*调用库函数,初始化PORT*/
          GPIO_Init(ECHO_PORT1, &GPIO_InitStructure);               
}

/**
* Function       bsp_Ultrasonic_Timer3_Init
* @brief         初始化定时器TIM3
* @param[in]     void
* @param[out]    void
* @return        距离浮点值
* @par History   无
*/

void bsp_Ultrasonic_Timer3_Init(void)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructer;
        NVIC_InitTypeDef NVIC_InitStructer;


        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
        
        /*定时器TIM3初始化*/
        TIM_DeInit(TIM3);
        TIM_TimeBaseInitStructer.TIM_Period = 999;//定时周期为1000
        TIM_TimeBaseInitStructer.TIM_Prescaler = 71; //分频系数72
        TIM_TimeBaseInitStructer.TIM_ClockDivision = TIM_CKD_DIV1;//不分频
        TIM_TimeBaseInitStructer.TIM_CounterMode = TIM_CounterMode_Up;
        TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructer);
        
        TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);//开启更新中断
        
        NVIC_InitStructer.NVIC_IRQChannelPreemptionPriority = 1;
        NVIC_InitStructer.NVIC_IRQChannelSubPriority = 0;
        NVIC_InitStructer.NVIC_IRQChannel = TIM3_IRQn;
        NVIC_InitStructer.NVIC_IRQChannelCmd = ENABLE;
        
        NVIC_Init(&NVIC_InitStructer);
        TIM_Cmd(TIM3, DISABLE);//关闭定时器使能 使接收到信号后再计时

}

void TIM3_IRQHandler(void) //中断,当回响信号很长是,计数值溢出后重复计数,用中断来保存溢出次数
{
        if(TIM_GetITStatus(TIM3,TIM_IT_Update) != RESET)
        {
                TIM_ClearITPendingBit(TIM3, TIM_IT_Update);//清除中断标志
                overcount2++;        //统计计数器的计时周期
        }
}



float bsp_getUltrasonicDistance2(void)
{
        float length2 = 0, sum2 = 0;
        u16 tim;
        unsigned int  x = 0;

        /*测5次数据计算一次平均值*/
        while(x != 5)
        {
                GPIO_SetBits(TRIG_PORT1, TRIG_PIN1);  //拉高信号,作为触发信号
                delay_us(20);                                                  //高电平信号超过10us
                GPIO_ResetBits(TRIG_PORT1, TRIG_PIN1);
                /*等待回响信号*/
                while(GPIO_ReadInputDataBit(ECHO_PORT1, ECHO_PIN1) == 0);
                TIM_Cmd(TIM3,ENABLE);//回响信号到来,开启定时器计数               
                x+=1; //每收到一次回响信号+1,收到5次就计算均值
                while(GPIO_ReadInputDataBit(ECHO_PORT1, ECHO_PIN1) == 1);//回响信号消失
                TIM_Cmd(TIM3, DISABLE);//关闭定时器               
                tim = TIM_GetCounter(TIM3);//获取计TIM3数寄存器中的计数值,一边计算回响信号时间               
                length2 = (tim + overcount2 * 1000) / 58.0;//通过回响信号计算距离               
                sum2 = length2 + sum2;
                TIM3->CNT = 0;  //将TIM3计数寄存器的计数值清零
                overcount2 = 0;  //中断溢出次数清零
                delay_ms(1);
        }
        length2 = sum2 / 5;
        return length2;                //距离作为函数返回值
}
csb.h


#ifndef __BSP_ULTRASONIC_H__
#define __BSP_ULTRASONIC_H__        
#define TRIG_RCC1                RCC_APB2Periph_GPIOB
#define ECHO_RCC1                RCC_APB2Periph_GPIOB
#define TRIG_PIN1                GPIO_Pin_6
#define ECHO_PIN1                GPIO_Pin_7
#define TRIG_PORT1                GPIOB
#define ECHO_PORT1                GPIOB
void Ultrasonic_GPIO_Init(void);

extern float bsp_getUltrasonicDistance2(void);
extern void bsp_Ultrasonic_Timer3_Init(void);



#endif

当时为了分开调试 所以将端口定义的一样 求大佬 可以帮忙看出程序的错误
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:488334 发表于 2021-12-25 19:50 | 只看该作者
有没有考虑过循环开启超声波时,关闭其他的定时器?一个超声波对应一个定时器,当前超声波开启时,关闭其他定时器,只用当前超声波对应的定时器

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表