单片机学习小组
直播中

laisvl

8年用户 1087经验值
私信 关注

怎样去使用GD32F130去开发项目呢

怎样去使用GD32F130去开发项目呢?有哪些使用步骤?

回帖(1)

李晟才

2022-2-17 14:39:25
一、选开发库

从芯片角度看,硬件上是PIN2PIN的,GD32F130外设地址设计是参考STM32F030,但STM32F030是M0内核,GD32F130是M3内核,时钟也可以到72M,多了APB2总线等。所以考虑用STM32F030的库来改写,本次实验采用的是STM32F0xx_DFP.1.5.0版本。
二、使用步骤

1.安装pack包和配置

从GD官网下载编译器芯片支持包:GigaDevice.GD32F1x0_DFP.3.2.0.pack
然后找一个原先用STM32f030做过的项目模板,配置一下编译环境。
Device选项里选择GD的对应的具体芯片,本次用的是130C8系列,效果图如下:

工程架构如下,继续采用ST的系统,如下

启动文件startup_stm32f0xx.s可以不用修改,直接使用。
系统文件system_stm32f0xx.c可以简单修改,主要是SetSysClock()函数,
主频提高到72MHz,

CC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL6 )


改为


RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLMULL9 )


另外增加APB2 配置,


        /* PCLK2 = HCLK */
    RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;           


后面发现以上几项参数不修改也可以直接使用。


2.项目编译和功能debug
现在直接编译后下载到芯片,发现GPIO,串口,PWM, 软件I2C(为代码通用性一些低速的通讯都采用软件模拟方式)等功能都能正常使用了。但ADC无法工作,表现为程序卡住,后debug发现是查询ADC转换是否完成始终没返回,


while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));


后需仔细核对后,发现虽然GD32F130的ADC内存地址段(0x40012400-0x400127ff)和STM32F030是一致的,但各个具体寄存器定义的状态和标志位还是不一样的,例如ADC_FLAG_EOC,ADCx->DR,ADC_CHANNEL定义都不一致。甚至宏定义ADC_BASE都不一样,在STM库里要用ADC1_BASE这个宏,前面这么顺利,这个地方轻敌了,debug了很久,被坑了一把…


最后参考了GD32F130的官方库中ADC内容,抽取出部分必要的内容,导入到现项目中,终于把ADC功能模块搞定。


具体参考代码如下
头文件增加内容


//
//for GD130
#define gdREG32(addr)       (*(volatile uint32_t *)(uint32_t)(addr))
#define gdBIT(x)            ((uint32_t)((uint32_t)0x01U<<(x)))
#define gdBITS(start, end)  ((0xFFFFFFFFUL << (start)) & (0xFFFFFFFFUL >> (31U - (uint32_t)(end))))


#define        gdADC_STAT                        gdREG32(0x40012400U)
#define gdADC_CTL1                         gdREG32(0x40012408U)
#define gdADC_RDATA                        gdREG32(0x4001244CU)


#define gdADC_RSQ0                 gdREG32(0x4001242CU)            
#define gdADC_RSQ1          gdREG32(0x40012430U)           
#define gdADC_RSQ2          gdREG32(0x40012434U)  
#define gdADC_SAMPT0        gdREG32(0x4001240CU)            
#define gdADC_SAMPT1        gdREG32(0x40012410U)     




#define gdADC_CTL1_ADCON    gdBIT(0)  
#define gdADC_CTL1_CLB                gdBIT(2)                           
#define gdADC_CTL1_RSTCLB        gdBIT(3)                           
#define gdADC_CTL1_SWRCST          gdBIT(22)                             


#define gdADC_FLAG_EOC                gdBIT(1)


/* gd_ADC channel definitions */
#define gdADC_CHANNEL_0                   ((uint8_t)0x00U)                  
#define gdADC_CHANNEL_1                   ((uint8_t)0x01U)                  
#define gdADC_CHANNEL_2                   ((uint8_t)0x02U)                  
#define gdADC_CHANNEL_3                   ((uint8_t)0x03U)                  
#define gdADC_CHANNEL_4                   ((uint8_t)0x04U)                  
#define gdADC_CHANNEL_5                   ((uint8_t)0x05U)                  
#define gdADC_CHANNEL_6                   ((uint8_t)0x06U)                  
#define gdADC_CHANNEL_7                   ((uint8_t)0x07U)                  
#define gdADC_CHANNEL_8                   ((uint8_t)0x08U)                  
#define gdADC_CHANNEL_9                   ((uint8_t)0x09U)                  
#define gdADC_CHANNEL_10                  ((uint8_t)0x0AU)                  
#define gdADC_CHANNEL_11                  ((uint8_t)0x0BU)                  
#define gdADC_CHANNEL_12                  ((uint8_t)0x0CU)                  
#define gdADC_CHANNEL_13                  ((uint8_t)0x0DU)                  
#define gdADC_CHANNEL_14                  ((uint8_t)0x0EU)                  
#define gdADC_CHANNEL_15                  ((uint8_t)0x0FU)                  
#define gdADC_CHANNEL_16                  ((uint8_t)0x10U)                  
#define gdADC_CHANNEL_17                  ((uint8_t)0x11U)                  
#define gdADC_CHANNEL_18                  ((uint8_t)0x12U)                    


/* adc_samptx register value */
#define gdSAMPTX_SPT(regval)              (gdBITS(0,2) & ((uint32_t)(regval) << 0))
#define gdADC_SAMPLETIME_1POINT5          gdSAMPTX_SPT(0)                     
#define gdADC_SAMPLETIME_7POINT5          gdSAMPTX_SPT(1)                     
#define gdADC_SAMPLETIME_13POINT5         gdSAMPTX_SPT(2)                     
#define gdADC_SAMPLETIME_28POINT5         gdSAMPTX_SPT(3)                     
#define gdADC_SAMPLETIME_41POINT5         gdSAMPTX_SPT(4)                  
#define gdADC_SAMPLETIME_55POINT5         gdSAMPTX_SPT(5)                     
#define gdADC_SAMPLETIME_71POINT5         gdSAMPTX_SPT(6)                       
#define gdADC_SAMPLETIME_239POINT5        gdSAMPTX_SPT(7)                     


#define gdADC_RSQX_RSQN                   gdBITS(0,4)                          
#define gdADC_RSQ0_RL                     gdBITS(20,23)                        
#define gdADC_SAMPTX_SPTN                 gdBITS(0,2)                          




///
...
void  gdADC_Init(void);
u16 gdGet_Adc(uint8_t ch);        


在源文件中添加,




void gdadc_enable(void)
{
    if(RESET == (gdADC_CTL1 & gdADC_CTL1_ADCON)){
        gdADC_CTL1 |= (uint32_t)gdADC_CTL1_ADCON;
    }
}




void gdadc_disable(void)
{
    gdADC_CTL1 &= ~((uint32_t)gdADC_CTL1_ADCON);
}


void gdADC_StartOfConversion()
{
  gdADC_CTL1 |= gdADC_CTL1_SWRCST;
}


uint16_t gdADC_GetConversionValue()
{
        return ((uint16_t)gdADC_RDATA);
}




void gdadc_flag_clear(uint32_t flag)
{
    gdADC_STAT &= ~((uint32_t)flag);
}


void gdadc_calibration_enable(void)
{
    gdADC_CTL1 |= (uint32_t) gdADC_CTL1_RSTCLB;
    while((gdADC_CTL1 & gdADC_CTL1_RSTCLB)){
    }


    gdADC_CTL1 |= gdADC_CTL1_CLB;
    while((gdADC_CTL1 & gdADC_CTL1_CLB)){
    }
}




void gdadc_regular_channel_config(uint8_t channel, uint32_t sample_time)
{
    uint32_t rsq,sampt;
   
#ifdef GD32F130_150
    if(gdADC_CHANNEL_18 == channel){
        channel = gdADC_CHANNEL_0;
    }
#endif
   
        rsq = gdADC_RSQ2;
        rsq &=  ~((uint32_t)gdADC_RSQX_RSQN);
        rsq |= ((uint32_t)channel );
        gdADC_RSQ2 = rsq;
  
    if(channel < 10U){
        sampt = gdADC_SAMPT1;
        sampt &= ~((uint32_t)(gdADC_SAMPTX_SPTN << (3U*channel)));
        sampt |= (uint32_t)(sample_time << (3U*channel));
        gdADC_SAMPT1 = sampt;
    }else if(channel < 18U){
        sampt = gdADC_SAMPT0;
        sampt &= ~((uint32_t)(gdADC_SAMPTX_SPTN << (3U*(channel-10U))));
        sampt |= (uint32_t)(sample_time << (3U*(channel-10U)));
        gdADC_SAMPT0 = sampt;
    }else{
  
    }
}


void  gdADC_Init(void)
{        
        ADC_InitTypeDef ADC_InitStructure;
        GPIO_InitTypeDef GPIO_InitStructure;


        RCC_ADCCLKConfig(RCC_ADCCLK_PCLK_Div4);
       
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);         
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
                     
        GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0 | GPIO_Pin_1;  
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;       
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
        GPIO_Init(GPIOA, &GPIO_InitStructure);       


        ADC_DeInit(ADC1);  
   
        ADC_StructInit(&ADC_InitStructure);
       
        //ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;  //not support
        ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                
        ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;       
        ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;       
        ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;       
        ADC_Init(ADC1, &ADC_InitStructure);          
       
        ADC_Cmd(ADC1, ENABLE);       
        //gdadc_enable(); //OK also
        delay_ms(1);
        gdadc_calibration_enable();


}       


u16 gdGet_Adc(uint8_t ch)
{         
        u16 ValResult=0;
       
        gdadc_regular_channel_config(ch,gdADC_SAMPLETIME_55POINT5);


        gdADC_StartOfConversion();               
        gdADC_StartOfConversion();        //a bug here related to trigger config above


        while(!ADC_GetFlagStatus(ADC1, gdADC_FLAG_EOC));


        ValResult = gdADC_GetConversionValue();


        gdadc_flag_clear(gdADC_FLAG_EOC);
                       
        return ValResult;       
}           


在main()中ADC测试OK


        ....
        gdADC_Init();
    while(1)
        {   
                delay_ms(1000);
                adc_value =        gdGet_Adc(gdADC_CHANNEL_0);       
                printf("ADC0= %drn", adc_value);
        }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分