GD32F310F8P6开发笔记

基于GD32F310F8P6的电源管理板软件。设备供电系统由220V、24V组成。当220V供电时,给24V电池充电,没有220V时由24V电池供电。电源管理软件实现电源切换,充电功能,并把相关信息通过串口发送给主板。

下载问题

demo下载不了

ADC

PA0,PA1用做ADC,分别用于检测充电电流和电池电压。查看数据手册引脚定义,PA0是ADC_IN0,PA1是ADC_IN1。ADC配置为扫描模式,连续模式,使用DMA,参考电压是3.3V,分辨率8位。在调试的过程中,adc值一直是0。将PA0接到3.3V,adc值还是0。一开始怀疑是软件问题,用官方demo也是同样的结果,换另外一块板子,adc值正常。换另外一颗芯片解决了这个问题,结论是芯片问题。

#include "gd32f3x0.h"
#include "systick.h"
#include "drv_adc.h"

#define ADC_CHAN_NUM	2U
uint16_t adc_value[ADC_CHAN_NUM];

void rcu_config(void);
void gpio_config(void);
void dma_config(void);
void adc_config(void);

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
void adcConfig(void)
{
    /* system clocks configuration */
    rcu_config();
    /* GPIO configuration */
    gpio_config();
    /* DMA configuration */
    /* ADC configuration */
    dma_config();
    adc_config();
}

/*!
    \brief      configure the different system clocks
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void rcu_config(void)
{
    /* enable GPIOC clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    /* enable ADC clock */
    rcu_periph_clock_enable(RCU_ADC);
    /* enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA);
    /* config ADC clock */
    rcu_adc_clock_config(RCU_ADCCK_APB2_DIV6);
}

/*!
    \brief      configure the GPIO peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void gpio_config(void)
{
    /* config the GPIO as analog mode */
    gpio_mode_set(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_0 | GPIO_PIN_1);
}

/*!
    \brief      configure the DMA peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void dma_config(void)
{
    /* ADC_DMA_channel configuration */
    dma_parameter_struct dma_data_parameter;

    /* ADC DMA_channel configuration */
    dma_deinit(DMA_CH0);

    /* initialize DMA single data mode */
    dma_data_parameter.periph_addr  = (uint32_t)(&ADC_RDATA);
    dma_data_parameter.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_data_parameter.memory_addr  = (uint32_t)(&adc_value);
    dma_data_parameter.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_data_parameter.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_data_parameter.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_data_parameter.direction    = DMA_PERIPHERAL_TO_MEMORY;
    dma_data_parameter.number       = ADC_CHAN_NUM;
    dma_data_parameter.priority     = DMA_PRIORITY_HIGH;
    dma_init(DMA_CH0, &dma_data_parameter);

    dma_circulation_enable(DMA_CH0);

    /* enable DMA channel */
    dma_channel_enable(DMA_CH0);
}

/*!
    \brief      configure the ADC peripheral
    \param[in]  none
    \param[out] none
    \retval     none
*/
static void adc_config(void)
{
    /* ADC continuous function enable */
    adc_special_function_config(ADC_CONTINUOUS_MODE, ENABLE);
    /* ADC scan function enable */
    adc_special_function_config(ADC_SCAN_MODE, ENABLE);
    /* ADC data alignment config */
    adc_data_alignment_config(ADC_DATAALIGN_RIGHT);
	adc_resolution_config(ADC_RESOLUTION_8B) ;
    /* ADC channel length config */
    adc_channel_length_config(ADC_REGULAR_CHANNEL, ADC_CHAN_NUM);

    /* ADC regular channel config */
    adc_regular_channel_config(0, ADC_CHANNEL_0, ADC_SAMPLETIME_55POINT5);
    adc_regular_channel_config(1, ADC_CHANNEL_1, ADC_SAMPLETIME_55POINT5);

    /* ADC trigger config */
    adc_external_trigger_source_config(ADC_REGULAR_CHANNEL, ADC_EXTTRIG_REGULAR_NONE);
    adc_external_trigger_config(ADC_REGULAR_CHANNEL, ENABLE);

    /* enable ADC interface */
    adc_enable();
    delay_1ms(1U);
    /* ADC calibration and reset calibration */
    adc_calibration_enable();

    /* ADC DMA function enable */
    adc_dma_mode_enable();
    /* ADC software trigger enable */
    adc_software_trigger_enable(ADC_REGULAR_CHANNEL);
}

//adc值换算成电压,注意乘法溢出,stSystate.batAdc最大值是4095,不溢出
stSystate.batVolmv = stSystate.batAdc * 125400 / 40950 + 18000;

PWM

PA4用作PWM输出,用于调节充电电流。pwm占空比加大,充电电流加大。pwm标准频率为100khz。查看数据手册引脚定义,PA4复用功能4是作为TIMER13_CH0输出,可以输出pwm。

系统时钟是72Mhz,AHB时钟是72Mhz,TIMER13时钟是1Mhz,pwm频率是100khz。

/*!
    \brief      configure the TIMER peripheral
    \param[in]  none
    \param[out] none
    \retval     none
  */
#define USER_TIMER_BASE	TIMER13
#define PWM_PERIOD	100

void timer_config(void)
{
    timer_oc_parameter_struct timer_ocintpara;
    timer_parameter_struct timer_initpara;

    rcu_periph_clock_enable(RCU_GPIOA);

    /*Configure PA4(TIMER13_CH0) as alternate function*/
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_4);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_4);
    gpio_af_set(GPIOA, GPIO_AF_4, GPIO_PIN_4);

    /*
    TIMER0 configuration: generate PWM signals with different duty cycles:
    TIMER0CLK = SystemCoreClock / (6+1) = 72/7 = 10MHz
	pwm frequency is 10Mhz/10 = 100khz
    */

    rcu_periph_clock_enable(RCU_TIMER13);
    timer_deinit(USER_TIMER_BASE);

    /* TIMER0 configuration */
    timer_initpara.prescaler         = 6;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;
    timer_initpara.period            = 100;
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
    timer_initpara.repetitioncounter = 0;
    timer_init(USER_TIMER_BASE,&timer_initpara);

     /* CH0 configuration in PWM mode */
    timer_ocintpara.outputstate  = TIMER_CCX_ENABLE;
    timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
    timer_ocintpara.ocpolarity   = TIMER_OC_POLARITY_HIGH;
    timer_ocintpara.ocnpolarity  = TIMER_OCN_POLARITY_HIGH;
    timer_ocintpara.ocidlestate  = TIMER_OC_IDLE_STATE_LOW;
    timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
    timer_channel_output_config(USER_TIMER_BASE,TIMER_CH_0,&timer_ocintpara);

    timer_channel_output_pulse_value_config(USER_TIMER_BASE,TIMER_CH_0,1);
    timer_channel_output_mode_config(USER_TIMER_BASE,TIMER_CH_0,TIMER_OC_MODE_PWM0);
    timer_channel_output_shadow_config(USER_TIMER_BASE,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);

    timer_primary_output_config(USER_TIMER_BASE,ENABLE);
    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(USER_TIMER_BASE);
    timer_enable(USER_TIMER_BASE);
}

void timer13_pwm_set_duty_cycle(uint16_t duty_cycle) {
	/* configure TIMER channel output pulse value */
	if(duty_cycle>PWM_PERIOD)
		duty_cycle = PWM_PERIOD;
    timer_channel_output_pulse_value_config(TIMER13, TIMER_CH_0, duty_cycle);
}

UART

PA2,PA3用作uart。在F8中,PA2用作UART1_TX,PA3用作UART1_RX。

#define EVAL_COM                         USART1
#define EVAL_COM_CLK                     RCU_USART1
#define EVAL_COM_IRQ                     USART1_IRQn

#define EVAL_COM_TX_PIN                  GPIO_PIN_2
#define EVAL_COM_RX_PIN                  GPIO_PIN_3

#define EVAL_COM_GPIO_PORT               GPIOA
#define EVAL_COM_GPIO_CLK                RCU_GPIOA
#define EVAL_COM_AF                      GPIO_AF_1

static rcu_periph_enum COM_CLK[COMn]  = {EVAL_COM_CLK};
static uint32_t COM_TX_PIN[COMn]      = {EVAL_COM_TX_PIN};
static uint32_t COM_RX_PIN[COMn]      = {EVAL_COM_RX_PIN};

uint8_t tx_data[DEBUG_MAX_SIZE];
uint16_t tx_length;
uint16_t tx_count;

void gd_eval_com_init(uint32_t com)
{
    uint32_t COM_ID = 0U;

    if(EVAL_COM == com){
        COM_ID = 0U;
    }else{
    }

    /* enable COM GPIO clock */
    rcu_periph_clock_enable(EVAL_COM_GPIO_CLK);

    /* enable USART clock */
    rcu_periph_clock_enable(COM_CLK[COM_ID]);

    /* connect port to USARTx_Tx */
    gpio_af_set(EVAL_COM_GPIO_PORT, EVAL_COM_AF, COM_TX_PIN[COM_ID]);

    /* connect port to USARTx_Rx */
    gpio_af_set(EVAL_COM_GPIO_PORT, EVAL_COM_AF, COM_RX_PIN[COM_ID]);

    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(EVAL_COM_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, COM_TX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, COM_TX_PIN[COM_ID]);

    /* configure USART Rx as alternate function push-pull */
    gpio_mode_set(EVAL_COM_GPIO_PORT, GPIO_MODE_AF, GPIO_PUPD_PULLUP, COM_RX_PIN[COM_ID]);
    gpio_output_options_set(EVAL_COM_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_10MHZ, COM_RX_PIN[COM_ID]);

    /* USART configure */
    usart_deinit(com);
    usart_baudrate_set(com, 115200U);
    usart_receive_config(com, USART_RECEIVE_ENABLE);
    usart_transmit_config(com, USART_TRANSMIT_ENABLE);

    usart_enable(com);
}

nvic_irq_enable(EVAL_COM_IRQ, 0, 1);


//----------------------------------------


/*!
    \brief      this function handles USART RBNE interrupt request and TBE interrupt request
    \param[in]  none
    \param[out] none
    \retval     none
*/
void USART1_IRQHandler(void)
{
//    if (RESET != usart_interrupt_flag_get(EVAL_COM, USART_INT_FLAG_RBNE)){
//        /* receive data */
//        rx_buffer[rx_count++] = usart_data_receive(EVAL_COM);
//        if (rx_count >= rx_buffer_size){
//            usart_interrupt_disable(EVAL_COM, USART_INT_RBNE);
//        }
//    }

    if (RESET != usart_interrupt_flag_get(EVAL_COM, USART_INT_FLAG_TBE)){
        /* transmit data */
        usart_data_transmit(EVAL_COM, tx_data[tx_count++]);
        if (tx_count >= tx_length){
            usart_interrupt_disable(EVAL_COM, USART_INT_TBE);
        }
    }
}


void usart1_send_data(void) {
	uint8_t cnt = 0;

	memset(tx_data,0,sizeof(tx_data));
    tx_data[cnt++] = 0xcc;
	tx_data[cnt++] = 0xdd;
	tx_data[cnt++] = stSystate.extPower;
	tx_data[cnt++] = stSystate.discharge;
	tx_data[cnt++] = stSystate.charge;
	tx_data[cnt++] = stSystate.chargePwm;
	tx_data[cnt++] = stSystate.chargeCurAdc & 0xff;
	tx_data[cnt++] = stSystate.chargeCurAdc >> 8;
	tx_data[cnt++] = stSystate.batAdc & 0xff;
	tx_data[cnt++] = stSystate.batAdc >> 8;
	tx_data[cnt++] = stSystate.batVolmv & 0xff;
	tx_data[cnt++] = stSystate.batVolmv >> 8;
	tx_data[2+0x10] = calculateChecksum(tx_data,2+0x10);
	tx_length = 2+0x10+1;
    tx_count = 0;

    /* enable USART TBE interrupt */
    usart_interrupt_enable(EVAL_COM, USART_INT_TBE);

}

充电策略

外部电源接入时,电池电压低于21V才开始充电。在调试的时候发现充电电流的特性,开始时,充电电流随pwm增加的变化不大,在某个节点,一般是占空比达到90以上,电池电压越高,该节点越往后,出现pwm加1,充电电流增加200ma-500ma的情况。 但是之后充电电流会逐渐减小。为了寻找合适的充电电流,pwm从50开始增加,检测到充电电流在800ma-1000ma范围内,则以该pwm充电。如果充电电流超过1000ma,则占空比减1充电。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值