超声波雷达--IO方式驱动

1.超声波雷达驱动.h文件

采用一个定时器10us一次进行检测

#include "stdint.h"


extern TIM_HandleTypeDef htim16;
#define Driver_Radar_ITStart()			HAL_TIM_Base_Start_IT(&htim16)
#define Driver_Radar_ITStop()			HAL_TIM_Base_Stop_IT(&htim16)
#define Driver_Radar_Cnt_Clear()		__HAL_TIM_SET_COUNTER(&htim16, 0)

#define Driver_Radar1_Trig_Port			GPIOB
#define Driver_Radar1_Echo_Port			GPIOB

#define Driver_Radar1_Trig_Pin			GPIO_PIN_11
#define Driver_Radar1_Echo_Pin			GPIO_PIN_10

#define Driver_Radar_Set				GPIO_PIN_SET
#define Driver_Radar_Reset				GPIO_PIN_RESET

#define Driver_Radar_Start_Time			10			//触发信号时间 -- 10us*100
#define Driver_Radar_Time_Out			24000		//检测最大为4m,时间约为0.24s
#define Driver_Radar_Error_Time			4000		//测试时发送出现莫名其妙的大数值一般就是雷达太近了
#define Driver_Radar_Normal				0x00		//正常模式
#define Driver_Radar_Trig_Off			0x01		//触发信号关闭模式
#define Driver_Radar_Cheak_Ready		0x02		//检测信号准备
#define Driver_Radar_Cheak				0x03		//检测信号模式


typedef enum
{
	Radar_1 = 0,
	
	Radar_Max
} Driver_Radar_TypeDef;


typedef struct
{
	volatile uint8_t Ctrl;
	volatile uint32_t time;
	uint32_t cheak_time;
	uint32_t pin_number;
	void (*Radat_On)(void);
	void (*Radat_Off)(void);
	uint8_t (*Radat_Read)(void);
} Driver_Radar_Struct;

2.超声波雷达驱动.c文件

//雷达1开启
static void Driver_Radar_1_On(void)
{
	HAL_GPIO_WritePin(Driver_Radar1_Trig_Port, Driver_Radar1_Trig_Pin, Driver_Radar_Set);
}

//雷达1关闭
static void Driver_Radar_1_Off(void)
{
	HAL_GPIO_WritePin(Driver_Radar1_Trig_Port, Driver_Radar1_Trig_Pin, Driver_Radar_Reset);
}

//雷达1读数据
static uint8_t Driver_Radar_1_Read(void)
{
	return HAL_GPIO_ReadPin(Driver_Radar1_Echo_Port, Driver_Radar1_Echo_Pin);
}

static Driver_Radar_Struct radar[Radar_Max] = 
{
	//控制信号	触发时间		检测时间		引脚号					触发信号开			触发信号关			检测信号读取
	{0, 		0,  		0, 			Driver_Radar1_Echo_Pin, Driver_Radar_1_On, 	Driver_Radar_1_Off, Driver_Radar_1_Read},
};


/*********************************************************************
 * @fn      Driver_Radar_Start
 *
 * @brief   雷达启动.
 *
 * @param   none
 *
 * @return  none
 */
void Driver_Radar_Start(uint8_t ID)
{
	if(ID < Radar_Max)
	{
		if(radar[ID].Ctrl == Driver_Radar_Normal)
		{
			radar[ID].time = 0;
			radar[ID].Ctrl = Driver_Radar_Trig_Off;
			radar[ID].Radat_On();
			Driver_Radar_Cnt_Clear();
			Driver_Radar_ITStart();
		}
	}
}


/*********************************************************************
 * @fn      Driver_Radar_Read
 *
 * @brief   读取雷达数值.
 *
 * @param   none
 *
 * @return  none
 */
uint16_t Driver_Radar_Read(uint8_t ID)
{
	return radar[ID].cheak_time;
}


/*********************************************************************
 * @fn      Driver_Radar_Cheak_Callback
 *
 * @brief   雷达检测.
 *
 * @param   none
 *
 * @return  none
 */
void Driver_Radar_Cheak_Callback(uint16_t GPIO_Pin)
{
	for(Driver_Radar_TypeDef i = Radar_1; i < Radar_Max; i++)
	{
		if(GPIO_Pin == radar[i].pin_number)
		{
			if(radar[i].Radat_Read() == Driver_Radar_Set)
			{
				radar[i].time = 0;
				radar[i].Ctrl = Driver_Radar_Cheak;
			}
			else if(radar[i].Radat_Read() == Driver_Radar_Reset)
			{
				radar[i].cheak_time = radar[i].time;
				if(radar[i].cheak_time >= Driver_Radar_Error_Time)
				{
					radar[i].cheak_time = 0;
				}
				radar[i].time = 0;
				radar[i].Ctrl = Driver_Radar_Normal;
			}
		}
	}
}


/*********************************************************************
 * @fn      HAL_TIM_PeriodElapsedCallback
 *
 * @brief   定时器回调函数 -- 10us一次.
 *
 * @param   none
 *
 * @return  none
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	uint8_t radar_open_num = 0;
	
	if(htim->Instance == TIM16)
	{
		for(Driver_Radar_TypeDef i = Radar_1; i < Radar_Max; i++)
		{
			switch(radar[i].Ctrl)
			{
				case Driver_Radar_Normal:		//正常等待模式
					if(++radar_open_num >= Radar_Max)
					{
						Driver_Radar_ITStop();
					}
					break;
				
				case Driver_Radar_Trig_Off:		//信号触发模式
					if(radar[i].time++ >= Driver_Radar_Start_Time)
					{
						radar[i].Ctrl = Driver_Radar_Cheak_Ready;
						radar[i].time = 0;
						radar[i].Radat_Off();
					}
					break;
				
				case Driver_Radar_Cheak_Ready:	//数据等待校验模式

					break;
				
				case Driver_Radar_Cheak:		//数据检测模式
					radar[i].time++;
					break;
						
				default:
					break;
			}
		}
	}
}

3.例程

static uint16_t radar_val = 0;

Driver_Radar_Start(Radar_1);	//开启雷达
radar_val = Driver_Radar_Read(Radar_1)*17/10;

### 在 Atlas 200DK A2 的 IO 口上连接超声波雷达传感器的方法 在华为 Atlas 200DK A2 开发板上连接超声波雷达传感器需要完成硬件连接和软件配置两个部分。以下是详细说明: #### 硬件连接 Atlas 200DK A2 提供了丰富的 GPIO 接口,可以用于连接各种外部设备。超声波雷达传感器通常包含触发(Trigger)和回响(Echo)两个信号引脚。以下是连接步骤: 1. **确认接口类型**:Atlas 200DK A2 的 GPIO 接口支持多种模式(如 I2C、SPI、UART 等),但超声波雷达传感器一般只需要普通数字输入输出功能。 2. **连接传感器**:将超声波雷达传感器的 Trigger 引脚连接到开发板的一个 GPIO 输出引脚,Echo 引脚连接到一个 GPIO 输入引脚。同时确保电源和地线正确连接[^3]。 - 电源(VCC):通常为 5V 或 3.3V,需根据传感器规格选择合适的电压。 - 地线(GND):连接到开发板的地线。 - Trigger 和 Echo:分别连接到指定的 GPIO 引脚。 #### 软件配置 1. **启用 GPIO 功能**:在 CANN 框架下,GPIO 配置可以通过 `npu-smi` 工具或直接编写驱动代码实现。以下是一个简单的 Python 示例代码,展示如何使用 GPIO 控制超声波雷达传感器: ```python import RPi.GPIO as GPIO import time TRIG = 16 # GPIO 引脚号,对应 Trigger ECHO = 18 # GPIO 引脚号,对应 Echo GPIO.setmode(GPIO.BOARD) GPIO.setup(TRIG, GPIO.OUT) GPIO.setup(ECHO, GPIO.IN) def measure_distance(): GPIO.output(TRIG, False) time.sleep(0.2) GPIO.output(TRIG, True) time.sleep(0.00001) GPIO.output(TRIG, False) while GPIO.input(ECHO) == 0: pulse_start = time.time() while GPIO.input(ECHO) == 1: pulse_end = time.time() pulse_duration = pulse_end - pulse_start distance = pulse_duration * 17150 # 超声波速度计算公式 distance = round(distance, 2) return distance try: while True: dist = measure_distance() print(f"Distance: {dist} cm") time.sleep(1) except KeyboardInterrupt: GPIO.cleanup() ``` 上述代码通过控制 GPIO 引脚发送触发信号并测量回响时间,从而计算距离[^5]。 2. **环境准备**:确保开发板运行的操作系统支持 GPIO 操作。对于 Ubuntu 系统,可以安装 `RPi.GPIO` 库以简化 GPIO 控制: ```bash sudo apt-get update sudo apt-get install python3-rpi.gpio ``` 3. **测试与调试**:运行上述代码后,检查是否能够正确获取超声波雷达传感器的距离数据。如果遇到问题,可以参考昇腾官方文档中的 GPIO 配置指南[^4]。 #### 注意事项 - 确保开发板的 GPIO 引脚电压与传感器的工作电压匹配,避免损坏设备。 - 如果需要同时连接多个传感器,建议使用多路复用器或其他扩展设备。 - 开发板的 GPIO 驱动可能需要额外配置,具体方法请参考昇腾官方文档[^3]。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值