基于GD32F207ZE的光伏升压MPPT控制器

[复制链接]
2145|17
手机看帖
扫描二维码
随时随地手机跟帖
paderboy|  楼主 | 2016-1-25 22:14 | 显示全部楼层 |阅读模式
本帖最后由 paderboy 于 2016-1-25 22:15 编辑

一、方案名称:  

基于GD32F207ZE的光伏升压MPPT控制器

二、方案介绍:
此方案是采用GD32F207ZE作为主控制器的太阳能光伏充电控制器,可对以下主要的类型电池组实现充电管理:(铅酸电池组,普通锂电池组,铁锂电池组….等等)并且使用LCD显示光伏板电压,电池组电压和控制器温度(因为年末时间比较少,就简化了控制器的附加高级功能。(例如:可以再添加电流传感器,实现功率可控-发电电量累计和手机APP查看和设置参数。以及通过wifi实时上传物联网平台。。))有喜欢的利用本方案自己再添加高级功能。。。本控制器使用串口输入设置参数,为了后期可以使用蓝牙模块配合APP预留的功能,本控制器具有电池过压保护,控制器过温保护功能,夜间防逆流功能,
具有最大化利用光伏发电板,使其输出最大功率状态给电池组充电,实现绿色能源最大使用效益。。

三、方案结构框图:

流程图1.png
四、设计应用描述及心得总结:
1.    使用的GD32F207资源配置:配置DMAIDLE方式接收串口数据,配置5个DMAADC通道获取数据,配置TIMER2 2个通道PWM输出控制,配置SPI1显示数据,配置内部FLASH作为设置参数的掉电存储
GD32F207ze_07.png


2.    使用SPI1驱动LCD引脚配置:PA5-SCL,PA7-SI,PA4-RES,PD0-RSX,PD1-CSX

GD32F207ze_02.png
   

3.    控制器供电使用了LM2596HVS降压12v给MOS驱动IR2110s供电以及(通过5v降压和3.3vLDO降压)提供单片机的供电。。最高支持60vDC输入(也可以使用XL7015替换,支持最高80VDC输入)

GD32F207ze_04.png
GD32F207ze_05.png

GD32F207ze_06.png

GD32F207ze_03.png


4.    不得不说,第一次使用GD32F系列的单片机,对GD32的库(使用非常方便,提供的历程也很多。有时间还是要继续再深入的学习)和STM32库的兼容性非常不错。可以节省很多的时间再去重新学习GD32的库使用函数了。。。
      

五、作品实物图+视频:   

       串口调试截图:
GD32F207ze_01.png


IMG_20160125_120053.jpg

IMG_20160125_120135.jpg

IMG_20160125_120153.jpg

IMG_20160125_124144.jpg
        
       这个是小功率光伏板:
IMG20160125125024.jpg
      
       这个板子的功率非常小。。。电流只有180ma最大了。。。。。
IMG_20160125_124125.jpg
      
       移到楼下:换50w的光伏板
      
IMG_20160125_134025.jpg

       测试输入电压空载21v,输出23v电流:1.8a =41.4w的功率。。今天天气特别的好
IMG_20160125_133959.jpg
     

   
      视频里测试过程按了重启,为了方便观察mppt最大功率点的快速定位。。。

      视频演示链接:

六、方案部分代码:

ADC DMA 配置:PC0 PC2 PC3 内部温度传感器和内部Vrefint
void ADC_Configuration(void)
{
    ADC_InitPara ADC_InitStructure;
         
    ADC_InitStructure.ADC_Mode_Scan = ENABLE;
    ADC_InitStructure.ADC_Mode_Continuous = ENABLE;
    ADC_InitStructure.ADC_Trig_External = ADC_EXTERNAL_TRIGGER_MODE_NONE;
    ADC_InitStructure.ADC_Data_Align = ADC_DATAALIGN_RIGHT;
    ADC_InitStructure.ADC_Channel_Number = 5;
    ADC_Init(ADC1,&ADC_InitStructure);
    /* Configure ADC1 regular channel13 */
    ADC_RegularChannel_Config(ADC1, ADC_CHANNEL_10, 1, ADC_SAMPLETIME_55POINT5);
                ADC_RegularChannel_Config(ADC1, ADC_CHANNEL_12, 2, ADC_SAMPLETIME_55POINT5);
    ADC_RegularChannel_Config(ADC1, ADC_CHANNEL_13, 3, ADC_SAMPLETIME_239POINT5);
    ADC_RegularChannel_Config(ADC1, ADC_CHANNEL_16, 4, ADC_SAMPLETIME_239POINT5);
    ADC_RegularChannel_Config(ADC1, ADC_CHANNEL_17, 5, ADC_SAMPLETIME_239POINT5);
    ADC_TempSensorVrefint_Enable(ENABLE);

    /* Enable ADC1 DMA */
    ADC_DMA_Enable(ADC1,ENABLE);
    /* Enable ADC1 */
    ADC_Enable(ADC1,ENABLE);
    ADC_Calibration(ADC1);
    /* Start ADC1 Software Conversion */
    ADC_SoftwareStartConv_Enable(ADC1,ENABLE);
}
复制代码
SPI 配置: PA4 PA5 PA6 PA7 D0 D1 驱动ST7858 LCD
void SPI1_Configuration(void)
{
    SPI_InitPara  SPI_InitStructure;
    SPI_InitStructure.SPI_TransType = SPI_TRANSTYPE_FULLDUPLEX;
    SPI_InitStructure.SPI_Mode = SPI_MODE_MASTER;
    SPI_InitStructure.SPI_FrameFormat = SPI_FRAMEFORMAT_8BIT;
    SPI_InitStructure.SPI_SCKPL = SPI_SCKPL_HIGH;
    SPI_InitStructure.SPI_SCKPH = SPI_SCKPH_2EDGE;
    SPI_InitStructure.SPI_SWNSSEN = SPI_SWNSS_SOFT;
    SPI_InitStructure.SPI_PSC = SPI_PSC_4;
    SPI_InitStructure.SPI_FirstBit = SPI_FIRSTBIT_MSB;
    SPI_InitStructure.SPI_CRCPOL = 10;

    SPI_Init(SPI1, &SPI_InitStructure);
    SPI_Enable(SPI1, ENABLE);
                SPIx_ReadWriteByte(0xff);

}
复制代码
TIMER2 PWM输出配置:配置PA1 PA2
void TIM_Configuration(void)
{
    /* -----------------------------------------------------------------------
    TIMER2 Configuration: generate 2 PWM signals with 2 different duty cycles:
    TIMER2CLK = SystemCoreClock / 8 = 9MHz
    TIMER2 frequency = 180/9M = 0.02ms

    ----------------------------------------------------------------------- */
    TIMER_BaseInitPara TIMER_TimeBaseStructure;
    TIMER_OCInitPara   TIMER_OCInitStructure;

    /* TIMER2 clock enable */
    RCC_APB1PeriphClock_Enable(RCC_APB1PERIPH_TIMER2,ENABLE);

    /* TIMER2  configuration */
    TIMER_DeInit(TIMER2);
    TIMER_TimeBaseStructure.TIMER_Prescaler     = 8-1;
    TIMER_TimeBaseStructure.TIMER_CounterMode   = TIMER_COUNTER_UP;
    TIMER_TimeBaseStructure.TIMER_Period        = 180-1;
    TIMER_TimeBaseStructure.TIMER_ClockDivision = TIMER_CDIV_DIV1;
    TIMER_BaseInit(TIMER2,&TIMER_TimeBaseStructure);

    /* CH2,CH3 and CH4 Configuration in PWM mode */
    TIMER_OCInitStructure.TIMER_OCMode      = TIMER_OC_MODE_PWM1;
    TIMER_OCInitStructure.TIMER_OCPolarity  = TIMER_OC_POLARITY_HIGH;
    TIMER_OCInitStructure.TIMER_OutputState = TIMER_OUTPUT_STATE_ENABLE;
    TIMER_OCInitStructure.TIMER_OCIdleState = TIMER_OC_IDLE_STATE_RESET;

    TIMER_OCInitStructure.TIMER_Pulse = 0;
    TIMER_OC2_Init(TIMER2, &TIMER_OCInitStructure);
    TIMER_OC2_Preload(TIMER2,TIMER_OC_PRELOAD_DISABLE);

    TIMER_OCInitStructure.TIMER_Pulse = 0;
    TIMER_OC3_Init(TIMER2, &TIMER_OCInitStructure);
    TIMER_OC3_Preload(TIMER2,TIMER_OC_PRELOAD_DISABLE);

    /* Auto-reload preload enable */
    TIMER_CARLPreloadConfig(TIMER2,ENABLE);
    /* TIMER enable counter*/
    TIMER_Enable( TIMER2, ENABLE );
}
复制代码
FMC 存储数据函数:
void FMC_savedate(void)
{
          uint8_t p=0,n=0,flashflag[3]={0};
    if(flashdate==1)
                {
                if(ReadData[0]>=PVMIN&&ReadData[0]<=PVMAX){backupData[0]=ReadData[0];flashflag[0]=1;}else{/*printf("PV SETTING ERROR\n\r");*/}
                if(ReadData[1]>=BATMIN&&ReadData[1]<=BATMAX){backupData[1]=ReadData[1];flashflag[1]=1;}else{/*printf("BAT SETTING ERROR\n\r");*/}
                if(ReadData[2]>=FANMIN&&ReadData[2]<=FANMAX){backupData[2]=ReadData[2];flashflag[2]=1;}else{/*printf("FAN TEMP SETTING ERROR\n\r");*/}        
    for(p=0;p<Savenumber;p++){ReadData[p]=0;}                        
                if(flashflag[0]==1&&flashflag[1]==1&&flashflag[2]==1)
                {        
    FMC_Unlock();
   
    /* Define the number of page to be erased */
    NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FMC_PAGE_SIZE;
   
    /* Clear All pending flags */
    FMC_ClearBitState(FMC_FLAG_EOP | FMC_FLAG_WERR | FMC_FLAG_PERR );
   
    /* Erase the FLASH pages */
    for(EraseCounter = 0; EraseCounter < NbrOfPage; EraseCounter++)
    {
        FMCStatus = FMC_ErasePage(BANK1_WRITE_START_ADDR + (FMC_PAGE_SIZE * EraseCounter));
        FMC_ClearBitState(FMC_FLAG_EOP | FMC_FLAG_WERR | FMC_FLAG_PERR );
    }  
    FMC_Lock();
               
    /* Unlock the Flash Bank1 Program Erase controller */
    FMC_Unlock();
   
    /* Define the number of page to be erased */
    NbrOfPage = (BANK1_WRITE_END_ADDR - BANK1_WRITE_START_ADDR) / FMC_PAGE_SIZE;
   
    /* Clear All pending flags */
    FMC_ClearBitState(FMC_FLAG_EOP | FMC_FLAG_WERR | FMC_FLAG_PERR );   
        
    /* Program Flash Bank1 */
                Address = BANK1_WRITE_START_ADDR;
                for(save=0;save<Savenumber;save++)
                {        
    FMCStatus = FMC_ProgramWord(Address, backupData[save]);
                FMC_ClearBitState(FMC_FLAG_EOP | FMC_FLAG_WERR | FMC_FLAG_PERR );
                Address+=4;
                }
    FMC_Lock();

                for(n=0;n<3;n++){flashflag[n]=0;}
                reset=1;
         }
                flashdate=0;
         
        }

}
复制代码
串口DMA+IDLE中断接收数据
void USART1_IRQHandler(void)
{
          uint32_t tmp_flag = 0;
          uint32_t temp;
          tmp_flag=USART_GetIntBitState(USART1, USART_INT_IDLEF);
    if(tmp_flag!= RESET)
    {
                DMA_Enable(DMA1_CHANNEL5, DISABLE);
                                        temp = USART1->STR;
          temp = USART1->DR;
                                        temp= DMA_GetCurrDataCounter(DMA1_CHANNEL5);;
                                        Length=BufferSize-temp;
                            flag=1;
                                        DMA1_CHANNEL5->RCNT=BufferSize;
                            DMA_Enable(DMA1_CHANNEL5,ENABLE);
                         }  
    __nop();  
}

GD32F207ZE_BOOST_MPPT.rar (17.69 KB)
qiangg| | 2016-1-26 15:05 | 显示全部楼层
这应该给个精华吧

使用特权

评论回复
上山砍老虎| | 2016-1-26 15:31 | 显示全部楼层
谢谢分享,楼主确实是好人啊

使用特权

评论回复
ah9b87| | 2016-1-26 15:33 | 显示全部楼层
光伏很火的,那个锂电池的管理不错

使用特权

评论回复
paderboy|  楼主 | 2016-1-27 09:22 | 显示全部楼层
自己再顶下。。。多谢楼上各位的答复。。。

使用特权

评论回复
paderboy|  楼主 | 2016-2-5 10:58 | 显示全部楼层
自己再顶下。。

使用特权

评论回复
chuntian2016| | 2016-2-16 18:02 | 显示全部楼层
控制器的设计是非常必要的,这个挂席到光伏电池板的寿命。

使用特权

评论回复
LEDS| | 2016-2-16 23:21 | 显示全部楼层
楼主研究这个多久了。我用MEGA48做的控制器自己用了好几年了。

使用特权

评论回复
paderboy|  楼主 | 2016-2-17 09:15 | 显示全部楼层
本帖最后由 paderboy 于 2016-2-17 09:16 编辑
LEDS 发表于 2016-2-16 23:21
楼主研究这个多久了。我用MEGA48做的控制器自己用了好几年了。

我也用MEGA 168  和 MEGA 328 的做过,也用了几年了。。。。

使用特权

评论回复
shenmu2012| | 2016-2-18 11:48 | 显示全部楼层
采用DMA的功能可以提高AD转换效率的。

使用特权

评论回复
paderboy|  楼主 | 2016-2-18 16:28 | 显示全部楼层
shenmu2012 发表于 2016-2-18 11:48
采用DMA的功能可以提高AD转换效率的。

嗯,DMA ADC采样快很多。。。。

使用特权

评论回复
paderboy|  楼主 | 2016-3-8 21:56 | 显示全部楼层

使用特权

评论回复
LEDS| | 2016-3-8 23:34 | 显示全部楼层
那个显示屏是不是老杨那里买的.2块钱,真心便宜.
很想买上200片.银子不够,狠不下心来.

使用特权

评论回复
paderboy|  楼主 | 2016-3-9 08:41 | 显示全部楼层
LEDS 发表于 2016-3-8 23:34
那个显示屏是不是老杨那里买的.2块钱,真心便宜.
很想买上200片.银子不够,狠不下心来. ...

嗯,确实不错。。

使用特权

评论回复
baimiaocun2015| | 2016-3-9 22:40 | 显示全部楼层
看来这个设计还是挺复杂的么

使用特权

评论回复
paderboy|  楼主 | 2016-3-10 07:00 | 显示全部楼层
baimiaocun2015 发表于 2016-3-9 22:40
看来这个设计还是挺复杂的么

:loveliness:

使用特权

评论回复
jstel| | 2018-6-1 15:05 | 显示全部楼层
最近在学习MPPT    看到你的诚品   是否可以向你学习呢?
QQ:645218608
謝謝

使用特权

评论回复
戈卫东| | 2018-6-3 20:24 | 显示全部楼层
据说只要保持光电池输出电压在固定值就可以输出最大功率根本就不需要处理器那么麻烦。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

31

主题

352

帖子

5

粉丝