打印
[STM32F3]

与实际值相差如此大

[复制链接]
1029|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
morrisk|  楼主 | 2016-10-28 17:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用STM32F373 的SDADC采样,实测CPU端口上 VREFSD+ 为2.500V,PE8脚和PE9脚的电压分别为 2.292V 和 1.907V,输入模式为SDADC_InputMode_SEZeroReference,放大位数为1,
仿真显示 SDADC_Channel_7(PE9脚)的值为0x4877, SDADC_Channel_8(PE8脚)的值为0x617C,
而实际上根据实测电压值,采样值应为
1.907*65536/2.5 = 24995 = 0xc346
2.292*65536/2.5 = 60083 = 0xEAB3
与实际值相差如此大
沙发
小小猫咪| | 2016-10-28 17:26 | 只看该作者
换板子试了吗

使用特权

评论回复
板凳
morrisk|  楼主 | 2016-10-28 17:28 | 只看该作者
换了两块板也一样

使用特权

评论回复
地板
zwll| | 2016-10-28 17:30 | 只看该作者
楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因

使用特权

评论回复
5
morrisk|  楼主 | 2016-10-28 17:32 | 只看该作者

代码如下:
static uint32_t SDADC1_Config(void)
{
  SDADC_AINStructTypeDef SDADC_AINStructure;
  GPIO_InitTypeDef   GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  uint32_t SDADCTimeout = 0;
  
  /* MPX2102_SDADC APB2 interface clock enable */
  RCC_APB2PeriphClockCmd(MPX2102_SDADC_CLK, ENABLE);

  /* PWR APB1 interface clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
  /* Enable MPX2102_SDADC analog interface */
  PWR_SDADCAnalogCmd(MPX2102_SDADC_PWR, ENABLE);

  /* Set the SDADC divider: The SDADC should run @6MHz */
  /* If Sysclk is 72MHz, SDADC divider should be 12 */
  RCC_SDADCCLKConfig(RCC_SDADCCLK_SYSCLK_Div48);

  /* GPIOE Peripheral clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOE, ENABLE);

  /* MPX2102_SDADC channel 8P (PE8)  and channel 8N (PE9) */
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_Init(GPIOE, &GPIO_InitStructure);

  /* Select External reference: The reference voltage selection is available
     only in SDADC1 and therefore to select the VREF for SDADC2/SDADC3, SDADC1
     clock must be already enabled */
  SDADC_VREFSelect(SDADC_VREF_Ext);
  //SDADC_VREFSelect(SDADC_VREF_VDDA);
  //SDADC_VREFSelect(SDADC_VREF_VREFINT2);
  /* Insert delay equal to ~5 ms */
  delay(5);  //5ms
  
  /* Enable MPX2102_SDADC */
  SDADC_Cmd(MPX2102_SDADC, ENABLE);

  /* Enter initialization mode */
  SDADC_InitModeCmd(MPX2102_SDADC, ENABLE);
  SDADCTimeout = SDADC_INIT_TIMEOUT;
  /* wait for INITRDY flag to be set */
  //while((SDADC_GetFlagStatus(MPX2102_SDADC, SDADC_FLAG_INITRDY) == RESET) && (--SDADCTimeout != 0));
  while(SDADC_GetFlagStatus(MPX2102_SDADC, SDADC_FLAG_INITRDY) == RESET);

  if(SDADCTimeout == 0)
  {
    /* INITRDY flag is not set */
    return 1;
  }

  /* Analog Input configuration conf0: use differential mode and gain = 4 */
  //SDADC_AINStructure.SDADC_InputMode = SDADC_InputMode_Diff;
  SDADC_AINStructure.SDADC_InputMode = SDADC_InputMode_SEZeroReference;
  //SDADC_AINStructure.SDADC_InputMode = SDADC_InputMode_SEOffset;
  SDADC_AINStructure.SDADC_Gain = SDADC_Gain_1;
  SDADC_AINStructure.SDADC_CommonMode = SDADC_CommonMode_VSSA;
  //SDADC_AINStructure.SDADC_CommonMode = SDADC_CommonMode_VDDA_2;
  SDADC_AINStructure.SDADC_Offset = 0;
  SDADC_AINInit(MPX2102_SDADC, SDADC_Conf_0, &SDADC_AINStructure);

  /* select MPX2102_SDADC channel 8 to use conf0 */
  SDADC_ChannelConfig(MPX2102_SDADC, SDADC_Channel_8, SDADC_Conf_0);

  /* select channel 8 */
  SDADC_InjectedChannelSelect(MPX2102_SDADC, SDADC_Channel_8);
        SDADC_InjectedContinuousModeCmd(MPX2102_SDADC, ENABLE);
  /* Select an external trigger */
  //SDADC_ExternalTrigInjectedConvConfig(MPX2102_SDADC, SDADC_ExternalTrigInjecConv_T19_CC2);
  /* Select rising edge */
  //SDADC_ExternalTrigInjectedConvEdgeConfig(MPX2102_SDADC, SDADC_ExternalTrigInjecConvEdge_Rising);

  /* Exit initialization mode */
  SDADC_InitModeCmd(MPX2102_SDADC, DISABLE);

  /* Enable end of injected conversion interrupt */
  SDADC_ITConfig(MPX2102_SDADC, SDADC_IT_JEOC, ENABLE);

  /* NVIC Configuration */
  NVIC_InitStructure.NVIC_IRQChannel = SDADC1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  /* configure calibration to be performed on conf0 */
  SDADC_CalibrationSequenceConfig(MPX2102_SDADC, SDADC_CalibrationSequence_1);
  /* start MPX2102_SDADC Calibration */
  SDADC_StartCalibration(MPX2102_SDADC);
  /* Set calibration timeout: 5.12 ms at 6 MHz in a single calibration sequence */
  SDADCTimeout = SDADC_CAL_TIMEOUT;
  /* wait for MPX2102_SDADC Calibration process to end */
  //while((SDADC_GetFlagStatus(MPX2102_SDADC, SDADC_FLAG_EOCAL) == RESET) && (--SDADCTimeout != 0));
  while(SDADC_GetFlagStatus(MPX2102_SDADC, SDADC_FLAG_EOCAL) == RESET);

  if(SDADCTimeout == 0)
  {
    /* EOCAL flag can not set */
    return 2;
  }

        SDADC_SoftwareStartInjectedConv(MPX2102_SDADC);
  return 0;
}

void SDADC1_IRQHandler(void)
{
  uint32_t ChannelIndex;

  if(SDADC_GetFlagStatus(SDADC1, SDADC_FLAG_JEOC) != RESET)
  {
    /* Get the converted value */
    InjectedConvData = SDADC_GetInjectedConversionValue(SDADC1, &ChannelIndex);
                ChannelIndex = ChannelIndex;
  }
}

使用特权

评论回复
6
司徒老鹰| | 2016-10-28 17:34 | 只看该作者
计算公式不对

使用特权

评论回复
7
morrisk|  楼主 | 2016-10-28 17:37 | 只看该作者
正确的计算公式是什么呢

使用特权

评论回复
8
pengf| | 2016-10-28 17:38 | 只看该作者
这样算:
1.907*65536/2.5 - 32768 - OFFSET = 49990 - 32768 - OFFSET = 0x4347 - OFFSET
2.292*65536/2.5 - 32768 - OFFSET = 60083 - 32768 - OFFSET = 0x6AB3 - OFFSET
OFFSET在校准结果里找

使用特权

评论回复
9
supernan| | 2016-10-28 17:40 | 只看该作者
我看了下官方例程,也要减去32768,可是减去32768的原理是什么,求解。

使用特权

评论回复
10
栩栩如生| | 2016-10-28 17:41 | 只看该作者
SDADC的其他两种采集模式又是怎样的计算公式呢,是否还要减去这个32768???

使用特权

评论回复
11
liuzaiy| | 2016-10-28 17:43 | 只看该作者
SDADC的采样周期计算公式是什么呢?

使用特权

评论回复
12
yinxiangh| | 2016-10-28 17:45 | 只看该作者
也就是用SDADC采集一个完整的数据需要多少个SDADC_CLK。。。

使用特权

评论回复
13
huangchui| | 2016-10-28 17:49 | 只看该作者
  你的这个中断函数读取的对吗   我配置的读取到都是-32768  不知道什么问题

使用特权

评论回复
14
pangb| | 2016-10-28 17:51 | 只看该作者
请问你的stm32f373用的什么仿真器?还有ulink2可以吗?

使用特权

评论回复
15
morrisk|  楼主 | 2016-10-28 17:54 | 只看该作者
搞定了,呵呵,犯了低级错误……结贴啦,多谢各位

使用特权

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

本版积分规则

701

主题

6879

帖子

2

粉丝