在完成《让Pegasus天马座开发板用上OLED屏》后,我觉得可以把超声波测距功能也在Pegasus天马座开发板上实现。于是在箱子里找到了,Grove - Ultrasonic Ranger 这一超声波测传感器。
官方地址: https://wiki.seeedstudio.com/Grove-Ultrasonic_Ranger
Grove - Ultrasonic Ranger测距模块一般配备有一个标准的Grove接口,使得接线变得简单。通常,这个模块有4个引脚:
其中SIG信号引脚,是触发信号引脚,也是发送测距时长反馈引脚(高电平的时长为超声波往返距离所以使用的时间)。
按照初中物理声音传播公式:
我们只要测出公式中T所用的时间,即可得到距离。
为了方便捕获SIG信号高脉冲的宽度,为使用芯片的TIMER2的通道3作为输入捕获口。此通道对应的是PA3这个IO口。如下图所示:
main.c代码
#include "config.h"
#include "delay.h"
#include "ultrasonic.h"
#include "oled.h"
#define LED_GPIO_PORT GPIOD
#define LED_PIN GPIO_PIN_4
#define BUTTON_GPIO_PORT GPIOD
#define BUTTON_PIN GPIO_PIN_3
static void init_gpio()
{
GPIO_Init(LED_GPIO_PORT, LED_PIN, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_Init(BUTTON_GPIO_PORT, BUTTON_PIN, GPIO_MODE_IN_PU_NO_IT);
OLED_Init();
}
void set_screen_color_and_display(uint8_t cfg)
{
// BIT0作为屏幕颜色控制 0: 正常显示, 1: 反色显示
OLED_ColorTurn(cfg & 0x01);
// BIT1作为屏幕颜色控制 0: 正常显示 1: 屏幕翻转显示
OLED_DisplayTurn((cfg >> 1) & 0x01);
}
void main(void)
{
static uint8_t testBuffer[32] = {0};
static uint8_t k = 0;
bool isKeyDown = FALSE;
uint8_t screenCfg = 0;
uint8_t t = ' ';
uint32_t range = 0;
disable_interrupts();
for (uint16_t i = 0; i < sizeof(testBuffer); i++)
{
testBuffer[i] = i;
}
enable_interrupts();
LOG("Startup...\r\nss");
DUMP(testBuffer,sizeof(testBuffer));
init_gpio();
OLED_ColorTurn(0);//0正常显示,1 反色显示
OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
while (1)
{
GPIO_WriteReverse(LED_GPIO_PORT,LED_PIN);
isKeyDown = GPIO_ReadInputPin(BUTTON_GPIO_PORT,BUTTON_PIN) == RESET;
range = ultrasonic_get_range_in_centimeters();
LOG(" app_sdcc == %u key %s , range == %lu cm\r\n",k++, isKeyDown ? "down" : "up",range);
if (isKeyDown == TRUE)
{
if (++screenCfg > 3)
{
screenCfg = 0;
}
set_screen_color_and_display(screenCfg);
OLED_Clear();
}
OLED_ShowString(25,0,"Pegasus Board",8);
OLED_ShowString(35,2,"2023/09/20",8);
OLED_ShowString(20,4,isKeyDown ? "Button Down" : "Button Up ",8);
OLED_ShowNum(90,4,range,3,8);
OLED_ShowString(108,4," cm",8);
OLED_ShowString(0,6,"ASCII:",8);
OLED_ShowString(63,6,"CODE:",8);
OLED_ShowChar(48,6,t,8);
t++;
if(t>'~')t=' ';
OLED_ShowNum(103,6,t,3,8);
delay(500);
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
LOG("Wrong parameters value: file %s on line %d\r\n", file, line);
/* Infinite loop */
while (1)
{
}
}
#endif
让Pegasus天马座开发板实现超声波测距
工程下载路径