IC4011+MCP4921(D/A)
|
||||
---|---|---|---|---|
初級會員
|
以下是光碟的spi_master.c檔
// *********************************************************************** // File : SPI_MASTER.c // *********************************************************************** #include <p30F4011.h> #include "C30EVM_LCD.h" // 將LCD函式的原型宣告檔案含入 #include <timer.h> // 將Timer函式的原型宣告檔案含入 #include <adc10.h> // 將adc10函式的原型宣告檔案含入 #include "ADCSubs.h" #include "SPISubs.h" #define FCY 7372800 * 2 // 因為使用頻率為將外部 7.3728 MHz * 8 的模式 , 每一指令週期需 4 個 clock // 所以 FCY = (7.3728 * 8 / 4 ) MHz = 7372800* 2 _FOSC(CSW_FSCM_OFF & XT_PLL8); // XT with 8xPLL oscillator, Failsafe clock off _FWDT(WDT_OFF); // Watchdog timer disabled _FBORPOR(PBOR_OFF & MCLR_EN); // Brown-out reset disabled, MCLR reset enabled _FGS(CODE_PROT_OFF); // Code protect disabled const char My_String1[]="VR1: VR2: " ; // 宣告字串於 Program Memory (因為 const 宣告) char My_String2[]="EE1: EE2: " ; // 宣告字串於 Data Memory unsigned int miliSec ; void Init_ADC(void) ; void Show_ADC(void) ; void SPI_Delay(void) ; // union 宣告將使8位元變數ByteAccess與SystemFlag結構變數使用相同的記憶體, // 以利不同格式的位元運算需求 union { unsigned char ByteAccess ; struct { unsigned Bit0: 1 ; unsigned Bit1: 1 ; unsigned Bit2: 1 ; unsigned unused : 5 ; } ; } SystemFlag ; //定義OneSecond旗標等同於SystemFlag.Bit0位元變數,故將其使用一個位元記憶空間 #define OneSecond SystemFlag.Bit0 void _ISR _T1Interrupt(void) //Timer1中斷副程式 { miliSec += 1 ; if (miliSec == 1000) //每1000次將OneSecond旗標設定為1 { OneSecond = 1 ; miliSec = 0 ; } IFS0bits.T1IF = 0 ; //清除中斷旗標 } unsigned int ADC_Value; unsigned char EEPROM_Data1 , EEPROM_Data2 ; unsigned char SPI_Status ; int main( void ) { Init_ADC( ) ; // 將ADC進行初始化設定 Init_SPI( ) ; OpenLCD( ) ; // 使用 OpenLCD( )對 LCD 模組作初始化設定 // 4 bits Data mode // 5 * 7 Character setcurLCD(0,0) ; // 使用 setcurLCD( ) 設定游標於 (0,0) putrsLCD( My_String1 ) ; // 將存在 Program Memory 的字串使用 // putrsLCD( ) 印出至 LCD setcurLCD(0,1) ; // 使用 setcurLCD( ) 設定游標於 (0,1) putrsLCD( My_String2 ) ; // 將存在 Data Memory 的字串使用 // putsLCD( ) 印出至 LCD ConfigIntTimer1( T1_INT_PRIOR_7 & T1_INT_ON ) ; // Timer1 的中斷優先等級設 7 (最高) // Timer1 的中斷 ON OpenTimer1( T1_ON & T1_IDLE_STOP & T1_GATE_OFF & // Timer1 的 Period 設為每 1ms T1_PS_1_1 & T1_SYNC_EXT_OFF & T1_SOURCE_INT , (FCY/ 1000) ) ; OneSecond = 0 ; SPI_EEPROM_StsWrite(0x00 ) ; SPI_Delay() ; while(1) { if ( OneSecond ) // 詢問 Timer1 的 Period 時間是否已到 // 可以用軟體模擬來檢查是否為準確的 1 ms { OneSecond = 0 ; Nop() ; // // 本練習會將 VR1 & VR2 的值寫入 EEPROM 位址 0x10 & 0x20 // 所以在此先讀出EEPROM 位址 0x10 & 0x20 的資料, 省下如果在 Write EEPROM // 後就馬上要讀必須等 EEPROM 寫完 ! 麻煩且浪費時間 // EEPROM_Data1 = SPI_EEPROM_ByteRead( 0x10 ) ; EEPROM_Data2 = SPI_EEPROM_ByteRead( 0x20 ) ; ADC_Value = Get_VR1( ) ; setcurLCD(4,0) ; // Set LCD cursor put_Num_LCD( ADC_Value >> 2 ) ; // 將類比轉換結果以十進位數字顯示至液晶顯示器 SPI_EEPROM_ByteWrite( 0x10 , ADC_Value >> 2 ) ; ADC_Value = Get_VR2( ) ; setcurLCD(12,0) ; // Set LCD cursor put_Num_LCD( ADC_Value >> 2 ) ; // 將類比轉換結果以十進位數字顯示至液晶顯示器 while ( ! SPI_EE_Ready() ) ; // 使用 SPI_RD_STATUS 來確認 EEPROM 是否處於 WIP ( Write In Process ) // Ready == 1 // Not Ready == 0 ; SPI_EEPROM_ByteWrite( 0x20 , ADC_Value >> 2 ) ; setcurLCD(4,1) ; // Set LCD cursor put_Num_LCD( EEPROM_Data1 ) ; setcurLCD(12,1) ; // Set LCD cursor put_Num_LCD( EEPROM_Data2 ) ; } } } void SPI_Delay(void) { int LoopSPI ; for (LoopSPI = 0 ; LoopSPI < 100 ; LoopSPI ++ ) ; } ------------------------------------------------------ Mcp4921的Avss、SCK、SDI 分別接ic4011的GND、SCK、SDO 4921的VDD外接電源power supply VDD和AVSS跨接104電容 CS接AVSS, VDD接Vref 燒入步驟沒問題, 液晶顯示vr1:XXX vr2:xxx (xxx為可變數字) EE1:000 EE2:000 -------- 小弟想請問,因為mcp4921的LDAC腳位沒接 不知道這樣的接法有誤嗎? IC4011只外接4921的SDO、GND、SCK; 以示波器測量SCK、SDO等腳位沒訊號 4921的Vout也沒訊號 整體來說,4921都沒再作動 願大師們,指引一下小弟方向
發表於: 2008/7/3 10:42
|
|||
|