SPI原理
SPI協(xié)議詳解(圖文并茂+超詳細(xì))
SPI超詳細(xì)解析
【STM32筆記】HAL庫(kù)中的SPI傳輸(可利用中斷或DMA進(jìn)行連續(xù)傳輸)
AD5421芯片了解
AD5421是一款集成器件,設(shè)計(jì)用于環(huán)路供電型4-20mA智能發(fā)射器應(yīng)用。AD5421在單芯片內(nèi)提供如下特性和功能:16位DAC和電流放大器,用于對(duì)環(huán)路電流進(jìn)行數(shù)字控制;用于為整個(gè)發(fā)射器供電的穩(wěn)壓器;基準(zhǔn)電壓源;故障報(bào)警功能;靈活的SPI兼容型串行接口;增益和失調(diào)調(diào)整寄存器;以及其它特性和功能。
AD5421為四線制信號(hào)芯片,這四個(gè)信號(hào)線分別為MISO、MOSI、CS、SCLK,即主入從出、主出從入、片選、時(shí)鐘。片選信號(hào)線在有的地方也稱SS,其是由主設(shè)備控制的,用來(lái)確定從機(jī)且低電平有效。當(dāng)編寫程序時(shí),通常采用GPIO模擬片選信號(hào)(人為拉低pin電平)。
在本文,需要利用AD5421實(shí)現(xiàn)寫入和讀取數(shù)據(jù)的功能,首先通過芯片手冊(cè)可以看到,實(shí)現(xiàn)寫入功能的第八位是0,讀取是1。
數(shù)據(jù)格式為8位命令+16位數(shù)據(jù)(+8位CRC循環(huán)校驗(yàn))
AD5421數(shù)據(jù)傳輸時(shí)序圖如下圖所示,當(dāng)SYNC為低電平時(shí)有效,此時(shí),當(dāng)SCLK為下降沿時(shí)傳輸數(shù)據(jù),當(dāng)SYNC為高電平時(shí),輸入的數(shù)據(jù)會(huì)鎖存。
HAL庫(kù)配置及初始化
根據(jù)芯片手冊(cè)配置引腳和SPI引腳模式參數(shù),開啟中斷。
SPI的片選信號(hào)設(shè)置為GPIO_Output,低電平有效,傳輸速度Low
配置完成后,同I2C一樣,會(huì)生成一個(gè)SPI 的句柄。
SPI_HandleTypeDef hspi2;
部分代碼
通過AD5421實(shí)現(xiàn)SPI通信
以下是基于HAL庫(kù)的SPI收發(fā)函數(shù),主要用到HAL_SPI_Transmit
和HAL_SPI_Receive
這兩個(gè)函數(shù)實(shí)現(xiàn),這兩個(gè)函數(shù)相對(duì)應(yīng)的就是HAL_SPI_Transmit_IT
和HAL_SPI_Receive_IT
,這兩個(gè)函數(shù)和前兩個(gè)函數(shù)的差別就是,前者是在阻塞模式下發(fā)送和接收消息,而后者是利用中斷在非阻塞的模式下發(fā)送接收消息,前兩個(gè)函數(shù)無(wú)法連續(xù)發(fā)送或接收消息,而后兩個(gè)函數(shù)可以連續(xù)發(fā)送或接收消息。除此以外,還有用DMA直接存儲(chǔ)模式讀寫消息,使用示波器也可以看到相關(guān)波形,這里沒有演示,可以查看文章開頭的第三個(gè)鏈接,里面有對(duì)這幾個(gè)函數(shù)比較詳細(xì)的解釋。HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_RESET);
就是之前一直在講的軟件片選,人為拉高置低電平,啟動(dòng)SPI收發(fā)數(shù)據(jù)。
//this spi's transmisson can not continuous transmission of data.start
int spi_transmit(uint8_t *tpdat,uint16_t tdsize)
{
HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_RESET);
if(tpdat != NULL || tdsize > 0)
{
HAL_SPI_Transmit(&hspi2,tpdat,tdsize,0xFFFF);
HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_SET);
delay_ms(10);
return 1;
}
else
{
HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_SET);
return 0;
}
}
int spi_receive(uint8_t *rpdat,uint16_t rdsize)
{
HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_RESET);
if(rpdat != NULL || rdsize > 0)
{
HAL_SPI_Receive(&hspi2,rpdat,rdsize,0xFFFF);
HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_SET);
delay_ms(10);
return 1;
}
else
{
HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_SET);
return 0;
}
}
//this spi's transmisson can not continuous transmission of data.end
AD5421的讀寫數(shù)據(jù)函數(shù),輸入移位寄存器為24位(如果需要對(duì)數(shù)據(jù)進(jìn)行CRC糾錯(cuò)校驗(yàn),則為32位,這里沒用到)。
24/32位字寬的數(shù)據(jù)在串行時(shí)鐘輸入SCLK的控制下優(yōu)先載入器件的MSB位,所以在wbuf[1]時(shí)需要把data右移八位。
輸入移位寄存器由8位地址/命令字節(jié)、16位數(shù)據(jù)字和可選的8位CRC組成。
寫序列開始于SYNC信號(hào)的下降沿,數(shù)據(jù)在SCLK下降沿通過SDIN數(shù)據(jù)線輸入。在SYNC上升沿,24位數(shù)據(jù)被鎖存,然后傳輸?shù)较嚓P(guān)的寄存器并執(zhí)行規(guī)定的功能(DAC輸出改變或工作模式改變)。
void ad5421_write(uint8_t wadd,uint16_t data)
{
uint8_t wbuf[3];
memset(wbuf,0,sizeof(wbuf));
wbuf[0]=wadd&0x7F;
wbuf[1]=data>>8;
wbuf[2]=data&0x00FF;
spi_transmit(wbuf,3);
}
uint16_t ad5421_read(uint8_t radd)
{
uint8_t rbuf[3];
uint8_t read[3];
memset(rbuf,0,sizeof(rbuf));
rbuf[0]=radd;
rbuf[1]=0;
rbuf[2]=0;
spi_transmit(rbuf,3);
rbuf[0]=0x09;
rbuf[1]=0;
rbuf[2]=0;
HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_RESET);
// HAL_SPI_Transmit(&hspi2,rbuf,1,0xFFFF);
// HAL_SPI_Receive(&hspi2,rbuf,2,0xFFFF);
HAL_SPI_TransmitReceive(&hspi2,rbuf,read,3,0xFFFF);
HAL_GPIO_WritePin (SPI_CS_GPIO_Port,SPI_CS_Pin,GPIO_PIN_SET);
return (read[1]<<8)|(read[2]&0xFF);
}
在這里有一個(gè)函數(shù)HAL_SPI_TransmitReceive
這個(gè)函數(shù)是指在阻塞狀態(tài)下發(fā)送或接收一段數(shù)據(jù),該函數(shù)在文件stm32l4xx_hal_spi.c下。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-770228.html
/**
* @brief Transmit and Receive an amount of data in blocking mode.
* @param hspi pointer to a SPI_HandleTypeDef structure that contains
* the configuration information for SPI module.
* @param pTxData pointer to transmission data buffer
* @param pRxData pointer to reception data buffer
* @param Size amount of data to be sent and received
* @param Timeout Timeout duration
* @retval HAL status
*/
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size,uint32_t Timeout);
遇到的問題
SPI和I2C的代碼編寫步驟相似,思路也比較相像,但由于SPI讀寫寄存器這個(gè)完成了有一段時(shí)間了,所以遇到了什么問題其實(shí)印象有點(diǎn)模糊了,如果想到什么再加吧。
后面在實(shí)現(xiàn)讀芯片溫度和讀VLoop功能時(shí)有遇到過問題,下文再述。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-770228.html
到了這里,關(guān)于【STM32L496】使用HAL庫(kù)實(shí)現(xiàn)SPI寫入/讀取數(shù)據(jù)(AD5421)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!