采集模擬量數據在一台一起中是必不可少的功能。在本次實驗中我們要采集的模擬量值主要包括氧氣傳感器的輸出以及壓力變送器的輸出。
1硬件設計
我們需要采集數據對精度有一定的要求,而STM32L476自帶ADC為12位的,所以我們采用獨立的ADC芯片來完成這一工作。由於使用經驗的關系,我們選擇了AD7705芯片。
AD7705為完整16位、低成本、Σ-Δ型ADC,適合直流和低頻交流測量應用。其具有低功耗(3 V時最大值為1 mW)特性,因而可用於環路供電、電池供電或本地供電的應用中。片內可編程增益放大器提供從1至128的增益設置,無需使用外部信號調理硬件便可接受低電平和高電平模擬輸入。AD7705擁有兩個差分通道,對外通訊支持SPI接口方式。其結構圖如下:
在STM32L476RG開發板中,有SPI3口已經引到端子可以使用。各引腳分別為:
CN7-1 PC10 SPI3-SCK
CN7-2 PC11 SPI3-MISO
CN7-3 PC12 SPI3-MOSI
在開發板上的位置如下紅框標識:
根據以上描述,於是我們設計電路圖如下:
2、軟件設計
完成硬件連接后我們可以開始軟件開發了,首先我們在STM32CubeMX中對硬件部分進行配置。由於板子上沒有焊接X3外部晶振,我們使用內部時鍾源。使用SPI3的引腳PC10,PC11,PC12,如下圖所示:
然后配置SPI3的的參數,我們采用7為數據,大端以及64分頻,具體的參數配置如下圖所示:
對應的SPI3端口的配置程序如下所示:
static void SPI3_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接口讀取摸你臉個采集值得程序。
/*獲取采集的物理量值,並作平滑處理*/
void GetMeasuredValue(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 void CalcMeasuredValue(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_t SPIReadWriteByte(uint8_t data) { uint8_t rxData=0; HAL_SPI_TransmitReceive(&hspi3,&data,&rxData,1,1000); return rxData; }
/*檢查數據是否准備好*/
static uint8_t CheckDataIsReady(void) { return (uint8_t)HAL_GPIO_ReadPin (GPIOB,GPIO_PIN_7); }
3、測試結果
程序下裝后,運行正常可一看到2個通道的采集數據。如下圖所示:
我們在測試時,采集了兩個傳感器輸出,在實際使用時,我們只需要一路接傳感器,而另外一路我們采集鋰電池的電壓信號。