> 文档中心 > 【GD32F310开发板试用】CMSIS-DAP上电只能烧录一次问题解决&定时器脉宽采集

【GD32F310开发板试用】CMSIS-DAP上电只能烧录一次问题解决&定时器脉宽采集


首发极术社区。如对兆易创新GD32F310 MCU感兴趣,欢迎添加微信 aijishu2020 加入GD32技术讨论群。
兆易创新家的GD32F310的开发板到手了,今天给玩一玩。
我们先看看兆易创新如何解释自家的MCU
【GD32F310开发板试用】CMSIS-DAP上电只能烧录一次问题解决&定时器脉宽采集

确认过眼神!哈哈

GD32F310拥有TSSOP20、QFN28、QFN32、LQFP32以及LQFP48共5种封装类型,采用Arm Cortex-M4内核,性能强劲,其内部集成了FPU,
下图是Cortex-M4内核的主要功能

【GD32F310开发板试用】CMSIS-DAP上电只能烧录一次问题解决&定时器脉宽采集

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);}     }