NUCLEO-F411RE 是ST公司推出的一款针对STM32F4系列设计的Cortex-M4开发板,具有 mbed 功能,支持Arduino。同时还提供 ST Morpho 扩展排针,可连接微控制器的所有周边外设。
开发板基于STM32F411RET6设计,开发板还集成了ST-LINK/V2-1仿真下载器(但仅对外提供SWD接口),免除另外采购仿真器或下载器的麻烦。并且具备Arduino接口,可接入 Arduino 巨大生态系统的各种 Shield 扩展板,能够轻松快速增加特殊功能。
使用HC-SR04超声波模块,此模块性能稳定,测度距离精确,模块高精度,盲区小。主要的电气参数如下:
电气参数 HC-SR04超声波模块
工作电压 DC 5V
工作电流 15mA
工作频率 40Hz
最远射程 4m
最近射程 2cm
测量角度 15度
输入触发信号 10Us的TTL脉冲
输出回响信号 输出TTL电平信号,与射程成比例
规格尺寸 45*20*15mm
基本工作原理:
1、采用IO口TRIG触发测距,给至少10us的高电平信号;
2、模块自动发送8个40khz的方波,自动检测是否有信号返回;
3、有信号返回,通过IO口ECHO输出一个高电平,高电平持续的时间就是超声波从发射到返回的时间。测试距离=(高电平时间*声速(340M/S))/2;
本模块使用方法简单,一个控制口发一个10US以上的高电平,就可以在接收口等待高电平输出.一有输出就可以开定时器计时,当此口变为低电平时就可以读定时器的值,此时就为此次测距的时间,方可算出距离.如此不断的周期测,即可以得到你移动测量的值。超声波模块时序图如下:
输入捕获可以用来测量脉冲宽度或者测量频率。超声波用到的是测量脉宽,这里我以测量脉宽为例,用一个简图来说明输入捕获的原理,如下图:
如上图所示,就是输入捕获测量高电平脉宽的原理,假定定时器工作在向上计数模式,图中t1-t2时间,就是我们需要测量的高电平时间。测量方法如下:首先设置定时器通道x为上升沿捕获,这样,t1时刻就会捕捉到CNT值,然后立即清零CNT,并设置通道x为下降沿捕获,这样t2时刻又会发生捕获事件,得到此时的CNT值,记为CCRx2。这样,根据定时器的计数频率,我们就可以算出t1-t2的时间,从而得到高电平的脉宽。
在t1-t2之间,可能产生N次定时器溢出,这就要求我们对定时器溢出做处理,防止高电平太长,导致数据不准确。如上图所示,t1-t2之间CNT计数的的次数等于:N*ARR+CRRx2,有了这个计数次数,再乘以CNT的计数周期,即可得到t1-t2的时间长度,即高电平持续时间。
使用STM32CubeMX配置输入捕获功能初始化代码步骤如下:
进入Configuration->TIM2配置页,在弹出的界面中点击Parameter Settings选项卡,Counter Settings配置栏下面的四个选项就是用来配置定时器的预分频系数,自动装载值,计数模式以及时钟分频因子。在界面的Input Capture Channel 1配置栏配置输入捕获通道1的捕获极性,分频系数、映射、滤波器等参数,操作方法如下图:
配置完上面步骤后,生成代码。在生成的代码中,并没有使能相应中断的代码,也没有改写中断处理回调函数,这都需要我们自己来编写
tim.c文件新增的内容如下
/* USER CODE BEGIN 1 */
uint8_t TIM2CH1_CAPTURE_STA=0; //ÊäÈ벶»ñ״̬
uint32_t TIM2CH1_CAPTURE_VAL; //ÊäÈ벶»ñÖµ(TIM2/TIM5ÊÇ32λ)
//¶¨Ê±Æ÷¸üÐÂÖжϣ¨¼ÆÊýÒç³ö£©Öжϴ¦Àí»Øµ÷º¯Êý£¬ ¸Ãº¯ÊýÔÚHAL_TIM_IRQHandlerÖлᱻµ÷ÓÃ
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)//¸üÐÂÖжϣ¨Òç³ö£©·¢ÉúʱִÐÐ
{
if((TIM2CH1_CAPTURE_STA&0X80)==0)//»¹Î´³É¹¦²¶»ñ
{
if(TIM2CH1_CAPTURE_STA&0X40)//ÒѾ²¶»ñµ½¸ßµçƽÁË
{
if((TIM2CH1_CAPTURE_STA&0X3F)==0X3F)//¸ßµçƽ̫³¤ÁË
{
TIM2CH1_CAPTURE_STA|=0X80; //±ê¼Ç³É¹¦²¶»ñÁËÒ»´Î
TIM2CH1_CAPTURE_VAL=0XFFFFFFFF;
}
else TIM2CH1_CAPTURE_STA++;
}
}
}
//¶¨Ê±Æ÷ÊäÈ벶»ñÖжϴ¦Àí»Øµ÷º¯Êý£¬¸Ãº¯ÊýÔÚHAL_TIM_IRQHandlerÖлᱻµ÷ÓÃ
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//²¶»ñÖжϷ¢ÉúʱִÐÐ
{
if((TIM2CH1_CAPTURE_STA&0X80)==0)//»¹Î´³É¹¦²¶»ñ
{
if(TIM2CH1_CAPTURE_STA&0X40) //²¶»ñµ½Ò»¸öϽµÑØ
{
TIM2CH1_CAPTURE_STA|=0X80; //±ê¼Ç³É¹¦²¶»ñµ½Ò»´ÎµÍµçƽÂö¿í
TIM2CH1_CAPTURE_VAL=HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_1);//»ñÈ¡µ±Ç°µÄ²¶»ñÖµ.
long long temp=0;
temp=TIM2CH1_CAPTURE_STA&0X3F;
temp*=0XFFFFFFFF; //Òç³öʱ¼ä×ܺÍ
temp+=TIM2CH1_CAPTURE_VAL; //µÃµ½×ܵĸߵçƽʱ¼ä
temp=temp*17/1000;
printf("distence:%lld cm\r\n",temp);//´òÓ¡×ܵĸߵãƽʱ¼ä
__HAL_TIM_DISABLE(&htim2); //¹Ø±Õ¶¨Ê±Æ÷2
}
else //»¹Î´¿ªÊ¼,µÚÒ»´Î²¶»ñÉÏÉýÑØ
{
TIM2CH1_CAPTURE_STA=0; //Çå¿Õ
TIM2CH1_CAPTURE_VAL=0;
TIM2CH1_CAPTURE_STA|=0X40; //±ê¼Ç²¶»ñµ½ÁËÉÏÉýÑØ
__HAL_TIM_DISABLE(&htim2); //¹Ø±Õ¶¨Ê±Æ÷2
__HAL_TIM_SET_COUNTER(&htim2,0);
TIM_RESET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1); //Ò»¶¨ÒªÏÈÇå³ýÔÀ´µÄÉèÖã¡£¡
TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1, TIM_ICPOLARITY_FALLING);//¶¨Ê±Æ÷2ͨµÀ1ÉèÖÃΪÉÏϽµÑز }
}
}
/* USER CODE END 1 */
定义了两个全局变量,用于辅助实现高电平捕获。其中TIM2CH1_CAPTURE_STA是用来记录捕获状态,各位描述如下:辅助实现高电平捕获。其中TIM2CH1_CAPTURE_STA是用来记录捕获状态,各位描述如下:
bit7:捕获完成标志
bit6:捕获到高电平的标志
bit5~0:捕获高电平后定时器溢出的次数
另一个变量TIM2CH1_CAPTURE_VAL,则用来记录捕获到下降沿的时候,TIM2_CNT的值。
main函数内容
int main(void)
{
/* USER CODE BEGIN 1 */
long long temp=0;
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_1); //¿ªÆôTIM5µÄ²¶»ñͨµÀ1£¬²¢ÇÒ¿ªÆô²¶»ñÖжÏ
__HAL_TIM_ENABLE_IT(&htim2,TIM_IT_UPDATE); //ʹÄܸüÐÂÖжÏ
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
if(TIM2CH1_CAPTURE_STA&0X80) //³É¹¦²¶»ñµ½ÁËÒ»´ÎµÍµçƽ
{
HAL_Delay(1000);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
__HAL_TIM_SET_COUNTER(&htim2,0);
TIM_RESET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1); //Ò»¶¨ÒªÏÈÇå³ýÔÀ´µÄÉèÖã¡£¡
TIM_SET_CAPTUREPOLARITY(&htim2,TIM_CHANNEL_1,TIM_ICPOLARITY_RISING);//¶¨Ê±Æ÷2ͨµÀ1ÉèÖÃΪÉÏÉýÑز¶»ñ
__HAL_TIM_ENABLE(&htim2);//ʹÄܶ¨Ê±Æ÷5
TIM2CH1_CAPTURE_STA=0;
}
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
完整工程下载:http://download.csdn.net/detail/sensiki/9825937