• slider image 442
  • slider image 483
  • slider image 484
  • slider image 485
  • slider image 486
  • slider image 487
  • slider image 488
  • slider image 491
:::

論壇索引


Board index » All Posts (Lunger)




Re: I2C的問題(1個傳送,3個接收)
#1
新會員
新會員


請問一下
傳送位址與資料時的ACK訊號為一個1伏的方波
這算正常嗎?
如果不正常,原因出在哪呢?

發表於: 2006/5/11 21:44
頂部


Re: I2C的問題(1個傳送,3個接收)
#2
新會員
新會員


大家安安~

小弟想問一下:
Master傳送一個byte時,
如果Slave因為資料遺失而沒收滿一個byte,
也就不會回傳確認訊號,
這時Master發個STOP,
Slave可以繼續接收資料而不會有任何影響嗎?

如果START和STOP的訊號也接收失敗,
這樣會影響資料接收吧?!

發表於: 2006/5/10 17:36
頂部


Re: I2C的問題(1個傳送,3個接收)
#3
新會員
新會員


我發現好像是電路的問題= =
我試過只傳給兩個PIC, 把第三個PIC從電路中拔除後
程式與硬體運作是很正常的, 不會出問題, 我敢拍胸脯保證
(給他跑了好一段時間還是正常到不行...)
當三個PIC同時插在電路板上後
唉...問題又發生了..
眼睜睜的看著閃爍的LED一個一個停住了
最後...PIC全部死當無一倖免...囧rz
即使把程式改成只傳Device1也是一樣
LED燈不是像跑馬燈一樣閃爍的很有規律
而是亂閃(會miss資料)...

請問要怎麼解決呢?
( 硬體電路 or... )

發表於: 2006/5/5 0:06
頂部


Re: I2C的問題(1個傳送,3個接收)
#4
新會員
新會員


傳送端是根據PIC18f452寫的
接收端則是PIC18f4431
我看波形圖比較奇怪的是傳送位址跟資料的時候
ACK的波形都是1,照理說應該只有傳送資料時的ACK為1才對
不過我怎麼改都還是1....

以下是傳送端與接收端的程式碼
( 一傳一時可以持續接收, 一傳三就傳一段時間就掛掉了= = )
//====================傳送端 只作傳送===========
#include <p18f452.h>
#include <delays.h>
#include <i2c.h>

int dy=0,i=0;
void F_Initial(void);
void F_I2C_START(void);
unsigned char F_I2C_WAIT(void);
unsigned char F_I2C_Send_Address(unsigned char);
void F_I2C_Send_Data(unsigned char);
void F_I2C_STOP(void);

void main(void)
{
    
unsigned char UC_I2C_Data1=0x00,      
                  
UC_I2C_Data2=0x10,      
                  
UC_I2C_Data3=0x04,      
                  
I2C_Device1=0x22,   //addr 0001 0010 
                  
I2C_Device2=0x18,   //addr 0001 1000
                  
I2C_Device3=0x60;   //addr 0110 0000
    
F_Initial();
    while(
1)
    {
                                
//====傳Device1
        
F_I2C_START();
        if( 
F_I2C_Send_Address(I2C_Device1 0XFE) )
        {
            
F_I2C_Send_Data(UC_I2C_Data1);    
        }
        
F_I2C_STOP();
        
i++;//for test
        //=================test============
        
UC_I2C_Data1++;
        if(
UC_I2C_Data1>0x0f)
            
UC_I2C_Data1=0x00;
        
Delay10KTCYx(1);//2.5ms
        //=================================
//====傳Device2
        
F_I2C_START();
        if( 
F_I2C_Send_Address(I2C_Device2 0XFE) )
        {
            
F_I2C_Send_Data(UC_I2C_Data2);    
        }
        
F_I2C_STOP();
        
i++;//for test
        //=================test============
        
UC_I2C_Data2+=16;
        if(
UC_I2C_Data2>0xff)
            
UC_I2C_Data2=0x10;
        
Delay10KTCYx(1);
        
//=================================
//====傳Device3
        
F_I2C_START();
        if( 
F_I2C_Send_Address(I2C_Device3 0XFE) )
        {
            
F_I2C_Send_Data(UC_I2C_Data3);    
        }
        
F_I2C_STOP();
        
i++;//for test
        //=================test============
        
UC_I2C_Data3+=4;
        if(
UC_I2C_Data3>0x3c)
            
UC_I2C_Data3=0x04;
        
Delay10KTCYx(1);
        
//=================================

    
}
}

void F_Initial(void)
{
    
TRISD 0;
    
LATD 0;
    
TRISCbits.TRISC3 0;
    
TRISCbits.TRISC4 0;
    
SSPSTATbits.SMP 1;
    
SSPSTATbits.CKE 0;
    
SSPCON1 0x38;
    
SSPADD 0x30;
}

void F_I2C_START(void)
{
    
unsigned char a;
    
SSPCON2bits.SEN 1;
    
a=F_I2C_WAIT();
    for(
dy=0;dy<3;dy++);    //緩衝時間
}

unsigned char F_I2C_WAIT(void)
{
    
int count=0;
    while (!
PIR1bits.SSPIF && count<5)    // when SSPIF is Hi
        
count++;
    
PIR1bits.SSPIF=0;                   
    if(
count==5)
        return (
0);
    else
        return (
1);
}

unsigned char F_I2C_Send_Address(unsigned char UC_Address)
{
    
int count=0;
    
unsigned char flag='1';
    
SSPBUF UC_Address;
    while(
SSPSTATbits.BF==1);
    while(
SSPCON2bits.ACKSTAT && count<)
        
count++;
    
flag F_I2C_WAIT();
    if(
flag=='0' || count==8)
        return (
0);
    else
        return (
1);
}

void F_I2C_Send_Data(unsigned char UC_Data)
{
    
unsigned char a;
    
SSPBUF UC_Data;
    while(
SSPSTATbits.BF==1);
    
a=F_I2C_WAIT();
}

void F_I2C_STOP(void)
{    
    
unsigned char a;
    
SSPCON2bits.PEN 1;
    
a=F_I2C_WAIT();
    for(
dy=0;dy<3;dy++);    //緩衝時間
}


//==================接收端  只做接收=============================
#include <p18f4431.h>
#include <i2c.h>
#include <delays.h>

unsigned char UC_I2C_CMD=0x00,TEMP=0x00;
void F_Check_I2C_CMD(void);
void i2c_Initial(void);

void High_INT_SER(void);
#pragma code High_Interrupt_Vector=0x08
void High_INT_VEC (void)
{
    
_asm
    
goto    High_INT_SER
    _endasm
}
#pragma code

#pragma interrupt High_INT_SER
void High_INT_SER (void)
{
    if ( 
PIR1bits.SSPIF == )
    {
        
TEMP=SSPBUF;
        
PIR1bits.SSPIF 0;
        
F_Check_I2C_CMD();
    }
}

void main(void)
{
    
i2c_Initial();
    while(
1);
}

void i2c_Initial(void)
{
    
LATD 0;
    
TRISD=0;
    
TRISCbits.TRISC4=1;
    
TRISCbits.TRISC5=1;
    
SSPSTATbits.SMP 0;
    
SSPSTATbits.CKE 0;
    
SSPCON 0x3e;
    
SSPADD 0x60 0xFE;
    
//======= i2c interrupt =======
    
PIE1bits.SSPIE=1;
    
IPR1bits.SSPIP=1;
    
//======= interrupt set =======
    
RCONbits.IPEN=1;
    
INTCONbits.GIEH=1;
    
INTCONbits.GIEL=1;

    
SSPSTATbits.BF=0;
    
SSPCONbits.SSPOV=0;
}

void F_Check_I2C_CMD(void)
{
    
SSPSTATbits.BF=0;
    
SSPCONbits.SSPOV=0;
    switch(
TEMP)
    {
        case 
0x60 0xFE:    
            break;

        default:
            
LATD=TEMP;
            break;
    }
}



發表於: 2006/5/4 20:55
頂部


Re: I2C的問題(1個傳送,3個接收)
#5
新會員
新會員


請問一下
我用led來顯示接收到的資料值
傳送端一直傳資料
接收端就不斷把資料值顯示在led上
傳送端每隔2.5ms傳送一次資料
大約過半分鐘後
接收端就停住而無法繼續接收了

請問有可能是某些暫存器溢位造成的嗎?
不過,會溢位的暫存器我程式方面已經做過處理
但是還是發生無法繼續接收的情況
這是哪種原因造成的呢??

發表於: 2006/5/4 13:58
頂部


Re: I2C的問題(1個傳送,3個接收)
#6
新會員
新會員


很抱歉 我沒遇過耶= =
應該丟什麼到SSPBUF,就傳什麼出來才對...

我只碰過傳資料時傳的位址被當成資料,傳的資料被當成位址,所以接收端一直收不到...
後來把接收端的SSPADD改成傳送端傳過來的資料時,SSPBUF就可以收到位址了(事實上是傳送端傳來的資料),但是第二筆資料還是收不到...
用示波器看波形後發現SCL有19個方波(中間SCL held low的地方,SDA跟SCL產生一個方波,我只傳送2個BYTES,所以理論上是18個才對),上述傳送端傳的位址跟資料才被當成位址來傳了,所以才會發生傳的資料被當成位址的情況= =
最後 在開始跟結束的位元後都用for迴圈DELAY一段時間,就正常工作了

發表於: 2006/5/2 17:22
頂部


Re: I2C的問題(1個傳送,3個接收)
#7
新會員
新會員


我找到錯誤的來源了
因為接收端都沒加裝reset裝置
reset後就可以正常接收了= =

發表於: 2006/5/1 15:34
頂部


I2C的問題(1個傳送,3個接收)
#8
新會員
新會員


各位大大好~
小弟我有個問題
我在使用一對一時, 接收端都可以確實的接收到資料
在用一對三時, 傳送端是輪流傳送資料至三個接收端
假設分別為1,2,3號接收端
剛開始可能是只有1號可以收到資料
後來跳到2號, 1號又收不到了,
再後來又跳到3號, 其他的又收不到了
接收情況就像上述跳來跳去, 而不是輪流接收
看傳送的波形時, 的確是輪流傳送三筆資料給三個接收端
請問這情形要如何解決呢

發表於: 2006/5/1 12:00
頂部


Re: 關於使用PIC18F4431於APP001實驗板 --> I2C功能
#9
新會員
新會員


以上問題都解決了

請問一下
我觀測波形後發現
有些資料會遺失

請問有那些方法可以增加傳送時的穩定性呢?

發表於: 2006/4/24 19:49
頂部


Re: 關於使用PIC18F4431於APP001實驗板 --> I2C功能
#10
新會員
新會員


恩~謝謝版主回答
我對調後 Master可以傳送位址了

請問一下PIC18F452 的 I2C 的 Master 傳送資料的問題
在傳送數據後的ACK是由slave接受的嘛?
為何有個箭頭說"ACKSTAT in SSPCON2 = 1"
這樣的話不就代表沒有從slave接收到確認訊號
( 在PIC18FXX2 datasheet的156頁 )

了解的大大們就回答一下吧~
~~甘溫唷~~~


再問一個問題 :
MASTER端傳送的位址為0x12 資料為0x33
SLAVE端的SSPADD設為0x12, SSPBUF接收不到資料
把SLAVE端的SSPADD改為0x33, SSPBUF卻接收到0x33
看SDA-SCL波形發現,在傳送的第一個BYTE時, SCL的第九個脈衝對應到的SDA值都是HIGH, 照理說應該是LOW才對
會不會是這裡造成上述問題?
怎麼改程式都是如此....我要如何解決呢><"

註 : MASTER的晶片是PIC18F452,只做傳送
SLAVE的晶片是PIC18F4431,只做接收

//===================MASTER 端程式=======
#include <p18f452.h>
#include <delays.h>
#include <i2c.h>

void F_Initial(void);
void F_I2C_START(void);
unsigned char F_I2C_WAIT(void);
unsigned char F_I2C_Send_Address(unsigned char);
void F_I2C_Send_Data(unsigned char);
void F_I2C_STOP(void);

void main(void)
{
unsigned char UC_I2C_Data=0x33, //0101 0101
I2C_Devicel=0x13; //0001 0010
F_Initial();
while(1)
{
F_I2C_START();
if (F_I2C_Send_Address(I2C_Devicel & 0XFE))
{
F_I2C_Send_Data(UC_I2C_Data);
}
F_I2C_STOP();
}
}

void F_Initial(void)
{
TRISD = 0;
LATD = 0;
TRISCbits.TRISC3 = 0;
TRISCbits.TRISC4 = 0;
SSPSTATbits.SMP = 1;
SSPSTATbits.CKE = 0;
SSPCON1 = 0x38;
SSPADD = 0x30;
}

void F_I2C_START(void)
{
SSPCON2bits.SEN = 1;
}

unsigned char F_I2C_WAIT(void)
{
if ( PIR1bits.SSPIF )
{
PIR1bits.SSPIF = 0;
return (1);
}
else
return (0);
}

unsigned char F_I2C_Send_Address(unsigned char UC_Address)
{
SSPBUF = UC_Address;
while(!SSPCON2bits.ACKSTAT);
if(!F_I2C_WAIT())
return (1);
else
return (0);
}

void F_I2C_Send_Data(unsigned char UC_Data)
{
SSPBUF = UC_Data;
while(!F_I2C_WAIT());
}

void F_I2C_STOP(void)
{
SSPCON2bits.PEN = 1;
while(!F_I2C_WAIT());
}


//===================SLAVE端程式=======
#include <p18f4431.h>
#include <i2c.h>
#include <delays.h>

unsigned char UC_I2C_CMD=0x00,TEMP=0x00;
void F_Check_I2C_CMD(void);
void i2c_Initial(void);

void High_INT_SER(void);
#pragma code High_Interrupt_Vector=0x08
void High_INT_VEC (void)
{
_asm
goto High_INT_SER
_endasm
}
#pragma code

#pragma interrupt High_INT_SER
void High_INT_SER (void)
{
if ( PIR1bits.SSPIF == 1 )
{
PIR1bits.SSPIF = 0;
F_Check_I2C_CMD();
}
}

void main(void)
{
i2c_Initial();
while(1);
}

void i2c_Initial(void)
{
LATD = 0;
TRISD=0;

TRISCbits.TRISC4=1;
TRISCbits.TRISC5=1;
SSPSTATbits.SMP = 0;
SSPSTATbits.CKE = 0;
SSPCON = 0x3e;
SSPADD = 0x13 & 0xFE;
SSPBUF=0x00;
//======= i2c interrupt =======
PIE1bits.SSPIE=1;
IPR1bits.SSPIP=1;
//======= interrupt set =======
RCONbits.IPEN=1;
INTCONbits.GIEH=1;
INTCONbits.GIEL=1;

SSPSTATbits.BF=0;
}

void F_Check_I2C_CMD(void)
{
TEMP=SSPBUF;
LATD=TEMP;
}


發表於: 2006/4/19 21:35
頂部



(1) 2 »



:::

Microchip連結

https://www.facebook.com/microchiptechnologytaiwan/
http://www.microchip.com.tw/modules/tad_uploader/index.php?of_cat_sn=13
https://mu.microchip.com/page/tmu
http://elearning.microchip.com.tw/modules/tad_link/index.php?cate_sn=1
https://page.microchip.com/APAC-PrefCenters-TW.html
http://www.microchip.com/
http://www.microchip.com/treelink
http://www.microchipdirect.com/
http://www.microchip.com.cn/newcommunity/index.php?m=Video&a=index&id=103
http://www.microchip.com.tw/modules/tad_uploader/index.php?of_cat_sn=2
http://www.microchip.com.tw/Data_CD/eLearning/index.html
http://www.microchip.com.tw/RTC/RTC_DVD/
https://www.microchip.com/development-tools/
https://www.youtube.com/user/MicrochipTechnology
[ more... ]

教育訓練中心

!開發工具購買
辦法說明 [業界客戶] [教育單位]
----------------------------------
!校園樣品申請
辦法說明 [教師資格] [學生資格]
----------------------------------