一、芯片介紹
AD7124是一款適合高精度測(cè)量應(yīng)用的低功耗、低噪聲、完整模擬前端。該器件內(nèi)置一個(gè)低噪聲24位Σ-Δ型模數(shù)轉(zhuǎn)換器(ADC),可配置來(lái)提供8個(gè)差分輸入或15個(gè)單端或偽差分輸入。片內(nèi)低噪聲級(jí)確保ADC中可直接輸入小信號(hào)??捎糜跍囟葴y(cè)量、壓力測(cè)量、工業(yè)過(guò)程控制、儀器儀表和只能發(fā)射器。
二、引腳排布
AD7124的接口屬于標(biāo)準(zhǔn)4線SPI,DOUT是從設(shè)備輸出至主設(shè)備的,連接單片機(jī)SPI模塊的MISO(主輸入從輸出);DIN是主設(shè)備數(shù)據(jù)輸出至從設(shè)備的,連接單片機(jī)SPI模塊的MOSI(主輸出從輸入)。SYNC和CLK懸空。
本項(xiàng)目我們使用SPI2模塊。
三、時(shí)序圖與驅(qū)動(dòng)程序
調(diào)試數(shù)字設(shè)備,我們需要一邊查看技術(shù)手冊(cè)的時(shí)序圖寫代碼,一邊掛上邏輯分析儀。
1. 芯片初始化
我們打開AD7124的DataSheet,對(duì)其時(shí)序圖進(jìn)行分析,如下:
下圖為AD7124的單次和連續(xù)轉(zhuǎn)換時(shí)序圖,由圖可知,SCLK在空閑狀態(tài)下是高電平。
下圖是AD7124的讀&寫時(shí)序圖,無(wú)論是讀時(shí)序還是寫時(shí)序,均在第二個(gè)時(shí)鐘沿進(jìn)行數(shù)據(jù)轉(zhuǎn)換。
所以AD7124初始化時(shí),需要將SPI模式設(shè)置為時(shí)鐘懸空高、數(shù)據(jù)捕獲于第2個(gè)時(shí)鐘沿
void AD7124_SPI_Config(void)
{
SPI_InitTypeDef SPI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_12);
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //SPI主機(jī)
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //發(fā)送接收8位幀結(jié)構(gòu)
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //時(shí)鐘懸空高
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; //數(shù)據(jù)捕獲于第2個(gè)時(shí)鐘沿
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; //NSS信號(hào)由軟件控制
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定義波特率預(yù)分頻的值:波特率預(yù)分頻值為256
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //數(shù)據(jù)傳輸從MSB位開始
SPI_InitStructure.SPI_CRCPolynomial = 0; //CRC值計(jì)算的多項(xiàng)式
SPI_Init(SPI2, &SPI_InitStructure); //根據(jù)SPI_InitStruct中指定的參數(shù)初始化外設(shè)SPIx寄存器
SPI_Cmd(SPI2, ENABLE);
AD7124_CS_H; //片選拉高,失能AD7124
}
2. SPI讀寫函數(shù)
SPI讀寫是驅(qū)動(dòng)SPI設(shè)備的基礎(chǔ)。SPI的原理為
第一步:通過(guò)硬件或軟件NSS拉低從設(shè)備片選(CS),使能從設(shè)備。
第二步:通過(guò)MOSI引腳,發(fā)送8個(gè)時(shí)鐘周期,每個(gè)周期發(fā)送1個(gè)bit的數(shù)據(jù);通過(guò)寫入不同的地址,來(lái)決定對(duì)從設(shè)備的讀操作/寫操作。
第三步:8個(gè)倍數(shù)的時(shí)鐘周期發(fā)送完畢后,拉高片選,結(jié)束“發(fā)送/接收數(shù)據(jù)”。
這里我們把讀和寫都放在一個(gè)函數(shù)里面,因?yàn)镾PI如果只讀取,都需要發(fā)送8個(gè)時(shí)鐘周期和指令0XFF。
/**
* @brief AD7124的讀寫SPI操作
* @param Data : 需要傳輸?shù)臄?shù)據(jù)
* @retval SPI讀到的數(shù)據(jù)
*/
uint8_t AD7124_SPI_ReadWrite(uint8_t Data)
{
uint16_t retry=0;
//超時(shí)等待
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
{
retry++;
if(retry>200)return 0;
}
SPI_I2S_SendData(SPI2, Data); //MOSI主機(jī)發(fā)送給從機(jī)
retry=0;
while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
{
retry++;
if(retry>200)return 0;
}
return SPI_I2S_ReceiveData(SPI2); //MISO接收從機(jī)數(shù)據(jù)
}
3. AD7124復(fù)位
芯片上電初始化前,必須復(fù)位才能使用。
CS = 0 和 DIN = 1 的 64 個(gè) SCLK。這會(huì)復(fù)位 ADC 和所有寄存器內(nèi)容。也就是說(shuō),只要在AD7124 CS拉低的期間,在64個(gè)時(shí)鐘周期內(nèi)MOSI不斷輸出高電平,即可復(fù)位。代碼如下:
void AD7124_Reset(void)
{
AD7124_CS_L;
//提供大于64個(gè)寫操作,復(fù)位AD7124
for(uint8_t a=0; a<9; a++)
{
AD7124_SPI_ReadWrite(0XFF); //MOSI拉高
}
delay_us(60);
AD7124_CS_H;
}
加入延時(shí)delay_us()的目的是,防止在硬件SPI還未發(fā)送完最后幾個(gè)時(shí)鐘周期,CS提前拉高,造成復(fù)位失敗。在讀寫操作中,同樣加入了延時(shí)處理。
邏輯分析儀采集到的波形如下:
AD7124讀取ID
復(fù)位完成后需要讀取芯片的ID號(hào),不同封裝的ID號(hào)也不同,AD7124-4通常為0x14,而AD7124-8是0x12或0x04。SPI寫入命令0x40為讀寄存器,讀ID為0x05,故寫入0x45就可以讀出ID。
0x40是發(fā)送讀取ID指令返回的字節(jié),0x14是ID號(hào)。
AD7124寫入配置
寫入配置需要根據(jù)寫時(shí)序圖編寫,讀時(shí)序如下
我們復(fù)位后先對(duì)ADC_CTRL進(jìn)行操作,以開啟ADC控制寄存器,AD7124_ADC_CTRL_REG地址是0X01,如下圖DIN的第一個(gè)Byte,之后再把2字節(jié)的配置信息依次寫入,這個(gè)根據(jù)用戶需求配置,不在贅述。
通道和內(nèi)置濾波器配置方法相同。
讀取數(shù)據(jù)
本次實(shí)驗(yàn)我們采用單次讀取模式。在讀取數(shù)據(jù)之前先要寫入命令0x42,之后需要讀取多少個(gè)Byte的字節(jié),就修改形式參數(shù)byte的數(shù)量即可。讀取一次單次采集到的數(shù)據(jù),需要3次SPI讀寫(24個(gè)時(shí)鐘周期),DIN輸出全高即可讀取。
uint32_t DATA=0;
uint32_t Rd_Ary[3];
uint32_t AD7124_Read_Data(uint8_t byte)
{
for(uint8_t i=0; i<byte; i++)
{
Rd_Ary[i] = AD7124_SPI_ReadWrite(0xFF);
}
DATA = (Rd_Ary[0]<<16) + (Rd_Ary[1]<<8) + Rd_Ary[2];
return DATA;
}
主函數(shù)讀取代碼如下:
while(1)
{
AD7124_CS_L;
AD7124_SPI_ReadWrite(0x42); //讀操作
Data = AD7124_Read_Data(3); //Data采集結(jié)果
AD7124_CS_H;
data_temp = Data;
data_last1 = (float)Vref/AD_Gain * (float)data_temp/(2*0X800000); //單極性模式電壓轉(zhuǎn)換公式,單位mV
// data_last1 = (float)Vref/AD_Gain * ((float)data_temp/0X800000-1); //雙極性模式電壓轉(zhuǎn)換公式,單位mV
data_last1 = data_last1 * 1000.0f; //轉(zhuǎn)換為uV
printf("%X\r\n", Data); //打印原始16進(jìn)制數(shù)據(jù)
printf("%2f uV\r\n", data_last1); //打印微伏
delay_ms(100);
}
讓我們采集11mV的直流信號(hào),下圖分別為實(shí)際測(cè)量和邏輯分析儀讀取到的數(shù)據(jù),為0x928D11。
為了驗(yàn)證數(shù)據(jù)是否正確,我們查看此次串口讀取到的值:
原16進(jìn)制數(shù)據(jù)讀取正確,萬(wàn)用表實(shí)際測(cè)量11.0mV,實(shí)際讀取值為11.180mV,誤差在±100~200uV。因?yàn)樾盘?hào)發(fā)生器的線過(guò)長(zhǎng),影響了此次的精度。在PCB Layout時(shí),盡可能將ADC輸入的線路縮短,且圓弧布線,可以有效降低誤差。
資料鏈接
代碼可以在此處下載:文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-471955.html
鏈接: https://download.csdn.net/download/m0_46369352/85612772文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-471955.html
到了這里,關(guān)于STM32的硬件SPI驅(qū)動(dòng)AD7124的方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!