STM32L152RE实现定时器控制中断代码及原理拓展实验(超声测距全部代码)

前两周一直在忙社团的事情,没有时间更新,好多小伙伴又着急答辩,所以我跑过来更新一下,由于我物理实验报告还没有写完,可能讲解比较粗糙,就烦劳大家多动动脑啦!

先说一下四通道输出的实验

其实书上的代码没有那么多坑,我后来发现是自己改了一些不用改的地方,才导致做起来那么麻烦的。书上例7-6只有两个地方需要改,一个是开启时钟的时候再加一个GPIOA,一个是TIM3的中断服务函数里需要在每个注释处加一个GPIO_ToggleBits相应的管脚。
第一页AHB处加GPIOA
第二页
第三页注释处加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是否连对。

由于鄙人时间有限,细节的疑问请大家认真思考,自力更生

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值