Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

Sterownik do szyny i2c dla 8051 nie działa poprawnie.

nuah 30 Sep 2006 15:23 1646 2
  • #1
    nuah
    Level 2  
    Hi napisalem sterownik do szyny i2c dla at89c2051 ale niestety nie dziala poprawnie. Steruje poprzez i2c pcf8574ap. Wysylam poprawny adres i dane ale dopiero po zresetowaniu uC dwa uklad wysyla potwierdzenie bitu i tym samym chce wspolpracowac.


    #include <at89x051.h>
    #define READ 1
    #define WRITE 0
    #define SDA P1_0
    #define SCL P1_1
    #define DELAY 2
    #define ACK_ERR P3_1
    #define FALSE 0
    void i2cclear(void);
    void i2cdelay(void);
    void i2cclkh(void);
    void i2cclkl(void);
    void i2cstart(void);
    void i2cstop(void);
    void i2cack(void);
    void i2csendbyte(char);
    void i2csendaddr(char,char);
    char i2cgetbyte(void);

    void i2cclear() {
    SDA=0;
    SCL=0;
    ACK_ERR=0;
    }

    void i2cdelay(void) {
    int a;
    for(a=0;a<DELAY;a++) ;
    // for(b=0;b<DELAY/2;b++);
    }

    void i2cclkh() {
    SCL=1;
    }

    void i2cclkl() {
    SCL=0;
    }

    void i2cstart() {
    SDA=1;
    SCL=1; i2cdelay();
    SDA=0;
    // SCL=0; i2cdelay();
    }
    void i2cstop() {
    SCL=0; i2cdelay();
    SDA=0;
    SCL=1; i2cdelay();
    SDA=1;
    }



    void i2cack() {

    i2cclkl(); i2cdelay();
    SDA=1; i2cdelay();
    i2cclkh(); i2cdelay();

    }


    void i2csendbyte(char byte) {
    int a;
    for(a=0;a<8;a++){
    i2cclkl(); i2cdelay();
    SDA=byte & 0x80;
    i2cclkh(); i2cdelay();
    byte=byte<<1;
    }
    i2cclkl(); i2cdelay();
    SDA=1;
    i2cclkh(); i2cdelay();
    if(SDA) ACK_ERR=1;

    }
    void i2csendaddr(char addr,char mode) {
    i2csendbyte(addr+mode);
    }

    char i2cgetbyte(void){
    int a;
    char byte=0;
    for(a=0;a<8;a++) {
    i2cclkh(); i2cdelay();
    if(SDA) byte++;
    byte *= 2;
    i2cclkl();i2cdelay();
    }
    SDA=0;
    i2cdelay();

    i2cclkh();
    i2cdelay();
    i2cclkl();i2cdelay();
    return(byte);
    }

    void main() {
    i2cclear();i2cdelay();
    i2cstart();
    i2csendbyte(0x70);
    i2csendbyte(0x01);
    i2csendbyte(0x02);
    i2csendbyte(0x03);
    i2cstop();i2cdelay();
    i2cclear();
    }

    oto kod, pozdrawiam

    Dodano po 6 [minuty]:

    aj... zjadlo mi wyraz;/ chodzi oto, ze musze uC zresetowac 2 razy i dopiero wtedy pcf8574 chce wspolpracowac.
  • #2
    m8se
    Level 15  
    Spróbowałbym zamienić

    SDA=byte & 0x80;

    na

    SDA=(byte & 0x80)>>7;

    albo może

    if (byte & 0x80) SDA=1; else SDA=0;

    i zobaczył czy coś się zmieniło.
  • #3
    nuah
    Level 2  
    Ok, problem rozwiazany. chodzilo o ilosc taktow scl poprostu byla i jeden impuls za mala.
    Moj aktualny, sprawny kod:
    #include <at89x051.h>
    #define READ 1
    #define WRITE 0
    #define SDA P1_0
    #define SCL P1_1
    #define DELAY 2
    #define ACK_ERR P1_7
    #define FALSE 0
    #define SCL_H SCL=1;i2cdelay();
    #define SCL_L SCL=0;i2cdelay();
    void i2cclear(void);
    void i2cdelay(void);
    void i2cstart(void);
    void i2cstop(void);
    void i2cack(void);
    void i2csendbyte(unsigned char);
    void i2csendaddr(unsigned char,unsigned char);
    unsigned char i2cgetbyte(unsigned char);

    void i2cclear() {
    SDA=0;
    SCL_L;
    ACK_ERR=0;
    }

    void i2cdelay(void) {
    int a;
    for(a=0;a<DELAY;a++) ;
    // for(b=0;b<DELAY/2;b++);
    }

    void i2cstart() {
    SDA=1;
    SCL_H;
    SDA=0; i2cdelay();
    SCL_L;
    // SCL=0; i2cdelay();
    }



    void i2cstop() {
    if(SCL) SCL_L;
    SDA=0;
    SCL_H;
    SDA=1;
    }

    void i2cack() {

    if(SCL) SCL_L;
    SDA=1;
    SCL_H;
    SCL_L;
    }


    void i2csendbyte(unsigned char byte) {
    int a;
    for(a=0;a<8;a++){
    if(SCL) SCL_L;
    if(byte & 0x80) SDA=1;
    else SDA=0;
    SCL_H;
    byte=byte<<1;
    }
    i2cack();
    if(SDA) ACK_ERR=1;


    }
    void i2csendaddr(unsigned char addr,unsigned char mode) {
    i2csendbyte(addr+mode);
    }

    unsigned char i2cgetbyte(unsigned char lastone){
    int a;
    unsigned char byte=0;
    for(a=0;a<8;a++) {
    SCL_H;
    byte *=2;
    if(SDA) byte++;
    SCL_L;
    }
    P3=byte;
    SDA=lastone;
    SCL_H;
    SCL_L;
    return(byte);
    }

    void main() {
    void main() {
    unsigned char a=0;
    //int b;
    P3=0;
    i2cstart();
    i2csendaddr(0x70,READ);
    a=i2cgetbyte(1);
    // P3=a;

    // byte=i2cgetbyte();
    // P3=byte;
    // for(a=0;a<16;a++) {
    // i2csendbyte(a);
    // for(b=0;b<1000;b++)
    // i2cdelay();
    // }
    // i2csendbyte(0x02);
    // i2csendbyte(0x03);
    i2cstop();
    while(1);
    }
    pzdrawiam