基于GD32的超声波模块开发
代码见下:
首先初始化引脚接口,利用PA11作为Triger触发脚,PB12作为Echo脚。
(注意如果采集到的超声波信号一直为0,请检查触发脉宽是否大于10us,另外驱动电压vcc和Echo引脚的响应信号的电压均为5V,使用的时候要避免直接与IO口进行连接(GD32引脚最大电压为3.6V!!!!!))
rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
gpio_init(GPIOA,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_11);
gpio_init(GPIOB,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_12);
gpio_bit_reset(GPIOA,GPIO_PIN_11);
gpio_bit_reset(GPIOB,GPIO_PIN_12);
本例中使用TImer1作为计数时钟,初始化Timer1。由于数据处理是在中断中进行的,因此也要初始化中断。
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
//初始化中断
NVIC_SetPriorityGrouping(NVIC_PRIGROUP_PRE4_SUB0);
nvic_irq_enable(EXTI10_15_IRQn,4,0);
gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOB,GPIO_PIN_SOURCE_12);
exti_init(EXTI_12,EXTI_INTERRUPT,EXTI_TRIG_RISING);
exti_interrupt_flag_clear(EXTI_12);
//定时器1初始化
rcu_periph_clock_enable(RCU_TIMER1);
timer_deinit(TIMER1);
/* TIMER1 configuration */
//1us进行一次计数
timer_initpara.prescaler = 119;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 65535;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER1,&timer_initpara);
定义产生触发信号的函数
void Triger(void)
{
uint32_t count=0;
gpio_bit_set(GPIOA,GPIO_PIN_11);
for(count=0;count<800;count++);//产生一个大于10us的脉冲,这里的800是用示波器测出来的。
gpio_bit_reset(GPIOA,GPIO_PIN_11);
}
最后在中断中对数据进行处理输出即可
/*!
\brief Timer1 Interrupt handler
\param[in] none
\param[out] none
\retval none
*/
void Timer1_EXTI_IRQHandler(void)
{
uint32_t lastCount=0;
if(RESET!=exti_interrupt_flag_get(EXTI_12))//发生超声波中断
{
//先将定时器进行初始化,设置计数寄存器为0
timer_counter_value_config(TIMER1,0);
timer_enable(TIMER1);
while(gpio_input_bit_get(GPIOB,GPIO_PIN_12)==1);
lastCount=timer_counter_read(TIMER1);
printf("get trigger !!value = %d cm\n",(lastCount*34/2000));
timer_disable(TIMER1);
exti_interrupt_flag_clear(EXTI_12);
}
}
下面程序是初始化串口的代码,作为开发参考。
usart.c
#include "MiniSys_usart.h"
/*!
\brief USART initialize function
\param[in] none
\param[out] none
\retval none
*/
void MiniSys_USART_Init(void)
{
/* enable GPIO clock */
rcu_periph_clock_enable(RCU_GPIOB);
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART0);
/* connect port to USART0_TX */
gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
/* connnect port to USART0_RX */
gpio_init(GPIOB,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
/* remap config */
gpio_pin_remap_config(GPIO_USART0_REMAP,ENABLE);
/*usart configure */
usart_deinit(USART0);
usart_baudrate_set(USART0,115200U);
usart_receive_config(USART0,USART_RECEIVE_ENABLE);
usart_transmit_config(USART0,USART_TRANSMIT_ENABLE);
usart_enable(USART0);
}
/*!
\brief retarget the C library printf function to the USART
\param[in] none
\param[out] none
\retval none
*/
int fputc(int ch, FILE *f)
{
usart_data_transmit(USART0, (uint8_t)ch);
while(RESET == usart_flag_get(USART0, USART_FLAG_TBE));
return ch;
}