HT32+超声波测距
今天记录的是HT32F52352 通过定时器来实现超声波测距,在网上看了很多资料没有找到自己想要的,最后通过stm32写过的超声波进行了移值,遇到了很多问题,目前可用但非常不准不过对于我所做的作品来说足够了,最大的距离才测出16cm ,该了很久还是这种,望大佬们指正。
使用的是HC-SR04型号的超声波,具体的就不详细介绍了
使用的是定时器GPTM0
csb.h
#ifndef _CSB_H_
#define _CSB_H_
#include "ht32f5xxxx_ckcu.h"
#include "ht32f5xxxx_gpio.h"
//端口号定义
#define HT_GPIO_PORT_HC04 HT_GPIOA
//Trig 发送引脚 PD1
#define HC_SR04_Trig_GPIO_PIN GPIO_PIN_15
//Echo 接收引脚 PD2
#define HC_SR04_Echo_GPIO_PIN GPIO_PIN_14
#define HC_SR04_Trig_H() GPIO_WriteOutBits(HT_GPIO_PORT_HC04,HC_SR04_Trig_GPIO_PIN,SET) //拉高Trig
#define HC_SR04_Trig_L() GPIO_WriteOutBits(HT_GPIO_PORT_HC04,HC_SR04_Trig_GPIO_PIN,RESET) //拉低Trig
void HC_SR04_Init(void);
void Open_GPTM0(void);
void Close_GPTM0(void);
int Get_HS_Echo_Value(void);
int Get_HS_Time_Value(void);
float Get_HS_Length_Value(void);
#endif
csb.c
#include "csb.h"
#include "delay.h"
uint32_t overcount; //记录定时器溢出次数
void HC_SR04_Init(void)
{
CKCU_PeripClockConfig_TypeDef HC_CLOCK ={{0}};
TM_TimeBaseInitTypeDef TimeBaseIniture; //结构体
// HC_CLOCK.Bit.AFIO = 1; //开启引脚复用
HC_CLOCK.Bit.GPTM0 = 1; //开启中断时钟
HC_CLOCK.Bit.PA = 1; //使用PA
CKCU_PeripClockConfig(HC_CLOCK,ENABLE); //使能时钟AFIO_MODE_DEFAULT
//GPIO_DirectionConfig(HT_GPIO_TypeDef* HT_GPIOx, u16 GPIO_PIN_nBITMAP, GPIO_DIR_Enum GPIO_DIR_INorOUT);
GPIO_DirectionConfig(HT_GPIO_PORT_HC04,HC_SR04_Trig_GPIO_PIN,GPIO_DIR_OUT); //配置GPIO PD1为输出模式
GPIO_WriteOutBits(HT_GPIO_PORT_HC04, HC_SR04_Trig_GPIO_PIN ,RESET);
GPIO_DirectionConfig(HT_GPIO_PORT_HC04,HC_SR04_Echo_GPIO_PIN,GPIO_DIR_IN); //配置GPIO PD1为输入模式
// GPIO_PullResistorConfig(HT_GPIO_PORT_HC04,HC_SR04_Echo_GPIO_PIN,GPIO_PR_DISABLE); //下拉
GPIO_InputConfig(HT_GPIO_PORT_HC04,HC_SR04_Echo_GPIO_PIN,ENABLE);
//定时器初始化
TimeBaseIniture.CounterMode = TM_CNT_MODE_UP; //边沿对齐向上模式
TimeBaseIniture.CounterReload = 1000-1; //计数重装载计数器
TimeBaseIniture.Prescaler = 48 -1; //预分频系数
TimeBaseIniture.PSCReloadTime=TM_PSC_RLD_IMMEDIATE; //立即重装载
TM_TimeBaseInit(HT_GPTM0,&TimeBaseIniture);
TM_IntConfig(HT_GPTM0,TM_INT_UEV,ENABLE);
TM_Cmd(HT_GPTM0,DISABLE);
}
/**
* 功能:打开定时器函数
* 参数:None
* 返回值:None
*/
void Open_GPTM0(void)
{
TM_SetCounter(HT_GPTM0, 0);
overcount = 0;
TM_Cmd(HT_GPTM0, ENABLE);
}
/**
* 功能:关闭定时器4函数
* 参数:None
* 返回值:None
*/
void Close_GPTM0(void)
{
TM_Cmd(HT_GPTM0, DISABLE);
}
/**
* 功能:获取Echo引脚电平
* 参数:None
* 返回值:Echo_Value:高电平 or 低电平
*/
int Get_HS_Echo_Value(void)
{
uint16_t Echo_Value;
Echo_Value = GPIO_ReadInBit(HT_GPIOA, GPIO_PIN_14);
return Echo_Value;
}
/**
* 功能:获取高电平持续时间
* 参数:None
* 返回值:HS_Timer高电平持续时间
*/
int Get_HS_Time_Value(void)
{
uint32_t HS_Timer = 0;
HS_Timer = overcount*1000;
HS_Timer += TM_GetCounter(HT_GPTM0);
HT_GPTM0 -> CNTR = 0; //清除计数器寄存器的值
delay_ms(50);
return HS_Timer;
}
/**
* 功能:获取距离
* 参数:None
* 返回值:length :距离
*/
float Get_HS_Length_Value(void)
{
uint32_t time = 0;
uint16_t i;
float length = 0;
float sum =0 ;
for(i=0;i<5;i++)
{
HC_SR04_Trig_H();
delay_us(20);
HC_SR04_Trig_L();
while( GPIO_ReadInBit(HT_GPIOA, GPIO_PIN_14) == RESET);
Open_GPTM0();
while(GPIO_ReadInBit(HT_GPIOA, GPIO_PIN_14)== SET);
Close_GPTM0();
time=Get_HS_Time_Value();
length = ((float)time/58.0);
sum = sum + length;
}
length=sum/5.0;
return length;
}
//定时器中断
void GPTM0_IRQHandler(void)
{
if(TM_GetIntStatus(HT_GPTM0,TM_INT_UEV) != RESET)
{
TM_ClearIntPendingBit(HT_GPTM0,TM_INT_UEV); //清除中断标志
overcount++;
}
}
main.c
#include "ht32.h"
#include "ht32_board.h"
#include "led.h"
#include "delay.h"
#include "uart.h"
#include "time.h"
#include "csb.h"
#include "rain.h"
/******************TH32 超声波*******************
Author:小殷
Date:2022-5-2
***************************************************************/
float dis = 0;
int main()
{
Led_Init();
Uart_Init();
GPTM_PWM_init();
HC_SR04_Init();
printf("---------csb Test------\n");
while(1)
{
dis = Get_HS_Length_Value();
printf("dis = %.2f\n",dis);
delay_ms(1000);
}
}
实验结果
初次分析应该是定时器配置的问题,但是修改了很久还是没有搞好,请大佬指教。