STM32/STM8技术论坛
直播中

尹家军

10年用户 405经验值
擅长:MEMS/传感技术 测量仪表 嵌入式技术 接口/总线/驱动 控制/MCU
私信 关注
[经验]

【STM32L476 Nucleo试用体验】模拟量数据采集


采集模拟量数据在一台一起中是必不可少的功能。在本次实验中我们要采集的模拟量值主要包括氧气传感器的输出以及压力变送器的输出。

1硬件设计

我们需要采集数据对精度有一定的要求,而STM32L476自带ADC12位的,所以我们采用独立的ADC芯片来完成这一工作。由于使用经验的关系,我们选择了AD7705芯片。

AD7705为完整16位、低成本、Σ-ΔADC,适合直流和低频交流测量应用。其具有低功耗(3 V时最大值为1 mW)特性,因而可用于环路供电、电池供电或本地供电的应用中。片内可编程增益放大器提供从1128的增益设置,无需使用外部信号调理硬件便可接受低电平和高电平模拟输入。AD7705拥有两个差分通道,对外通讯支持SPI接口方式。其结构图如下:

2-1.png

STM32L476RG开发板中,有SPI3口已经引到端子可以使用。各引脚分别为:

CN7-1         PC10            SPI3-SCK

CN7-2         PC11            SPI3-MISO

CN7-3         PC12            SPI3-MOSI

在开发板上的位置如下红框标识:

2-2.jpg

根据以上描述,于是我们设计电路图如下:

2-3.png

2、软件设计

完成硬件连接后我们可以开始软件开发了,首先我们在STM32CubeMX中对硬件部分进行配置。由于板子上没有焊接X3外部晶振,我们使用内部时钟源。使用SPI3的引脚PC10PC11PC12,如下图所示:

2-4.png

然后配置SPI3的的参数,我们采用7为数据,大端以及64分频,具体的参数配置如下图所示:

2-5.png

对应的SPI3端口的配置程序如下所示:

static voidSPI3_Configuration(void)

{


  hspi3.Instance = SPI3;

  hspi3.Init.Mode = SPI_MODE_MASTER;

  hspi3.Init.Direction = SPI_DIRECTION_2LINES;

  hspi3.Init.DataSize = SPI_DATASIZE_8BIT;

  hspi3.Init.CLKPolarity = SPI_POLARITY_LOW;

  hspi3.Init.CLKPhase = SPI_PHASE_1EDGE;

  hspi3.Init.NSS = SPI_NSS_SOFT;

  hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;

  hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB;

  hspi3.Init.TIMode = SPI_TIMODE_DISABLE;

  hspi3.Init.CRCCalculation =SPI_CRCCALCULATION_DISABLE;

  hspi3.Init.CRCPolynomial = 7;

  if (HAL_SPI_Init(&hspi3) != HAL_OK)

  {

    Error_Handler();

  }


}

接下来我们实现通过SPI3接口读取摸你脸个采集值得程序。

/*获取采集的物理量值,并作平滑处理*/

voidGetMeasuredValue(void)

{

  float currentValue[2]={-1.0,-1.0};

  CalcMeasuredValue(currentValue);

    if(smoothIndex>=SmoothCount)

  {

    smoothIndex=0;

  }

  

aPara.phyPara.o2Concentration=SmoothingFilter(currentValue[0],AD1Value,smoothIndex,SmoothCount,(O2RANGE-O2ZERO),2.0,0.2);

aPara.phyPara.h2Concentration=SmoothingFilter(currentValue[1],AD2Value,smoothIndex,SmoothCount,(H2RANGE-H2ZERO),2.0,0.2);

  

  smoothIndex++;

}


/*计算测量值,将AD转换的值转为物理量的对应值*/

static voidCalcMeasuredValue(float *newValue)

{

  uint16_t measuredValue=0;

  

  /*转化通道1的值*/

  ADDA_AD7705_ENABLE();//使能器件

  Delayus(200);

measuredValue=GetAD7705ChannelValue(Channel1,SPIReadWriteByte,CheckDataIsReady);

  ADDA_AD7705_DISABLE();//片选取消

newValue[0]=PowerNPolyfit(((float)(measuredValue-AD1Zero)/(float)(AD1Scale-AD1Zero)),ADFactor[0],3)*(O2RANGE-O2ZERO)+O2ZERO;

  Delayms(1);

  

  /*转化通道2的值*/

  ADDA_AD7705_ENABLE();//使能器件

  Delayus(200);

measuredValue=GetAD7705ChannelValue(Channel2,SPIReadWriteByte,CheckDataIsReady);

  ADDA_AD7705_DISABLE();//片选取消

newValue[1]=PowerNPolyfit(((float)(measuredValue-AD2Zero)/(float)(AD2Scale-AD2Zero)),ADFactor[1],3)*(H2RANGE-H2ZERO)+H2ZERO;

  Delayms(1);

}


/*SPI端口读写一个字节*/

static uint8_tSPIReadWriteByte(uint8_t data)

{

  uint8_t rxData=0;

  

HAL_SPI_TransmitReceive(&hspi3,&data,&rxData,1,1000);

  

  return rxData;

}


/*检查数据是否准备好*/

static uint8_tCheckDataIsReady(void)

{

  return (uint8_t)HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_7);

}


3、测试结果

程序下装后,运行正常可一看到2个通道的采集数据。如下图所示:

2-6.png

我们在测试时,采集了两个传感器输出,在实际使用时,我们只需要一路接传感器,而另外一路我们采集锂电池的电压信号。

回帖(3)

王栋春

2017-9-21 22:15:14
非常经典的知识分享
举报

CHNlyt

2017-9-22 12:57:19
好资料,学习学习。。。。
举报

李泉胜

2018-8-31 06:37:10
谢谢分享!学习学习!
举报

更多回帖

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