新手入门
- 积分
- 18
- 金钱
- 18
- 注册时间
- 2019-7-8
- 在线时间
- 7 小时
|
5金钱
做的平衡车,一开始没加超声波,是正常的。现在想要加上超声波,遇到问题。超声波用的PB3、4口,pwm用TIM3的3、4通道即PB0、1口,在不初始化pwm时超声波可以在oled上显示正确,加上pwm初始化后超声波只能显示300应该是只进了一次中继和定时器,pitch角显示正常。不加超声波小车可以正常运行。问一下是复用的问题吗?但是注释掉复用后超声波虽然感觉不太稳但是还是可以显示,加上pwm初始化就不行了。
超声波距离显示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.现在已经不知道具体是哪块的问题。是复用还是别的什么。
|
|