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);
	 }
		 
   
}
相关推荐
qq_411262429 分钟前
Ml307Udp: Failed to send data chunk
单片机·嵌入式硬件
smalming13 分钟前
模块-图形界面之屏幕
嵌入式硬件
小郭团队40 分钟前
1_4_五段式SVPWM (传统算法反正切+DPWM0)算法理论与 MATLAB 实现详解
嵌入式硬件·算法·硬件架构·dsp开发
XINVRY-FPGA1 小时前
XCZU47DR-2FFVE1156I XilinxFPGA Zynq UltraScale+ RFSoC
嵌入式硬件·fpga开发·云计算·硬件工程·射频工程·fpga
望云山1901 小时前
ESP32—S3学习--入门五个基础实验
嵌入式硬件·学习
wit_yuan1 小时前
openbmc 支持mctp over pcie(三)(支持作为endpoint)
linux·服务器·嵌入式硬件
小郭团队1 小时前
1_2_五段式SVPWM (传统算法反正切+DPWMmin)算法理论与 MATLAB 实现详解
开发语言·嵌入式硬件·matlab·dsp开发
小郭团队1 小时前
1_3_五段式SVPWM (传统算法反正切+DPWMmax)算法理论与 MATLAB 实现详解
开发语言·嵌入式硬件·matlab·dsp开发
2301_772204281 小时前
51单片机——UART
单片机·嵌入式硬件·51单片机
Zeku1 小时前
Linux应用与驱动开发:mmap和内存映射
stm32·freertos·linux驱动开发·linux应用开发