搜索

[研电赛技术支持] STM32F030移植到GD32E230上时ADC采到的值为0

[复制链接]
260|6
 楼主 | 2021-1-27 15:41 | 显示全部楼层 |阅读模式
如题,之前我也在论坛里问过,也有很多人大佬帮忙解答了,大致为GD32E230不兼容STM32F030的ADC,但是兼容STM32F103的ADC,解决办法是将STM32F1的stm32f10x_adc.H和.C的内容复制到F0的stm32f0xx_adc.H和.C之中将ADC2和3屏蔽,然后在stm32f0xx.h中将f0的寄存器改为f1的,再将ADC配置改为F1的,大致就是这样,但是改完之后发现程序会死在while(ADC_GetResetCalibrationStatus(ADC1));ADC复位校准部分,而屏蔽掉RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);ADC时钟使能后倒是可以通过,但是理所应当的数据依然为0,所以想请问问各位有没有遇到过,帮忙解个惑,还有这是我这是自己的硬件,没有使用GD的开发板,没有外挂晶振,用的内部震荡,不知道会不会影响

使用特权

评论回复
| 2021-1-27 16:37 | 显示全部楼层
本帖最后由 sonicll 于 2021-1-27 16:42 编辑

可能是ADC时钟配置的问题?你系统时钟配的多少,ADC的分频怎么配的?

使用特权

评论回复
 楼主 | 2021-1-27 18:06 | 显示全部楼层
本帖最后由 15125413637 于 2021-1-27 18:07 编辑

void ADC1_DMA_Init(void)
{

  ADC_InitTypeDef     ADC_InitStruct;
  DMA_InitTypeDef     DMA_InitStruct;
        GPIO_InitTypeDef    GPIO_InitStruct;
          /* ADC1 DeInit */  
//                Delay_init1(72);


        /* Enable  GPIOA clock */
          RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);
  /* ADC1 Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  /* DMA1 clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
        ADC_DeInit(ADC1);
  /* Configure PA.01  as analog input */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
       
//  GPIO_Init(GPIOB, &GPIO_InitStruct);                                // PA1,输入时不用设置速率

        /* Enable  GPIOB clock */
        RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
        GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ;
        GPIO_InitStruct.GPIO_Speed =GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStruct);                                // PA1,输入时不用设置速率


  /* DMA1 Channel1 Config */
  DMA_DeInit(DMA1_Channel1);                                                                                                                                                                //将DMA的通道1寄存器重设为缺省值
  DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;//DMA外设ADC基地址
  DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&ADC1ConvertedValue;//DMA内存基地址
  DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;                                                                                //内存作为数据传输的目的地
  DMA_InitStruct.DMA_BufferSize =adc_tested_times*adc_chanal_data;        //DMA通道的DMA缓存的大小
  DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                 //外设地址寄存器不变
  DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable;                                                        //内存地址寄存器递增
  DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为16位
  DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;                                //数据宽度为16位
  DMA_InitStruct.DMA_Mode = DMA_Mode_Circular;                                                                                                                //工作在循环缓存模式
  DMA_InitStruct.DMA_Priority = DMA_Priority_High;                                                                                                //DMA通道 x拥有高优先级
  DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;                                                                                                                                //DMA通道x没有设置为内存到内存传输
  DMA_Init(DMA1_Channel1, &DMA_InitStruct);                                                                                                                                //根据DMA_InitStruct中指定的参数初始化DMA的通道

  /* DMA1 Channel1 enable */
  DMA_Cmd(DMA1_Channel1, ENABLE);                                                                                                                                                                        //启动DMA通道



  /* Initialize ADC structure */
  ADC_StructInit(&ADC_InitStruct);

  /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
//  ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b;
        ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;                        //独立工作模式
        ADC_InitStruct.ADC_ScanConvMode =ENABLE;        //模数转换工作在扫描模式
  ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; //模数转换工作在连续转换模式
         ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;       //由软件触发启动
  ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;                                                                                        //ADC数据右对齐
        ADC_InitStruct.ADC_NbrOfChannel = adc_chanal_data;        //顺序进行规则转换的ADC通道的数目
  ADC_Init(ADC1, &ADC_InitStruct);


  /* Convert the ADC1 Vref  with 55.5 Cycles as sampling time */

       
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5);       
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5);       
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239Cycles5);       
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_239Cycles5);       
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_239Cycles5);       
ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 6, ADC_SampleTime_239Cycles5);       
ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 7, ADC_SampleTime_239Cycles5);       
ADC_RegularChannelConfig(ADC1, ADC_Channel_7, 8, ADC_SampleTime_239Cycles5);       
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 9, ADC_SampleTime_239Cycles5);       
       
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //72M/6=12,ADC最大时间不能超过14M      

         /* Enable ADC1 DMA */          
  ADC_DMACmd(ADC1, ENABLE);
        /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
//                Delay_us1(1000);
        printf("\r\1111111111\r\n");
        /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);        //启用ADC1复位校准寄存器
        /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));   //等待ADC1复位校准
        printf("\r\2222222222\r\n");
        /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1);        //启动ADC1校准                                               
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1)); //等待ADC1校准  

  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);//开始ADC1软件转换
//        ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
}

使用特权

评论回复
 楼主 | 2021-1-27 18:08 | 显示全部楼层
sonicll 发表于 2021-1-27 16:37
可能是ADC时钟配置的问题?你系统时钟配的多少,ADC的分频怎么配的?

配置在下一楼

使用特权

评论回复
| 2021-1-28 12:03 | 显示全部楼层
我全部重新按GD的库文件改了,不过还没有下载代码,JLINK没连上,技术支持不建议按你这种方式移植

使用特权

评论回复
| 2021-1-28 15:03 | 显示全部楼层
楼主我找到你的问题了,E230的ADC时钟源配置,和STM32F1的不一样,在RCU_CFG2寄存器里的第8bit,还要配置用APB时钟还是内部28M时钟,这个寄存器在ST的库里是RCC->CFGR3,在你代码配置ADC时钟的地方再添加一句:

RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //72M/6=12,ADC最大时间不能超过14M  
RCC->CFGR3 |= 0x0100;

添加这个操作应该就可以了

使用特权

评论回复
 楼主 | 2021-1-29 14:44 | 显示全部楼层
sonicll 发表于 2021-1-28 15:03
楼主我找到你的问题了,E230的ADC时钟源配置,和STM32F1的不一样,在RCU_CFG2寄存器里的第8bit,还要配置用 ...

感谢老哥,成功了,好人一生平安

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 我要提问 投诉建议 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表