【GD32F310开发板试用】CMSIS-DAP上电只能烧录一次问题解决&定时器脉宽采集
首发极术社区。如对兆易创新GD32F310 MCU感兴趣,欢迎添加微信 aijishu2020 加入GD32技术讨论群。
兆易创新家的GD32F310的开发板到手了,今天给玩一玩。
我们先看看兆易创新如何解释自家的MCU
确认过眼神!哈哈
GD32F310拥有TSSOP20、QFN28、QFN32、LQFP32以及LQFP48共5种封装类型,采用Arm Cortex-M4内核,性能强劲,其内部集成了FPU,
下图是Cortex-M4内核的主要功能
CMSIS-DAP烧录问题
板子到手之后出现一个问题,CMSIS-DAP上电之后只能烧录一次单片机,弄了好久,感觉GPIO复用功能没有打开。
在GD32F3x0 固件库手册找到函数 gpio_af_set
函数原型:void gpio_af_set(uint32_t gpio_periph, uint32_t alt_func_num, uint32_t pin);
功能描述: 设置GPIO的备用功能
参数 :
gpio_periph GPIO 端口
alt_func_num GPIO 引脚备用功能
pin GPIO引脚
用这个函数把P13,P14的GPIO复用功能打开就好了,就是这三行代码
rcu_periph_clock_enable(RCU_GPIOA);gpio_af_set(GPIOA,GPIO_AF_0,GPIO_PIN_13);gpio_af_set(GPIOA,GPIO_AF_0,GPIO_PIN_14);
定时器采集脉宽
第一步 初始GPIO
void gpio_configuration(void){ rcu_periph_clock_enable(RCU_GPIOB); gpio_mode_set(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4); gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_4); gpio_af_set(GPIOB, GPIO_AF_1, GPIO_PIN_4);}
选择PB4作为脉宽输入,其复用功能为TIMER_CH0;TIMER_CH0;
第二步 配置嵌套矢量中断控制器
void nvic_configuration(void){ nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3); nvic_irq_enable(TIMER2_IRQn, 1, 1);}
第三步 初始化定时器
void timer_configuration(void){timer_ic_parameter_struct timer_icinitpara; timer_parameter_struct timer_initpara; rcu_periph_clock_enable(RCU_TIMER2); timer_deinit(TIMER2); timer_initpara.prescaler = 7199; 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(TIMER2, &timer_initpara); /* TIMER2 configuration */ /* TIMER2 CH0 input capture configuration */ timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING ; //输入捕获下降沿 timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI; timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1; timer_icinitpara.icfilter = 0x0; timer_input_capture_config(TIMER2, TIMER_CH_0, &timer_icinitpara); /* auto-reload preload enable */ timer_auto_reload_shadow_enable(TIMER2); /* clear channel 0 interrupt bit */ timer_interrupt_flag_clear(TIMER2, TIMER_INT_CH0); /* channel 0 interrupt enable */ timer_interrupt_enable(TIMER2, TIMER_INT_CH0); /* TIMER2 counter enable */ timer_enable(TIMER2);}
第三步 配置定时器中断
void TIMER2_IRQHandler(void){ if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH0)) { timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH0); if(0 == ccnumber) { //读取通道 0 捕获值 readvalue1 = timer_channel_capture_value_register_read(TIMER2, TIMER_CH_0); TIMER_CHCTL2(TIMER2) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); TIMER_CHCTL2(TIMER2) |= (uint32_t)(TIMER_IC_POLARITY_RISING); ccnumber = 1; } else if(1 == ccnumber) { readvalue2 = timer_channel_capture_value_register_read(TIMER2, TIMER_CH_0); TIMER_CHCTL2(TIMER2) &= (~(uint32_t)(TIMER_CHCTL2_CH0P | TIMER_CHCTL2_CH0NP)); TIMER_CHCTL2(TIMER2) |= (uint32_t)(TIMER_IC_POLARITY_FALLING); if(readvalue2 > readvalue1) { count = (readvalue2 - readvalue1); } else { count = ((0xFFFF - readvalue1) + readvalue2); } ccnumber = 0; } }}
第四步 主函数
int main(void){ rcu_periph_clock_enable(RCU_GPIOA); gpio_af_set(GPIOA,GPIO_AF_0,GPIO_PIN_13); gpio_af_set(GPIOA,GPIO_AF_0,GPIO_PIN_14); gpio_configuration(); nvic_configuration(); timer_configuration(); while(1){ delay_1ms(100); printf("\r /****按键脉宽:%d****/\r\n",count);} }