Direccionamiento de registros con bibliotecas HAL I2C STM32F0

7

Soy muy nuevo en el uso de CUBE y HAL_libraries de STM. Estoy usando un microcontrolador STM32F0 con 32 pines. El esquema para I2C es correcto. Así que necesito un poco de ayuda aquí.

Tengo un sensor capacitivo ( FDC1004 ) que utiliza la comunicación I2C. Tengo que escribir estos registros para leer los datos.

¿Cómo puedo enviar correctamente el formulario de solicitud de INICIO maestro al esclavo (la dirección del esclavo es A0)?

¿Cómo establecer el puntero en el registro 0x0C?

  • La hoja de datos ve (Registro 0x0C: bit [7: 4]) a 1.) No sé, ¿cómo hacerlo? Y finalmente, ¿cómo LEER desde el mismo registro?
  • Además, tengo que esperar el campo DONE_x (registro 0x0C: bits [3: 0]) antes de leerlo.

¡Pero no sé si me dirijo a los registros correctos! ¡Porque no recupero ningún dato del sensor!

Aquí está mi código:

int I2Ccomm ()
{

    HAL_I2C_Master_Transmit(&hi2c1,0xA1,0x0C, 10, 100); //start bit and pointer to register
    HAL_Delay(50);
    HAL_I2C_Master_Transmit(&hi2c1,0xA1,0x054, 10, 100); // setting the register
    HAL_Delay(50);

    HAL_I2C_Master_Receive(&hi2c1, 0xA0, 0x0C, 10, 100); //read from this register
    HAL_Delay(50);
    HAL_I2C_Master_Receive(&hi2c1, 0xA0, 0x02, 10, 100); //read data from register

    return ReadREG[1];
}
    
pregunta yest111

1 respuesta

11

Comencemos con la función HAL_I2C_Master_Transmit() . Si verifica su declaración:

 HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
  1. Problema menor con el parámetro 2do , la dirección del dispositivo esclavo. La dirección del dispositivo esclavo es b1010000 si lo completamos en formato de 8 bits, será 0xA0 , tal como lo ha dicho. Ahora, al pasar esto a HAL_I2C_Master_Transmit() , no tiene que configurar el bit R / W manualmente, HAL lo hará por usted. Por lo tanto, cuando llame a HAL_I2C_Master_Transmit() , el bit R / W transmitido será automáticamente 0 indicando operación de escritura y cuando llame a HAL_I2C_Master_Receive() , el bit R / W transmitido será automáticamente 1 indicando escritura operación . Ha mezclado los valores de R / W pero creo que es un bit de no importa para la función, por lo que no es un error real en su código.

  2. El parámetro 3º ( uint8_t *pData ) es un puntero a un búfer que contiene los datos que se enviarán . Ahora, en su llamada, el parámetro 3er es 0x0C , que son sus datos reales, la dirección de registro. El problema es que se interpretará como un puntero (por el HAL_I2C_Master_Transmit() ) a una ubicación de memoria, donde se pueden encontrar algunos datos no definidos.

  3. El parámetro 4º es el tamaño del búfer , el número de bytes que se enviarán. Si desea enviar un byte único , este parámetro debe ser 1 y no 10.

Cuando trabaje con \ $ \ small I ^ 2C \ $ lo mejor que puede hacer es obtener la hoja de datos del dispositivo esclavo y buscar la documentación de las operaciones de escritura y lectura.

Escribir registros

Aquí está el diagrama correspondiente de la hoja de datos.

Entonces,despuésdeenviarladireccióndeesclavoalbus,sedebentransmitirtresbytesmás:punteroderegistro,byteMSB,byteLSB.UnaimplementacióngeneralconHALescribiendoregistrosde16bits:

voidwrite_register(uint8_tregister_pointer,uint16_tregister_value){uint8_tdata[3];data[0]=register_pointer;//0x0Cinyourexampledata[1]=register_value>>8;//MSBbyteof16bitdatadata[2]=register_value;//LSBbyteof16bitdataHAL_I2C_Master_Transmit(&hi2c1,0xA0,data,3,100);//dataisthestartpointerofourarray}

Ejemploconsusvalores:write_register(0x0C,0x0054);

Comoalternativa,tambiénsepuedeutilizarlafuncióndeescrituraderegistrodefinidaporHAL,quetieneparámetrosadicionalesparapasarladirecciónderegistroyeltamañodeladirección.

voidwrite_reg(uint8_tregister_pointer,uint16_tregister_value){HAL_StatusTypeDefstatus=HAL_OK;status=HAL_I2C_Mem_Write(&hi2c1,0xA0,(uint16_t)register_pointer,I2C_MEMADD_SIZE_8BIT,(uint8_t*)(&register_value),2,100);/*Checkthecommunicationstatus*/if(status!=HAL_OK){//Errorhandling,forexamplere-initializationoftheI2Cperipheral}}

Ahora,lafunciónHAL_I2C_Master_Receive()escasilamismaquelaotra.

HAL_StatusTypeDefHAL_I2C_Master_Receive(I2C_HandleTypeDef*hi2c,uint16_tDevAddress,uint8_t*pData,uint16_tSize,uint32_tTimeout);

Laúnicadiferenciaesqueelparámetro3eresunpunteroalbúferdondesealmacenaránlosdatosrecibidos.Está0x02ensucódigoynosécuálfuesupropósitoconél,peroseinterpretarácomounpuntero(desafortunadamenteaunaubicacióndememoriaaleatoria).

Leerregistros

Paraleerunregistro,debeseleccionarseconunaoperacióndeescritura\$\smallI^2C\$enviandoelpunteroderegistroadecuado(tengaencuentaquesihaescritoesteregistrojustoantesdelalectura,notienequeenviarlo).denuevosudirecciónalregistrodepunteros,comoyalohaconfiguradodurantelaescritura).Luego,conunaoperacióndelectura\$\smallI^2C\$,vuelvaaleerlosdatosde16bits.

voidread_register(uint8_tregister_pointer,uint8_t*receive_buffer){//firstsettheregisterpointertotheregisterwantedtobereadHAL_I2C_Master_Transmit(&hi2c1,0xA0,&register_pointer,1,100);//notethe&operatorwhichgivesustheaddressoftheregister_pointervariable//receivethe2x8bitdataintothereceivebufferHAL_I2C_Master_Receive(&hi2c1,0xA0,receive_buffer,2,100);}

Ejemplo:

uint8_treg_ptr=0x0C;uint8_tbuffer[2];read_register(reg_ptr,buffer);//theregistercontentavailableinthebuffer

TambiénhayunafuncióndelecturaderegistrodefinidaporHAL,quetiene.

uint16_tread_reg(uint8_tregister_pointer){HAL_StatusTypeDefstatus=HAL_OK;uint16_treturn_value=0;status=HAL_I2C_Mem_Read(&hi2c1,0xA0,(uint16_t)register_pointer,I2C_MEMADD_SIZE_8BIT,&return_value,2,100);/*Checkthecommunicationstatus*/if(status!=HAL_OK){}returnreturn_value;}

Lealasección8.5Programacióndela hoja de datos para obtener más información detalles.

    
respondido por el Bence Kaulics

Lea otras preguntas en las etiquetas