NUC140之SPI和AD5441
阿新 • • 發佈:2019-01-12
NUC140的SPI庫函式還是寫的很不錯的,我們看這個函式說明:
/*---------------------------------------------------------------------------------------------------------*/ /* Function: DrvSPI_Open */ /* */ /* Parameters: */ /* eSpiPort [in]: Specify the SPI port */ /* eMode [in]: Specify the operation mode (eDRVSPI_MASTER/eDRVSPI_SLAVE) */ /* eType [in]: Specify the transfer type (eDRVSPI_TYPE0 ~ eDRVSPI_TYPE7) */ /* i32BitLength [in]: Specify the bit length in a transaction (1~32) */ /* */ /* Returns: */ /* E_DRVSPI_ERR_INIT: The specified SPI port has been opened before. */ /* E_DRVSPI_ERR_BUSY: The specified SPI port is in busy status. */ /* E_DRVSPI_ERR_BIT_LENGTH: The specified bit length is out of range. */ /* E_SUCCESS: Success. */ /* */ /* Description: */ /* Configure the operation mode, transfer type and bit length of a transaction of the specified SPI */ /* port. */ /* The timing waveform types: */ /* DRVSPI_TYPE0: CS --| Active state |--- _ _ _ _ _ _ _ _ CLK ____| |_| |_| |_| |_| |_| |_| |_| |_____ Tx ----| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |--- Rx --| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |----- DRVSPI_TYPE1: CS --| Active state |--- _ _ _ _ _ _ _ _ CLK ____| |_| |_| |_| |_| |_| |_| |_| |_____ Tx --| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |----- Rx --| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |----- DRVSPI_TYPE2: CS --| Active state |--- _ _ _ _ _ _ _ _ CLK ____| |_| |_| |_| |_| |_| |_| |_| |_____ Tx ----| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |--- Rx ----| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |--- DRVSPI_TYPE3: CS --| Active state |--- _ _ _ _ _ _ _ _ CLK ____| |_| |_| |_| |_| |_| |_| |_| |_____ Tx --| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |----- Rx ----| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |--- DRVSPI_TYPE4: CS --| Active state |--- ___ _ _ _ _ _ _ _ ______ CLK |_| |_| |_| |_| |_| |_| |_| |_| Tx --| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |------ Rx ----| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |---- DRVSPI_TYPE5: CS --| Active state |--- ___ _ _ _ _ _ _ _ ______ CLK |_| |_| |_| |_| |_| |_| |_| |_| Tx ----| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |---- Rx ----| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |---- DRVSPI_TYPE6: CS --| Active state |--- ___ _ _ _ _ _ _ _ ______ CLK |_| |_| |_| |_| |_| |_| |_| |_| Tx --| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |------ Rx --| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |------ DRVSPI_TYPE7: CS --| Active state |--- ___ _ _ _ _ _ _ _ ______ CLK |_| |_| |_| |_| |_| |_| |_| |_| Tx ----| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |---- Rx --| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |---- Master / Slave Transfer Type Matching Table DRVSPI_TYPE0 <==> DRVSPI_TYPE3 DRVSPI_TYPE1 <==> DRVSPI_TYPE1 DRVSPI_TYPE2 <==> DRVSPI_TYPE2 DRVSPI_TYPE3 <==> DRVSPI_TYPE0 DRVSPI_TYPE4 <==> DRVSPI_TYPE7 DRVSPI_TYPE5 <==> DRVSPI_TYPE5 DRVSPI_TYPE6 <==> DRVSPI_TYPE6 DRVSPI_TYPE7 <==> DRVSPI_TYPE4 */ /*------------------------------------------------------------------------------------------------------
庫函式將不同型別的SPI用圖表示的很清楚,只需要去檢視晶片的DATASHEET,選擇正確的
SPI形式,基本上一次就能除錯成功。
SPI是一個四條線的序列通訊協議,包括一條時鐘線,兩條資料線和一條使能線,如果在
一組SPI上覆用多個SPI器件,則會有多個使能線。
AD5441是一個SPI控制的DAC,它的資料型別如下:
上升沿傳送資料,低電平使能,符合庫函式TPYE1,附上程式如下:
/***************************************** *檔名:SPI_U27_28.c * *功能:公共變數定義檔案 * ******************************************/ #include "SPI_U27_U28.h" /************************************************** *函式名: initialize_SPI * *功能: 初始化SPI * *出口引數:無 * *入口引數:無 * *************************************************/ void initialize_SPI (void) { DrvGPIO_InitFunction (E_FUNC_SPI1); //PC.8,PC.9,PC.11設定為SPI DrvGPIO_InitFunction (E_FUNC_SPI1_SS1); //PB.9設定為SPI DrvSYS_UnlockProtectedReg (); //解鎖受保護的系統暫存器 DrvSYS_SetIPClock (E_SYS_SPI1_CLK, 1); //使能SPI埠1的核心時鐘 DrvSYS_LockProtectedReg (); //對系統暫存器上鎖 DrvSPI_Open(eDRVSPI_PORT1, //開啟SPI埠1 eDRVSPI_MASTER, //設為主控 eDRVSPI_TYPE1, //時鐘空閒狀態為低電平,在序列時鐘下降沿傳輸資料,上升沿鎖存資料 12); //每次傳輸12位元 DrvSPI_SetClockFreq(eDRVSPI_PORT1, //設定SPI埠1的時鐘頻率 2000000, //可變時鐘1頻率為2M 1000000); //可變時鐘2頻率為1M //若不選擇可變時鐘,復位預設時鐘源為可變時鐘1即DIVIDER的頻率,具體可見晶片手冊 delay(100); //延遲使時鐘穩定 DrvSPI_DisableAutoSS(eDRVSPI_PORT1); //禁止SPI埠1的自動從選擇功能 DrvSPI_SetTriggerMode(eDRVSPI_PORT1, eDRVSPI_LEVEL_TRIGGER); //設定從引腳為電平啟用模式 DrvSPI_SetSlaveSelectActiveLevel(eDRVSPI_PORT1, eDRVSPI_ACTIVE_LOW_FALLING); //設定埠1從引腳為低電平啟用 DrvSPI_SetEndian (eDRVSPI_PORT1, //設定SPI埠1資料傳送為高位元組在前 eDRVSPI_MSB_FIRST ); } /************************************************** *函式名: SPI_U27_write * *功能: 調製度寫函式 * *出口引數:無 * *入口引數:調製度的值,無符號32位(uint型) * *************************************************/ void SPI_U27_write (uint32_t modulation_value_ ) { while(DrvSPI_IsBusy(eDRVSPI_PORT1)) //查詢SPI埠1是否忙 { } DrvSPI_SetSS(eDRVSPI_PORT1, //啟用SPI埠1的從引腳1 eDRVSPI_SS1 ); DrvSPI_SingleWrite(eDRVSPI_PORT1, &modulation_value_); //將調製度的值送到SPI傳送器中 DrvSPI_SetGo(eDRVSPI_PORT1); //開始傳送 DrvSPI_ClrSS(eDRVSPI_PORT1, eDRVSPI_SS1); //使從引腳1非啟用 } /************************************************** *函式名: monitor_D6 * *功能: 功率寫函式 * *出口引數:無 * *入口引數:功率的值,無符號32位(uint型) * *************************************************/ void SPI_U28_write (uint32_t power_value_) { while(DrvSPI_IsBusy(eDRVSPI_PORT1)) //查詢SPI埠1是否忙 { } DrvSPI_SetSS(eDRVSPI_PORT1, //啟用SPI埠1的從引腳0 eDRVSPI_SS0 ); DrvSPI_SingleWrite(eDRVSPI_PORT1, &power_value_); //將功率的值送到SPI傳送器中 DrvSPI_SetGo(eDRVSPI_PORT1); //開始傳送 DrvSPI_ClrSS(eDRVSPI_PORT1, eDRVSPI_SS0); //使從引腳0非啟用 }
標頭檔案為
#ifndef SPI_U27_U28_h #define SPI_U27_U28_h #include "common_variables.h" #include "DrvSPI.h" #include "delay.h" #include "DrvGPIO.h" #include "DrvSYS.h" extern void initialize_SPI (void); //SPI初始化 extern void SPI_U27_write (uint32_t modulation_value_ ); //晶片U27寫入函式,引數為調製度的值 extern void SPI_U28_write (uint32_t power_value_); //晶片U28寫入函式,引數為功率值 #endif