/******************** (C) COPYRIGHT 2012 ELC ********************
* File Name : main.c
* Author : ELC@WHUT
* Version : V1.0
* Date : 2012-12-05
* Description : 超声波测距的STM32代码,采用HC-HR04模块,该模块Trig信号默认高电平(高阻态),但是还需要给10uS以上的高电平触发
* 有些HC-HR04模块需要高电平触发,将程序简单修改即可使用
* GPIOB_12作为触发管脚,GPIOA_12作为接收管脚
* 每隔一秒串口1打印一次距离长度
***************************************************************************/
/**********************************************************
淘宝资料:
1、本模块性能稳定,测度距离精确。能和国外的SRF05,SRF02等超声波测距模块相媲美。
模块高精度,盲区(2cm)超近,稳定的测距是此产品成功走向市场的有力根据!
2 主要技术参数:
1:使用电压:DC5V 2:静态电流:小于2mA
3:电平输出:高5V 4:电平输出:底0V
5:感应角度:不大于15度 6:探测距离:2cm-450cm
7:高精度:可达0.3cm 8.PCB板大小:4.5*2.0CM
接线方式,VCC、trig(控制端)、 echo(接收端)、 GND
本产品使用方法:一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出.
一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.
如此不断的周期测,就可以达到你移动测量的值了~~
模块工作原理:
(1)采用IO触发测距,给至少10us的高电平信号;
(2)模块自动发送8个40khz的方波,自动检测是否有信号返回;
(3)有信号返回,通过IO输出一高电平,高电平持续的时间就是超声波从发射到返回的时间.
测试距离=(高电平时间*声速(340M/S))/2;
***********************************************************/
/*所包含的头文件*/
#include "stm32f10x_lib.h"
#include "usart.h"
#include "delay.h"
#include "sys_config.h"
#include "EXTI.h"
#include <math.h> //Keil library
#define uchar unsigned char
#define uint unsigned int
unsigned char SFlag=0;
unsigned long Distance=0;
void Ultrasonic_GPIO_Conf(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure); //发射引脚初始化
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure); //接收引脚初始化
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE); // 改变指定管脚的映射 GPIO_Remap_SWJ_JTAGDisable ,JTAG-DP 禁用 + SW-DP 使能
}
void Timer_Configuration(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_DeInit(TIM1);
TIM_TimeBaseStructure.TIM_Period=2000; //ARR的值, 一次计时20ms 最大值为3.4米
TIM_TimeBaseStructure.TIM_Prescaler=719; //719+1=720
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; //采样分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
TIM1->DIER|=1<<0; //允许更新中断
TIM1->DIER|=1<<6; //允许触发中断
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
}
//定时器溢出中断服务程序
void TIM1_UP_IRQHandler(void)
{
if(TIM1->SR&0X0001)//溢出中断
{
Showstring("Out of distance! ");
GPIO_WriteBit(GPIOB, GPIO_Pin_12, (BitAction)1);
delay_us(20);//如果不加延时,系统不稳定
GPIO_WriteBit(GPIOB, GPIO_Pin_12, (BitAction)0);//低电平触发
TIM_SetCounter(TIM1,0);
TIM_Cmd(TIM1, ENABLE);
SFlag=0; //取消当前上升沿标志
}
TIM1->SR&=~(1<<0);//清除中断标志位
}
void Sys_Configuration(void)
{
RCC_Configuration();
NVIC_Configuration();
delay_init(72);
USART1_Configuration();
Ultrasonic_GPIO_Conf();
EXTI_Configuration();
Timer_Configuration();
}
unsigned long d=3400;
unsigned char i=0;
void EXTI15_10_IRQHandler(void) //当前是设置的电平变化就进入中断
{
if(EXTI_GetITStatus(EXTI_Line12) != RESET)
{
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12)==1) //接收到上升沿,开始计时
{
TIM_SetCounter(TIM1,0);
TIM_Cmd(TIM1, ENABLE);
SFlag=1; //表示经过了上升沿
}
else if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12)==0 && SFlag==1)
{
TIM_Cmd(TIM1, DISABLE);
Distance=(int)(((float)TIM_GetCounter(TIM1))*1.7); //如果测距是2.5m则需15ms
if(d>Distance) //只要最小值
d=Distance;
i++;
if(i==3) //测量三次,只要最小值
{
i=0;
Showstring("Distance:");
Show_u16(d);
Showstring("mm ");
delay_ms(300);
d=3400;
}
GPIO_WriteBit(GPIOB, GPIO_Pin_12, (BitAction)1);
delay_us(20);//如果不加延时,系统不稳定
GPIO_WriteBit(GPIOB, GPIO_Pin_12, (BitAction)0);//低电平触发
//TIM_SetCounter(TIM1,0);
//TIM_Cmd(TIM1, ENABLE);
SFlag=0;
}
EXTI_ClearITPendingBit(EXTI_Line12);
}
}
void init_Ultrasonic(void)
{
//delay_ms(100); //为超声波稳定争取时间
GPIO_WriteBit(GPIOB, GPIO_Pin_12, (BitAction)0);//先设置成低电平
delay_ms(100);//
GPIO_WriteBit(GPIOB, GPIO_Pin_12, (BitAction)1); //高电平触发
delay_us(20);//高电平至少10us
GPIO_WriteBit(GPIOB, GPIO_Pin_12, (BitAction)0);//降回低电平
TIM_SetCounter(TIM1,0);
TIM_Cmd(TIM1, ENABLE);
}
int main(void)
{
/*系统初始化*/
Sys_Configuration();
init_Ultrasonic();
while(1)
{
;
}
}
/******** (C) COPYRIGHT 2012 ELC **********END OF FILE**********/
#include <stm32f10x_lib.h>
#include "EXTI.h"
void EXTI_Configuration(void)
{
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable GPIOB clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Enable AFIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
/* Configure PB.09 pin as input floating */
/* Connect EXTI9 Line to PB.09 pin */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource12);
/* Configure EXTI9 line */
EXTI_InitStructure.EXTI_Line = EXTI_Line12;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger =EXTI_Trigger_Rising_Falling ;//EXTI_Trigger_Falling EXTI_Trigger_Rising_Falling
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* Enable and set EXTI9_5 Interrupt to the lowest priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQChannel;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//最高优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}