前两周一直在忙社团的事情,没有时间更新,好多小伙伴又着急答辩,所以我跑过来更新一下,由于我物理实验报告还没有写完,可能讲解比较粗糙,就烦劳大家多动动脑啦!
先说一下四通道输出的实验
其实书上的代码没有那么多坑,我后来发现是自己改了一些不用改的地方,才导致做起来那么麻烦的。书上例7-6只有两个地方需要改,一个是开启时钟的时候再加一个GPIOA,一个是TIM3的中断服务函数里需要在每个注释处加一个GPIO_ToggleBits相应的管脚。
然后只需要在电路板上用杜邦线把相应的管脚和灯的管脚连起来就行,不用跳线帽。
“万恶”的拓展实验
老师给的代码里好多好多好多坑,不赘述了,直接上代码
1.头文件
#include "stm32l1xx_gpio.h"
#include "stm32l1xx_rcc.h"
#include "stm32l1xx.h"
#include "stm32l1xx_tim.h"
#include "misc.h"
#include "core_cm3.h"
2.三个全局变量和delay_us()
uint8_t TIM2CH1_CAPTURE_STA;
uint32_t TIM2CH1_CAPTURE_VAL;
int d=0;
void delay_us(uint32_t n)
{
d=0;
SysTick_Config(320*n);
while(1)
{
if(d==1)
break;
}
}
3.初始化TIM2
void Ultrasonic_TIM2_Init(uint16_t arr, uint16_t psc)
{
TIM_ICInitTypeDef TIM_ICInitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInitStruct.TIM_Period = arr;
TIM_TimeBaseInitStruct.TIM_Prescaler = psc;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct);
TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
TIM_ICInitStruct.TIM_ICFilter = 0x00;
TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Rising;
TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInit(TIM2, &TIM_ICInitStruct);
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStruct.GPIO_PuPd =GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
GPIO_InitStruct.GPIO_OType=GPIO_OType_PP;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_PuPd =GPIO_PuPd_UP;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM2);
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStruct);
TIM_ITConfig(TIM2, TIM_IT_Update | TIM_IT_CC1, ENABLE);
TIM_Cmd(TIM2, ENABLE);
}
4.测算距离
uint16_t Ultrasonic_Value(uint16_t arr, uint16_t psc)
{
uint16_t value=0;
Ultrasonic_TIM2_Init(arr, psc);
GPIO_SetBits(GPIOA, GPIO_Pin_1);
delay_us(15);
GPIO_ResetBits(GPIOA, GPIO_Pin_1);
while(1)
{
if(TIM2CH1_CAPTURE_STA&0x80)
{
TIM2CH1_CAPTURE_STA&=0x3f;
value = (10.0)*(TIM2CH1_CAPTURE_STA * arr + TIM2CH1_CAPTURE_VAL) / 58;
TIM2CH1_CAPTURE_STA = 0;
break;
}
}
return value;
}
5.控制蜂鸣器
void Buzzer_Control(uint16_t frequency)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11, ENABLE);
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_TIM11);
TIM_TimeBaseStructure.TIM_Period = frequency-1;
TIM_TimeBaseStructure.TIM_Prescaler = 0;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM11, &TIM_TimeBaseStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = frequency/2;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM11, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM11, TIM_OCPreload_Enable);
TIM_ARRPreloadConfig(TIM11, ENABLE);
TIM_Cmd(TIM11, ENABLE);
}
6.蜂鸣器变频函数
void alerm(int i)
{
switch(i)
{
case 0:Buzzer_Control(200);break;
case 1:Buzzer_Control(1000);break;
case 2:Buzzer_Control(5000);break;
case 3:Buzzer_Control(20000);break;
default:break;
}
}
7.主函数
int main(void)
{
uint32_t distance;
while(1)
{
distance = Ultrasonic_Value(65535,0);
if(distance >30)
alerm(3);
else if (distance <5)
alerm(0);
else if(distance <10)
alerm(1);
else if(distance <20)
alerm(2);
}
}
8.stm32l1xx_it.c文件里的函数
打开stm32l1xx_it.c文件,把函数写在里面。
extern int d;
void SysTick_Handler(void)
{
if(d==0)
d=1;
}
extern uint8_t TIM2CH1_CAPTURE_STA;
extern uint32_t TIM2CH1_CAPTURE_VAL;
void TIM2_IRQHandler(void)
{
if((TIM2CH1_CAPTURE_STA & 0x80) == 0)
{
if(TIM_GetITStatus(TIM2, TIM_IT_Update) !=RESET)
{
if(TIM2CH1_CAPTURE_STA & 0x40)
{
if((TIM2CH1_CAPTURE_STA & 0x3f) == 0x3f)
{
TIM2CH1_CAPTURE_STA |= 0x80;
TIM2CH1_CAPTURE_VAL = 0x00;
}
else
TIM2CH1_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM2, TIM_IT_CC1) !=RESET)
{
if(TIM2CH1_CAPTURE_STA & 0x40)
{
TIM2CH1_CAPTURE_STA |= 0x80;
TIM2CH1_CAPTURE_VAL = TIM_GetCapture1(TIM2);
TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Rising);
}
else
{
TIM2CH1_CAPTURE_STA = 0;
TIM2CH1_CAPTURE_VAL = 0;
TIM2CH1_CAPTURE_STA |= 0x40;
TIM_SetCounter(TIM2, 0);
TIM_OC1PolarityConfig(TIM2, TIM_ICPolarity_Falling);
}
}
}
TIM_ClearITPendingBit(TIM2, TIM_IT_Update | TIM_IT_CC1);
}
以上代码就是完成超声测距的所有代码,亲测有效,如果完全按照我的代码写进去仍然不响的话,应该是板子连错地方了,请仔细检查超声测距模块的ECHO-PB0,TRIG-PB1,VCC-5V,GND-GND,是不是对应连好,以及蜂鸣器的VCC-3.3V,IO-PB9,GND-GND是否连对。
由于鄙人时间有限,细节的疑问请大家认真思考,自力更生