Re: 有關smbus的問題
|
||||
---|---|---|---|---|
初級會員
|
"而BF置1剛好就是在第八個CLK的下緣"
你通过软件怎么知道第8个脉冲的? 1>BF,只能读SSPBUF 清0;但不能软件制1,是只读的 2>SSPOV,可以软件SET,RESET
發表於: 2006/11/6 16:33
|
|||
|
Re: 有關smbus的問題
|
||||
---|---|---|---|---|
高級會員
|
嗯 謝謝EBOWANG大大加入討論
因為我是看DATASHEET上面的時序圖 他上面畫的圖看起來像是當SSPBUF裝滿的時候 BF就會置1 而BF置1剛好就是在第八個CLK的下緣 因為我在位址正確,進入ISR後就把SSPIE設置為0的這種笨方法 所以我才會認為可以判斷BF置1時,先將SSPBUF中的值讀出,再延長時間,先不讓第九個CLK發送出來 因為協議也是說,如果資料不符,或是位址不符時,SLAVER可以發送NACK來結束通信,也就是說當MASTER在第九個CLK時偵測到SDA上為1時,就必須發送停止信號,結束通信,BUS上必須變成IDLE EBOWANG大大 我也是想說先把SSPBUF的值讀出來後,再將SSPOV上置1讓MCU誤認為已經溢位了,就會讓我的MCU在MASTER發送出第九個CLK時將SDA置1, 可是有時候MCU裡面的旗標動作會讓我無法理解他為什麼會跟我所想的動作有所不同,例如我已經將CKP置1了,但是在通信結束後,在示波器上看SMBUS卻是CLK一直被拉為0,有些地方明明SSPBUF中的資料已經讀出來了,照道理說應該下一次讀的應該是下一筆資料,可是讀出來的資料卻跟上一筆是一樣的,這就讓我很困惑,不過我是還沒試過,在數據進來前,事先將BF設置為1,等會來試試看,如過我想請問BF跟SSPOV可以經由軟體將他設置為1嗎?
發表於: 2006/11/6 15:53
|
|||
|
Re: 有關smbus的問題
|
||||
---|---|---|---|---|
初級會員
|
我想你可能还要去看看协议,我想问问你,你是怎么能知道时钟的第8个脉冲的,
而事实上,但I2C用硬件方式,并且在是在接收状态下,你只能通过软件知道的是第9个脉冲结束(中断产生的).而事实上,ACK是硬件自动产生的,产生的条件为: 1>地址匹配. 2>数据接收前,BF=0; 3>数据接收前,SSPOV=0; 希望我的想法对你有用
發表於: 2006/11/6 13:42
|
|||
|
Re: 有關smbus的問題
|
||||
---|---|---|---|---|
高級會員
|
請問我可不可以在第八個CLK,SSPSTAT中的BF旗標置1的時候先將CKP清為0,然後讀出SSPBUF中的值,與SLAVER中的值做比較,如果比較後為錯誤則將SSPOV值置1,再將CKP的值置1,讓MASTER發送第九個CLK時,在SDA上送出1(NACK),結束傳輸
如果比較後為正確則將CKP旗標置0,讓MASTER發送第九個CLK時,再SDA上送出0(ACK),繼續下一筆資料的傳送。 不過我自己試過好像是不行,不知道是不是不能在第八個CLK時將CKP 旗標清0,還是不能自己將SSPOV置1讓SLAVER誤以為SSPBUF上為滿的,而在第九個CLK時將SDA置1
發表於: 2006/11/3 16:00
|
|||
|
Re: 有關smbus的問題
|
||||
---|---|---|---|---|
高級會員
|
謝謝版主提供這個程式給我參考
不知道版主使用的MCU跟我目前所使用的這顆,裡面IIC介面的操作方式是否相同,所以在看過程式後有一些比較不太清楚的地方,想要請版主幫忙解惑,因為不知道我觀念清不清楚,所以我會做些註解,如果不正確的地方請版主幫我做指正,謝謝 想先請問一下版主的SMBUS上的資料格式是使用哪一種protocal,可否請版主提供參考? 因為我想要的動作是READ與WRITE都要有,也就是一開始的資料格式依照SMBUS的規格是相同的 |START|ADDRESS|W|ACK|COMMAND|ACK| 接下來READ的格式為 |REPEAT START|ADDRESS|R|ACK|DATAL|ACK|DATAH|NACK|STOP| 而WRITE的格式則為 |DATAL|ACK|DATAH|NACK|STOP| 因為我要利用COMMAND中的直讓我的MCU去判斷要存取的值為何,所以會先從MASTER發送COMMAND的信號寫入到SLAVER,而SLAVER會依據COMMAND的值來存取特定的暫存器,可是當COMMAND為無效時就需要,馬上的發送NACK去告知MASTER讓MASTER不要繼續在發送接下來的DATA。 ISR movwf w_temp ; save off current W register contents movf STATUS,W ; move status register into W register movwf status_temp ; save off contents of STATUS register movf FSR,W movwf FSR_temp ; banksel PIR1 btfsc PIR1,SSPIF ; check I2C Interrupt ? goto I2C_ISR ; Yes, I2C Interrupt ; ;------------------------------------------------ call Main_ISR ; Not I2C Interrupt, Call the Main ISR ;------------------------------------------------ goto ISR_Exit ; ;******* I2C Interrupt for Slave Receive Mode ************ ; I2C_ISR bcf PIR1,SSPIF ; S/W clear SSPIF ; banksel SSPSTAT ; Bank 1 btfsc SSPSTAT,Data_Addr ; 1= Data, 0=Address <--請問版主,MCU是如何知道接收的是DATA或ADDRESS來使這個旗標做變化是經由硬體判斷接收的數據前的START CONDITION嗎? goto Is_I2C_Data ; ;*** I2C First byte (Address) is comming ****** ; banksel SSPCON movf SSPBUF,W<--MCU應該是會自動判斷BUS上的ADDRESS與本身儲存的是否相同,如果相同就會自動將SSPIF設置為1,並且根據中斷旗標判斷是否進入中斷副程式,所以這裡SSPBUF中所儲存的是ADDRESS bcf I2C_Rec_CMD ; Clear I2C Received Flag<--這個旗標在看了後面的程式後,應該是個命令旗標,是版主自己定義的旗標,作法還蠻特別的,讓我多了一思考模式,此旗標在此先清為0是因為ADDRESS之後接收的DATA要為COMMAND,所以在接下來的判斷中,如果為0就會判斷下一筆數據為COMMAND,否則則為一般的DATA bcf I2C_Rec_Data banksel SSPSTAT btfsc SSPSTAT,Read_Write<--這裡判斷的應該是在接收ADDRESS後的第八個位元,如果是1則為READ PROTOCAL,如果是0則為WRITE PROTOCAL,版主判斷在WRITE PROTOCAL下就將SCL釋放,之後MASTER在送出DATA時則又會重新進入中斷副程式中,接下來再經由判斷接收的是DATA的資料則跳到IS_I2C_DATA goto I2C_Read_Status banksel SSPCON bsf SSPCON,CKP ; Received ADDRESS match, Release SCL pin goto ISR_Exit I2C_Read_Status banksel PORTB movlw Status_Buffer ; Get buffer address addwf I2C_Read_Point,W ; FSR = Pointer + buffer address movwf FSR movf INDF,W ; get responce data from buffer movwf SSPBUF ; Send to I2C, reag by I2C Master nop BSF SSPCON,CKP ; Release CKP signal, inform I2C master to read back goto ISR_Exit ; ;*** I2C data byte is comming ******* ; Is_I2C_Data banksel Flag ; Bank 0 btfss I2C_Rec_CMD goto Is_I2C_CMD ; I2C COMMAND is comming ; ; "WRITE COMMAND" I2C_Rec_CMD == 1, receive the 3rd byte ; btfss F2_CMD_FG goto Non_F2_CMD Is_F2_CMD movf SSPBUF,W ; Get I2C data movwf I2C_Read_Point ; Set Status read point bsf SSPCON,CKP goto ISR_Exit Non_F2_CMD bsf I2C_Rec_Data ; Set I2C completed receving flag movf SSPBUF,W ; Get I2C data movwf I2C_Data_BFR bsf SSPCON,CKP goto ISR_Exit ; ; "WRITE COMMAND" I2C_Rec_CMD== 0 ,receive the 2nd yte ; Is_I2C_CMD bsf I2C_Rec_CMD ; Set I2C Command Received Flag bcf I2C_Rec_Data movf SSPBUF,W ; Get I2C data movwf I2C_CMD_BFR movlw Status_Check ; is "F2" Command ? subwf I2C_CMD_BFR,W bz F2_Req<--判斷是否為此SLAVER中的有效COMMAND如果是則跳到F2﹍REQ,如果不是則將F2_CMD_FG清0 bcf F2_CMD_FG ; Normal Read Command bsf SSPCON,CKP goto ISR_Exit F2_Req bsf F2_CMD_FG ; Status request Command bsf SSPCON,CKP ; ;************************************************* ; ISR_Exit movf FSR_temp,W movwf FSR movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents ; retfie ; return from interrupt 在版主的程式中好像在判斷接收的COMMAND不是SLAVER中有效的COMMAND後,不是經由發送NACK告知MASTER,而版主是由回傳的DATA告知MASTER是否SLAVER接收的COMMAND為有效的COMMAND,想請問版主,有沒有辦法是由發送一個NACK去告知MASTER傳錯COMMAND?
發表於: 2006/11/3 15:09
|
|||
|
Re: 有關smbus的問題
|
||||
---|---|---|---|---|
版主
|
這是幾年前寫得I2C bootloader 程式中的一段有關I2C Slave 接收資料ㄧ小段,讀取I2C資料是用Point的方式,先用write command 先將要讀回去的RAM Point 寫出去後再用毒的命令將所指到的Point的內容讀回來,程式裡有一些比較奇怪的命令可以不要去管內是給bootloader控制用的。
;***************************************************************************
發表於: 2006/11/3 10:40
|
|||
|
Re: 有關smbus的問題
|
||||
---|---|---|---|---|
高級會員
|
有沒有人有用P18F452的IIC介面,當成SLAVER接收一個ADDRESS+COMMAND+DATAL+DATAH
並且判斷ADDRESS及COMMAND是否正確,如果不正確則發送一個NACK告知MASTER的相關參考程式 謝謝
發表於: 2006/11/2 16:15
|
|||
|
有關PIC18F425當成SMBUS SLAVER WRITE WORD的問題,請各位幫忙
|
||||
---|---|---|---|---|
高級會員
|
請問有沒有人有用過p18f452當成slaver接收訊號
有沒有範例可以參考? 我自己有寫了一個,利用P18F452當成SLAVER接收一個word的程式 不過在有些地方會有問題 我在主程式中有建一個表,當接收的COMMAND在建表中找的到相同的值時,則接收完整的DATA 如果接收到的COMMAND再建表中找不到時,則COMMAND 暫存器中丟入FF的值,並且要正確的發出一個NACK結束通訊 請問我可不可以在第九個CLK之前將SSPOV設置為1,去產生一個NACK的信號 CODE _SMBUS_SLAVER_INIT: MOVFF DEVICE_ADDRESS,SSPADD MOVLW B'11000000' MOVWF SSPSTAT MOVLW B'00111110' MOVWF SSPCON1 MOVLW B'11000001' MOVWF SSPCON2 RETURN _SMBUS_SLAVER: BCF PIE1,SSPIE _SMBUS_SLAVER_ADDRESS: BTFSS SSPSTAT,BF GOTO _SMBUS_SLAVER_ADDRESS MOVF SSPBUF,W NOP NOP NOP BSF SSPCON1,CKP _SMBUS_SLAVER_ADDRESS_LOOP1: BTFSS PIR1,SSPIF GOTO _SMBUS_SLAVER_ADDRESS_LOOP1 BCF PIR1,SSPIF NOP _SMBUS_SLAVER_COMMAND: BTFSS SSPSTAT,BF GOTO _SMBUS_SLAVER_COMMAND BCF SSPCON1,CKP MOVFF SSPBUF,COMMAND<---這裡已經把COMMAND讀出了 _SMBUS_SLAVER_COMMAND_LOOP2: MOVFF COMMAND,INDEX BCF STATUS,C RLCF INDEX _SMBUS_SLAVER_COMMAND_LOOP3: MOVLW 02H MOVWF PCLATH MOVF INDEX,W CALL _COMMAND_TABLE INCF INDEX INCF INDEX XORWF COMMAND,W BTFSS STATUS,Z GOTO _SMBUS_SLAVER_FAIL <<-----當命令不在建表中時,應該要跳躍至SMBUS_SLAVER_FAIL 並發送nack的訊號,但我有時候會在示波器上看到送出一個word的完整格式,這點也令我很困惑,照道理來說,不是COMMAND中的值,與WREG中的值不同時,應該要跳到我指定的位址,可是模擬出來總覺得怪怪的 BSF SSPCON1,CKP _SMBUS_SLAVER_COMMAND_LOOP1: BTFSS PIR1,SSPIF GOTO _SMBUS_SLAVER_COMMAND_LOOP1 BCF PIR1,SSPIF BSF SSPCON1,CKP _SMBUS_SLAVER_RX_DATA: BTFSS SSPSTAT,BF GOTO _SMBUS_SLAVER_RX_DATA MOVFF SSPBUF,DATA_BYTE<---可是這裡讀出的值也是跟COMMAND讀到的值相同,有點想不通,是不是上一次的值沒有發送出ACK的訊號,導致沒有新的DATA被接收??可是我上面有釋放了CLK並且SSPIF也重新置為1了,這樣不就代表應該要有一個新的DATA進入了 _SMBUS_SLAVER_RX_DATA_LOOP1: BTFSS PIR1,SSPIF GOTO _SMBUS_SLAVER_RX_DATA_LOOP1 BCF PIR1,SSPIF _SMBUS_SLAVER_RX_DATA_LOOP2: BTFSS SSPSTAT,BF GOTO _SMBUS_SLAVER_RX_DATA_LOOP2 BSF SSPCON1,SSPOV BSF SSPCON1,CKP _SMBUS_SLAVER_RX_DATA_LOOP3: BTFSS PIR1,SSPIF GOTO _SMBUS_SLAVER_RX_DATA_LOOP3 BCF PIR1,SSPIF _SMBUS_SLAVER_RX_STOP: MOVFF SSPBUF,DATA_BYTE+1<---接下來才是下一筆DATA,資料好像向後挪了 BCF SSPCON1,SSPOV BSF PIE1,SSPIE RETURN _SMBUS_SLAVER_FAIL: BSF SSPCON1,SSPOV BSF SSPCON1,CKP BSF SSPCON1,CKP <<------瘋狂的利用指令將CKP置1,但是在用ICD2模擬時,卻無法將CKP置1 BSF SSPCON1,CKP <<------無法有效的將ckp置1,DATASHEET上面不是說可以隨時置1ㄇ?? _SMBUS_SLAVER_FAIL_LOOP1: BTFSS PIR1,SSPIF GOTO _SMBUS_SLAVER_FAIL_LOOP1 BCF PIR1,SSPIF NOP BSF SSPCON1,CKP <<------無法有效的將ckp置1 BCF SSPCON1,SSPOV BCF PIR1,SSPIF BSF PIE1,SSPIE 請各位大俠幫幫忙
發表於: 2006/11/1 18:31
|
|||
|