¿Puede SDA bajar de nivel al cambiar SCL de alto a bajo?

0

Actualmente estoy tratando de usar una nueva pantalla Haven (número de producto NHD-C0216CiZ-FN-FBW-3V) con un dispositivo i2c a usb. Estoy usando el código de bit banger de la documentación, enlace enlace , pero siempre que Envié un bit antiguo a I2C_Out Me chupo el bucle while, porque SDA nunca baja. Y veo que nunca recibí un agradecimiento de SDA. Si alguien sabe cómo resolver este problema, sería muy apreciado.

while(SDA==1){   
    SCL=0;   
    SCL=1;   
}

EDIT Pensé que el tiempo era de dos cortos entre el ajuste de SCL bajo y alto, así que agregué en un retraso de 1 segundo, pero todavía estoy siendo absorbido en un bucle infinito. También ya he intentado usar la función dada que el dispositivo i2c to usb me ofrece, pero esas funciones no funcionaban también, así que decidí usar el código bitbanger. La razón de esto es que con las funciones dadas desde el dispositivo, envía el i2c_start, luego envía los datos y luego envía el comando i2c_stop. Pero lo que necesito hacer es enviar el comando de inicio, luego un montón de comandos y luego el comando i2c_stop. Aquí está el código completo que estoy tratando de ejecutar

 void Show(unsigned char *text){  
    int n;  
    I2C_Start();  
    for(n=0;n<1;n++){   
        I2C_out(0x7C);  
        Delay(.05);
        I2C_out(0x40);  
        Delay(.05);
        I2C_out(*text);   
        ++text;   
    }  
    I2C_Stop(); 
}

void I2C_out(unsigned char j) {  
    BYTE value;
    int n, rc;  
    unsigned char d;  
    d=j;  
    for(n=0;n<8;n++){   
        if((d&0x80)==0x80)   
            rc = HidSmbus_WriteLatch(i2cDevice,0xFF,0x40); //SDA = 1   
        else   
            rc = HidSmbus_WriteLatch(i2cDevice,0,0x40); //SDA = 0  
        d=(d<<1);   
        Delay(.001);
        rc = HidSmbus_WriteLatch(i2cDevice,0,0x80); //Clock = 0   
        Delay(.001);
        rc = HidSmbus_WriteLatch(i2cDevice,0xFF,0x80); //Clock = 1  
        Delay(.001);
        rc = HidSmbus_WriteLatch(i2cDevice,0,0x80); //Clock = 0  
        Delay(.001);

    } 
    rc = HidSmbus_WriteLatch(i2cDevice,0xFF,0x80); //Clock = 1
    Delay(.001);
    rc = HidSmbus_ReadLatch(i2cDevice, &value);
    n = 116;
    while(((value &0x20)==0x20) && n--){
        rc = HidSmbus_WriteLatch(i2cDevice,0x00,0x80); //Clock = 0
        Delay(.001);
        rc = HidSmbus_WriteLatch(i2cDevice,0xFF,0x80); //Clock = 1 
        Delay(.001);
        //rc = HidSmbus_WriteLatch(i2cDevice,0x00,0x80); 
        rc = HidSmbus_ReadLatch(i2cDevice, &value);     
    }
    rc = HidSmbus_WriteLatch(i2cDevice,0,0x80); //Clock = 0 
}

void I2C_Stop(void) {  
    int rc;
    rc = HidSmbus_WriteLatch(i2cDevice,0,0x40); //SDA = 0
    rc = HidSmbus_WriteLatch(i2cDevice,0,0x80); //SCL = 0
    rc = HidSmbus_WriteLatch(i2cDevice,0xFF,0x80); //SCL = 1
    rc = HidSmbus_WriteLatch(i2cDevice,0xFF,0x40); //SDA = 1
}

void I2C_Start(void) {  
    int rc;
    rc = HidSmbus_WriteLatch(i2cDevice,0xFF,0x80);//pin 7 is clock  
    rc = HidSmbus_WriteLatch(i2cDevice,0xFF,0x40);//pin 6 is data
    rc = HidSmbus_WriteLatch(i2cDevice,0x00,0x40); //SDA = 0
    rc = HidSmbus_WriteLatch(i2cDevice,0x00,0x80); //SCL = 0
} 

void init_LCD(){ 
    I2C_Start();
    Delay(.05);
    I2C_out(0x7C); 
    Delay(.05);
    I2C_out(0x00); 
    Delay(.05);
    I2C_out(0x38); 
    Delay(0.10); 
    I2C_out(0x39); 
    Delay(0.10); 
    I2C_out(0x14); 
    Delay(.05);
    I2C_out(0x78); 
    Delay(.05);
    I2C_out(0x5E); 
    Delay(.05);
    I2C_out(0x6D); 
    Delay(.05);
    I2C_out(0x0E); 
    Delay(.05);
    I2C_out(0x01); 
    Delay(.05);
    I2C_out(0x06); 
    Delay(0.10); 
    I2C_Stop(); 
}

int BitBanger(){
    unsigned char text[]={"B"};
    int rc;
    BYTE dir, mode, special, clk;
    rc = HidSmbus_GetGpioConfig(i2cDevice, &dir, &mode, &special, &clk); 
    rc=HidSmbus_SetGpioConfig(i2cDevice, dir,0, 0, 0);
     init_LCD();
    Show(text); 

}
    
pregunta mohammed saleh

1 respuesta

1

El código que muestres no tiene sentido. No hay ninguna razón por la que se requiera que SDA disminuya después de un cierto número de pulsos de SCL.

No está claro lo que está intentando hacer, pero el código maestro IIC de bajo nivel nunca debe formar un bucle infinito. Si lo hace, eso es realmente una mala programación. Como el maestro controla el bus, realmente no hay nada que deba esperar. La única excepción es cuando cualquiera de los esclavos puede hacer estiramientos de reloj. En ese caso debería haber un tiempo muerto. Después de eso, el código debe intentar limpiar el bus y luego regresar con un error.

Tenga en cuenta que si no hay un esclavo ahí fuera, tiene la dirección equivocada, o si el esclavo no recibió correctamente el byte de la dirección, no se ACK. Sin embargo, ya sea ACK o no, no hay nada que esperar por el maestro. El bit ACK tiene una duración de un bit, y SDA es alto (NACK) o bajo (ACK).

De una forma u otra, necesita usar rutinas de IIC de bajo nivel competentes, ahora lo que muestra.

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas