OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2225|回复: 8

关于PB3、PB4用作超声波定时器与中断和PB0、PB1用作pwm时超声波无法进入中断的问题

[复制链接]

3

主题

12

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2019-7-8
在线时间
7 小时
发表于 2019-11-11 22:18:00 | 显示全部楼层 |阅读模式
5金钱
做的平衡车,一开始没加超声波,是正常的。现在想要加上超声波,遇到问题。超声波用的PB3、4口,pwm用TIM3的3、4通道即PB0、1口,在不初始化pwm时超声波可以在oled上显示正确,加上pwm初始化后超声波只能显示300应该是只进了一次中继和定时器,pitch角显示正常。不加超声波小车可以正常运行。问一下是复用的问题吗?但是注释掉复用后超声波虽然感觉不太稳但是还是可以显示,加上pwm初始化就不行了。

超声波距离显示300

超声波距离显示300


pwm初始化代码
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1(先高后低)
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_Pulse = 0;                            //设置待装入捕获比较寄存器的脉冲值
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
        TIM_OC3Init(TIM3, &TIM_OCInitStructure);  //根据TIM_OCInitStruct中指定的参数初始化外设TIMx


        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式1(先高后低)
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_Pulse = 0;                            //设置待装入捕获比较寄存器的脉冲值
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
        TIM_OC4Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2


  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM1在CCR1上的预装载寄存器
  TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM1在CCR2上的预装载寄存器
                TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIMx在ARR上的预装载寄存器
        TIM_Cmd(TIM3, ENABLE);  //使能TIM1




超声波


          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO, ENABLE);//|RCC_APB2Periph_AFIO
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能

//    AFIO->MAPR&=0XF8FFFFF0; //开启PB34的引脚复用功能,保留串口1、2的引脚为默认引脚
//    AFIO->MAPR|=0XF4FFFFF3; //串口1、2无复用,这里因为把串口1\2也复用了,所以此时需要打开.


        GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,ENABLE);

   GPIO_InitStructure.GPIO_Pin = TRIG_PIN;                                         //PB1接TRIG
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                     //设为推挽输出模式
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;                
   GPIO_Init(GPIOB, &GPIO_InitStructure);                         //初始化外设GPIOB
         GPIO_ResetBits(GPIOB,TRIG_PIN);                                                 //PA0 下?

       
   GPIO_InitStructure.GPIO_Pin = ECHO_PIN;                                     //PB10接ECH0
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;                 //设为输入
   GPIO_Init(GPIOB,&GPIO_InitStructure);                                                 //初始化GPIOB
       
         TIM_DeInit(TIM3);
         TIM_TimeBaseStructure.TIM_Period =499; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值         计数到5000为500ms
         TIM_TimeBaseStructure.TIM_Prescaler =7199; //设置用来作为TIMx时钟频率除数的预分频值  10Khz的计数频率  
         TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割: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,ENABLE);//|TIM_IT_Trigger                               
   TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
   TIM_Cmd(TIM3, DISABLE);

   //GPIOB.3          中断线以及中断初始化配置 下降沿触发
          EXTI_ClearITPendingBit(EXTI_Line4);  //清除LINE3上的中断标志位
          GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource4);
          EXTI_InitStructure.EXTI_Line=EXTI_Line4;
          EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;//_Falling
          EXTI_InitStructure.EXTI_LineCmd = ENABLE;
          EXTI_Init(&EXTI_InitStructure);                  //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

          NVIC_InitStructure.NVIC_IRQChannel =TIM3_IRQn;                       
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;        //抢占优先级2,
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                                        //子优先级3
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
          NVIC_Init(&NVIC_InitStructure);
               
                NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;                       
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;        //抢占优先级2,
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;                                        //子优先级3
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
          NVIC_Init(&NVIC_InitStructure);



void TIM3_IRQHandler(void)   //TIM3中断
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
                {
                        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx的中断待处理位:TIM 中断源
//                        UltrasonicWave_StartMeasure( );
                        UltrasonicWave_Distance=300;
                        TIM_Cmd(TIM3, DISABLE);
                }
}




void EXTI4_IRQHandler(void)
{                                        
                                TIM_SetCounter(TIM3,0);                       
       TIM_Cmd(TIM3, ENABLE);                                   //开启时钟       
                         while(PBin(4)==1);
                        TIM_Cmd(TIM3, DISABLE);                                                //定时器3失能                               
                                 UltrasonicWave_Distance=TIM_GetCounter(TIM3)*1.7;                                                //计算距离&&UltrasonicWave_Distance<150               
        if(UltrasonicWave_Distance>350)
        {
                UltrasonicWave_Distance=350;
        }                       
        printf("distance:%f cm\r\n",UltrasonicWave_Distance);  
                                EXTI_ClearITPendingBit(EXTI_Line4);  //清除EXTI10线路挂起位               
//         TIM_Cmd(TIM3, ENABLE);
}



void UltrasonicWave_StartMeasure(void)
{       
//        TIM_Cmd(TIM3, DISABLE);                                               
  GPIO_SetBits(GPIOB,TRIG_PIN);                   //送>10US的高电平RIG_PORT,TRIG_PIN这两个在define中有说
  delay_us(15);                                      //延时20US
  GPIO_ResetBits(GPIOB,TRIG_PIN);               
//         TIM_Cmd(TIM3, ENABLE);                                   //开启时钟
}


超声波UltrasonicWave_StartMeasure函数是通过mpu6050的中断发出的,用过超级中断,能够定时进入触发超声波工作的函数
EXTI->PR=1<<5;                                           //===清除LINE5上的中断标志位   
                mpu_dmp_get_data(&pitch,&roll,&yaw);                                                                                 //===得到欧拉角(姿态角)的数据(角度)
                MPU_Get_Gyroscope(&gyrox,&gyroy,&gyroz);                                                                 //===得到陀螺仪数据(加速度)
//                Encoder_Left=-Read_Encoder(2);                           //===读取编码器的值,因为两个电机的旋转了180度的,所以对其中一个取反,保证输出极性一致
//                Encoder_Right=Read_Encoder(4);                           //===读取编码器的值
                UltrasonicWave_Voltage_Counter++;
                if(UltrasonicWave_Voltage_Counter==10)                                                                         //===100ms读取一次超声波的数据以及电压
                {
                       
                        UltrasonicWave_Voltage_Counter=0;       
                        UltrasonicWave_StartMeasure();                     
                }



中断优先级的话,usart是1、3,INT是0、0,定时器时1、0,中断是1、1.现在已经不知道具体是哪块的问题。是复用还是别的什么。

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-11-12 08:51:32 | 显示全部楼层
回复

使用道具 举报

3

主题

12

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2019-7-8
在线时间
7 小时
 楼主| 发表于 2019-11-12 13:28:00 | 显示全部楼层

是的,我将它释放了,是这个影响吗?单独超声波能用的,是只能换io口了吗?
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-11-12 15:10:07 | 显示全部楼层
王婷雯 发表于 2019-11-12 13:28
是的,我将它释放了,是这个影响吗?单独超声波能用的,是只能换io口了吗?

看你关jtag的代码注释掉了
回复

使用道具 举报

3

主题

12

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2019-7-8
在线时间
7 小时
 楼主| 发表于 2019-11-13 10:18:33 | 显示全部楼层
nashui_sx 发表于 2019-11-12 15:10
看你关jtag的代码注释掉了

嗯对,最后注释了,但是之前一直没有注释,后来才想是不是关了的原因,所以把它注释了,然后发现还是不行
回复

使用道具 举报

3

主题

12

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2019-7-8
在线时间
7 小时
 楼主| 发表于 2019-11-13 10:20:04 | 显示全部楼层
王婷雯 发表于 2019-11-13 10:18
嗯对,最后注释了,但是之前一直没有注释,后来才想是不是关了的原因,所以把它注释了,然后发现还是不行

我第一段有说到“后来注释了”这么一个意思,可能表达的不清楚
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-11-13 11:59:46 | 显示全部楼层
王婷雯 发表于 2019-11-13 10:20
我第一段有说到“后来注释了”这么一个意思,可能表达的不清楚

不能注释   B3  B4做普通io  需要开复用时钟--关jtag

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);    //1、打开复用时钟:
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);//2、关闭jtag 开启sw
回复

使用道具 举报

3

主题

12

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2019-7-8
在线时间
7 小时
 楼主| 发表于 2019-11-14 18:12:17 | 显示全部楼层
nashui_sx 发表于 2019-11-13 11:59
不能注释   B3  B4做普通io  需要开复用时钟--关jtag

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,EN ...

嗯,我就注释了这一次啦,然后复制了一下,问题不是这个,注释了也这样。我知道不能注释,问题是这不是我问的问题啊,我真的只是提了一下而已,你就当我没注释好了,问题一样,我一直是在没注释的时候改的,最后真的改不出来了,才注释了试一次发现还是不行然后就发帖问了。整个流程就是这样,忘了取消注释再发帖了
回复

使用道具 举报

51

主题

2166

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10653
金钱
10653
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-11-14 19:13:18 | 显示全部楼层
王婷雯 发表于 2019-11-14 18:12
嗯,我就注释了这一次啦,然后复制了一下,问题不是这个,注释了也这样。我知道不能注释,问题是这不是我 ...

http://www.openedv.com/forum.php?mod=viewthread&tid=301676&extra=你看看这个捕获做的超声波,试试
不行不上传你的工程,大家还能试试
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-26 02:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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