STM32_4:TIM

cs 复制代码
#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "buzzer.h"
#include "key.h"
#include "Relay.h"
#include "Shake.h"
#include "Exti.h"
#include "usart.h"
#include "stdio.h"
#include "Time.h"

void delay(uint16_t time)
{
	uint16_t i = 0;
	while(time --)
	{
		i = 12000;
		while(i --);
	}
}

int  main()
{
	led_init();
	Base_Time_Init();

   while(1)
	 {
		 
	 }
		 
   
}

void TIM2_IRQHandler(void)
{
		if(TIM_GetITStatus(TIM2,TIM_IT_Update) != RESET)
		{
			GPIO_ResetBits(GPIOA,GPIO_Pin_1);
			delay(1000);
			GPIO_SetBits(GPIOA,GPIO_Pin_1);
		}
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}

3.控制超声波测距步骤

  • 初始化超声波引脚和定时器时钟
  • 初始化引脚模式和定时器中断
  • 编写定时器中断函数测距

获取距离:

  1. Trig引脚输出高电平10us
  2. 定时器计算Trig引脚的高电平时间 高电平时间=中断次数+不足一次中断的次数
  3. 时间换算成距离
  4. 串口打印距离

time.h

cs 复制代码
#ifndef _TIME_H
#define _TIME_H

void Base_Time_Init(void);
void HC_SR04_Init(void);
void Open_Tim(void);
void Close_Tim(void);
int Get_Echo_Tim(void);
float Get_Length(void);

#endif

time.c

cs 复制代码
#include "Time.h"
#include "stm32f10x.h"

void delay_us(uint32_t us)
{
	us *= 8;
	while(us--);
}

void delay_ms(uint32_t ms)
{
	while(ms--)
	{
		delay_us(1000);
	}
}

int tim_count;

void Base_Time_Init(void)
{
	TIM_TimeBaseInitTypeDef Time_Initstructure;
	NVIC_InitTypeDef NVIC_Initstructure; 

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
	
	Time_Initstructure.TIM_ClockDivision = TIM_CKD_DIV1;
	Time_Initstructure.TIM_CounterMode = TIM_CounterMode_Up;
	Time_Initstructure.TIM_Period = 1000-1;
	Time_Initstructure.TIM_Prescaler = 72-1;
	Time_Initstructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2,&Time_Initstructure);
	TIM_Cmd(TIM2,DISABLE);
	
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	
	//NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	
	NVIC_Initstructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_Initstructure.NVIC_IRQChannelCmd = ENABLE; 
	NVIC_Initstructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_Initstructure.NVIC_IRQChannelSubPriority =0;
	NVIC_Init(&NVIC_Initstructure);
	
	
}

void HC_SR04_Init(void)
{
	
	GPIO_InitTypeDef GPIO_Initstructure; 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	
	//Trig B11
	GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Initstructure.GPIO_Pin = GPIO_Pin_11;
	GPIO_Initstructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOB,&GPIO_Initstructure);
	
	//Echo B10
	GPIO_Initstructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Initstructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_Init(GPIOB,&GPIO_Initstructure);
	
}

void Open_Tim()
{
	TIM_SetCounter(TIM2, 0);
	tim_count = 0;
	TIM_Cmd(TIM2,ENABLE);
	
}


void Close_Tim()
{
	TIM_Cmd(TIM2,DISABLE);
}

//获取定时器中断次数
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
	{
		tim_count++;
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
	
}

//获取总的高电平时间
int Get_Echo_Tim()
{
	uint16_t sum_tim;
	
	sum_tim = tim_count * 1000 ;
	sum_tim += TIM_GetCounter(TIM2);
	
	TIM_SetCounter(TIM2, 0);
	
	delay_ms(50);
	
	return sum_tim;
}



float Get_Length(void)
{
	uint16_t time = 0;
	float length;
	
	int i = 0;
	float sum = 0;
	
	while(i != 5)
	{
	
		//hc_sr04 work
		GPIO_SetBits(GPIOB,GPIO_Pin_11);
		delay_us(20);
		GPIO_ResetBits(GPIOB,GPIO_Pin_11);
		
		//定时器计算高电平时间
		while( GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_10) == 0); //等待echo引脚低电平到高电平的跳变
		Open_Tim();
		while( GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_10) == 1);
		Close_Tim();
		
		//时间换算距离
		time = Get_Echo_Tim();
		length = ((float)time/58.0)  ;
		
		sum  += length;
		i++;
	}
	
	length = sum/5.0;
	
	return length;
	
}

注:

1.1ms = 1000us = 1000 000ns

2.高电平时间=中断次数+不足一次中断的次数

  1. 中断次数用定时器中断函数来计算
  2. 不足一次中断的次数,用CNT计数器中记得次数

所以这里,设置预分频系数为72hz,自动重装载寄存器设为1000,此时定时器每1ms触发一事件,即计数器每计1000个数为1ms,每记一个数为1us

3.获取总的定时器时间完之后,要把CNT计数器清0

而且要延时等待50ms,寄存器写入是需要时间的,在连续测量之间添加间隔

这样既能保证模块正常工作,又能提高代码效率和可读性

4.打开定时器的时候,最好把CNT计数器和全局变量都清0

5.length = ((float)time/58.0) ;

6.最后取五次的平均值

mian

cs 复制代码
#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "buzzer.h"
#include "key.h"
#include "Relay.h"
#include "Shake.h"
#include "Exti.h"
#include "usart.h"
#include "stdio.h"
#include "Time.h"

void delay(uint16_t time)
{
	uint16_t i = 0;
	while(time --)
	{
		i = 12000;
		while(i --);
	}
}

int  main()
{
	float length;
	
	led_init();
	my_usart_init();
	Base_Time_Init();
	HC_SR04_Init();

   while(1)
	 {
		 length =  Get_Length();
		 printf("%lf\r\n",length);
	 }
		 
   
}
相关推荐
会编程是什么感觉...2 小时前
单片机 - STM32HAL库常用API
stm32·单片机
小叶子来了啊2 小时前
7Arduino 结构体
单片机·嵌入式硬件
云山工作室13 小时前
基于单片机的智能电表
单片机·毕业设计·毕设
不怕犯错,就怕不做14 小时前
RK3562 +RK817的dts布尔属性解析(uboot基础知识)
linux·驱动开发·嵌入式硬件
逐梦之程14 小时前
STM32的串口通讯--DMA接收和CPU接收不定长数据帧对比
stm32·单片机·嵌入式硬件
文弱书生65615 小时前
2-electronbot主控免驱工程结构
linux·单片机·嵌入式硬件
求知喻15 小时前
LCD真值表
单片机·嵌入式硬件
csg110716 小时前
高效驱动,灵活控制:深度解析RZ7899大电流DC双向马达驱动芯片及其创新应用
单片机·嵌入式硬件·物联网
心疼你的一切16 小时前
三菱FX5U PLC与C#通信开发指南
开发语言·单片机·c#