前瞻步骤:1配置SYS调试接口(SWD)和时钟源(SysTick)、2配置RCC的High Speed Clock(HSSE)(CrystalCeramic Resonator)和3配置时钟树(Clock Configuration),注:详细看学习笔记(二)。
步骤4、配置定时器1(TIM1)
首先在功能类型中找到定时器(Timers)功能,在其下选择定时器1(TIM1);
其次配置定时器的时钟源(Clock Source)为内部时钟源(Internal Clock);
最后配置定时器1(TIM1)的基础参数(Prescaler、Period、CounterMode、ClockDivision、RepetitionCounter和AutoReloadPreload),这里配置Prescaler为72-1,Period为65535,其余的设置为默认。
图1:配置TIM1为定时器模式
步骤5、配置GPIO模式为外部中断(EXIT)
首先在Pinout view窗口下找到引脚PA11,将其引脚功能设置为GPIO_EXTI11即外部触发中断;
其次在功能类型中选择系统核心(system core)类,在其下选择引脚(GPIO)找到PA11;
再者配置PA11的引脚模式为外部中断模式并且上升沿或者下降沿触发,PA11引脚配置为即不上拉也不下拉,用户命名为Echo;
最后切换到NVIC界面将EXTI line[15:10]interrupts使能。
图2:配置GPIO模式为外部中断
步骤6、配置串口通信(注:这里只是用来接收超声波测距值的交互串口所以这里不展开写,如果有需求,详情请看学习笔记(六))
首先在功能类型中找到连接通信(Connectivity)功能,在其下选择串口1(USART1);
其次通信模式配置为异步通信,波特率为9600,字节为8,无校验位,1位停止位;
最后使能中断,配置DMA。
这里我使用了无线模块(HC12)作为无线传输,所以配置个引脚作为其的使能引脚,影响不大。
图3:配置串口通信
步骤7、生成项目
配置project manager,配置完成后点击GENERATE CODE就可以生成此项目,(详细看学习笔记(二))。
步骤8、在main.c文件中定义两个变量
一个是char类型的10位字符串(str[10])作为串口发送数据的缓冲区;另一个为uint16_t类型的局部变量value1作为临时存储超声波测距的值。
图4:main.c文件的变量定义
步骤9、启动定时器1和使能外部中断通道10到15
启动定时器1
HAL_TIM_Base_Start_IT(&htim1);
使能外部中断通道10到15
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
步骤10、启动空闲中断和启动DMA
启动串口1的空闲中断
__HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);
启动串口1的DMA读取
HAL_UART_Receive_DMA(&huart1,rxbuffer,BUFFER_SIZE);
步骤11、主函数循环逻辑
首先当超声波回波标记为1是发送一个10MS的方波信号;
其次将超声波测量出来的距离传输到发送缓冲区;
最后当此前次超声波测量的距离与上次测量距离不同时,将此次的距离存储到了临时距离变量(value1), 通过串口中断发送串口数据缓冲区;
if(flig==1){
trigToggle();
HAL_Delay(10);
}
sprintf(str,"%dcm\r\n",getValue());
if(value1!=getValue())
{
value1=getValue();
HAL_UART_Transmit_IT(&huart1,(uint8_t *)str,strlen(str));
}
步骤12、 在tim.h头文件中延申超声波标志、声明trigToggle()函数和声明获取测距值的函数。
- 延申超声波标志:extern uint8_t flig;
- 声明trigToggle()函数:void trigToggle(void);
- 声明获取测距值的函数:uint16_t getValue(void);
步骤13、在tim.c源文件中,定义变量
- 超声波标志:因为标志值只需要0和1 所以此变量的类型设置为uint8_t,而且当首次进入循环时就需要进入trigToggle()函数,所以将标志(flig)设置为1;
- 存储测距值:超声波测量出来的距离会超过255又没超过65535,所以变量类型为uint16_t类型。这里的默认值就设置为零(value=0);
- trigToggle()函数步骤索引:在trigToggle()函数中其步骤不超过255所以变量类型为uint8_t类型且步骤从零开始(tindex=0)。
步骤14、配置trigToggle()函数
此函数主要是为了产生10MS的方波,所以每一步骤进行输出电平翻转而每步骤之间的延时即为方波的波宽,代码如下:
void trigToggle(void)
{
switch(tindex)
{
case 0:
HAL_GPIO_TogglePin(Trig_GPIO_Port,Trig_Pin);
tindex++;
break;
case 1:
HAL_GPIO_TogglePin(Trig_GPIO_Port,Trig_Pin);
tindex=0;
flig=0;
break;
}
}
步骤15、重写外部触发中断回调函数
在回调函数中,首先需要定义一个局部uint16_t变量用来存储Echo引脚触发的时间;
其次判断触发中断的引脚是不是Echo引脚,只有为Echo引脚的前提下才可以进行下一步;
当Echo引脚为高电平的时候,也就是上升沿触发,将定时器计算清零并且开启定时器1;
当Echo引脚为低电平的时候,也就是下降沿触发,就将定时器1关闭,并且将定时器1所计数存储到变量中;
最后根据声波在空气中传输的速度计算出来测量的距离,公式为S=T*0.034/2。
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{uint16_t time;
if(GPIO_Pin==Echo_Pin)
{
if(HAL_GPIO_ReadPin(Echo_GPIO_Port,Echo_Pin)==GPIO_PIN_SET)
{
__HAL_TIM_SET_COUNTER(&htim1,0);
HAL_TIM_Base_Start_IT(&htim1);
}
else
{
HAL_TIM_Base_Stop_IT(&htim1);
time=__HAL_TIM_GET_COUNTER(&htim1);
value=time*0.034/2;
}
}
}
步骤16、配置获取测距
首先,将测距标志置为1,也就是可以进行下一次方波发出;
最后,将回调函数所计算到的距离返回调用此函数处。
uint16_t getValue(void)
{
flig=1;
return value;
}
已经补完
步骤15、配置串口
目前在外面工作,手上没有超声波模块进行效果展示,不过逻辑已经使用到自制的智能小车上了,有什么问题可以说一下,后面有时间在补充上来。
(注:这些笔记基本会无偿公开一周时间,后面基本没有什么人会看的所以会转为粉丝可见,笔记1和2会一直公开)