Forum: Mikrocontroller und Digitale Elektronik I2C Funktionsproblem


von D. I. (Firma: Fa) (buell)


Lesenswert?

Hallo zusammen

Ich habe eine kurze Frage.
Ich habe mir das Manual zum I2C durchgelesen und wollte die 
Schnittstelle initialisieren und die entsprechenden Funktionen 
programmieren.

Dabei bin ich auf die Funktion unten gestossen. Was das Protokoll 
angeht, müsste man nun bei den Write und Read Funktionen so einiges 
überprüfen. Das scheint nun aber die Funktion unten alles abzudecken.
Ich bin nun etwas verwirrt. Was muss ich denn da noch programmieren, 
wenn ich diese Funktion nutze?
Es wird ja das Busy flag abgefragt, das Start bit gesetzt, und NByteSize 
berücksichtigt und am Ende das Stop bit gesetzt.
Was mir aber irgendwie fehlt ist, die Registeradresse des Device in 
dieser Funktion. Ich kann aber keine übergeben. Muss ich da selbst eine 
Funktion schreiben oder geht das irgendwie anders auch?

Ich habe das STM32L476RG Nucleo Board
1
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
2
{
3
  uint32_t tickstart = 0U;
4
5
  if(hi2c->State == HAL_I2C_STATE_READY)
6
  {
7
    /* Process Locked */
8
    __HAL_LOCK(hi2c);
9
10
    /* Init tickstart for timeout management*/
11
    tickstart = HAL_GetTick();
12
13
    if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY, tickstart) != HAL_OK)
14
    {
15
      return HAL_TIMEOUT;
16
    }
17
18
    hi2c->State     = HAL_I2C_STATE_BUSY_TX;
19
    hi2c->Mode      = HAL_I2C_MODE_MASTER;
20
    hi2c->ErrorCode = HAL_I2C_ERROR_NONE;
21
    
22
    /* Prepare transfer parameters */
23
    hi2c->pBuffPtr  = pData;
24
    hi2c->XferCount = Size;
25
    hi2c->XferISR   = NULL;
26
27
    /* Send Slave Address */
28
    /* Set NBYTES to write and reload if hi2c->XferCount > MAX_NBYTE_SIZE and generate RESTART */
29
    if(hi2c->XferCount > MAX_NBYTE_SIZE)
30
    {
31
      hi2c->XferSize = MAX_NBYTE_SIZE;
32
      I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_GENERATE_START_WRITE);
33
    }
34
    else
35
    {
36
      hi2c->XferSize = hi2c->XferCount;
37
      I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_GENERATE_START_WRITE);
38
    }
39
40
    while(hi2c->XferCount > 0U)
41
    {
42
      /* Wait until TXIS flag is set */
43
      if(I2C_WaitOnTXISFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
44
      {
45
        if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
46
        {
47
          return HAL_ERROR;
48
        }
49
        else
50
        {
51
          return HAL_TIMEOUT;
52
        }
53
      }
54
      /* Write data to TXDR */
55
      hi2c->Instance->TXDR = (*hi2c->pBuffPtr++);
56
      hi2c->XferCount--;
57
      hi2c->XferSize--;
58
59
      if((hi2c->XferSize == 0U) && (hi2c->XferCount!=0U))
60
      {
61
        /* Wait until TCR flag is set */
62
        if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_TCR, RESET, Timeout, tickstart) != HAL_OK)
63
        {
64
          return HAL_TIMEOUT;
65
        }
66
67
        if(hi2c->XferCount > MAX_NBYTE_SIZE)
68
        {
69
          hi2c->XferSize = MAX_NBYTE_SIZE;
70
          I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_RELOAD_MODE, I2C_NO_STARTSTOP);
71
        }
72
        else
73
        {
74
          hi2c->XferSize = hi2c->XferCount;
75
          I2C_TransferConfig(hi2c, DevAddress, hi2c->XferSize, I2C_AUTOEND_MODE, I2C_NO_STARTSTOP);
76
        }
77
      }
78
    }
79
80
    /* No need to Check TC flag, with AUTOEND mode the stop is automatically generated */
81
    /* Wait until STOPF flag is set */
82
    if(I2C_WaitOnSTOPFlagUntilTimeout(hi2c, Timeout, tickstart) != HAL_OK)
83
    {
84
      if(hi2c->ErrorCode == HAL_I2C_ERROR_AF)
85
      {
86
        return HAL_ERROR;
87
      }
88
      else
89
      {
90
        return HAL_TIMEOUT;
91
      }
92
    }
93
94
    /* Clear STOP Flag */
95
    __HAL_I2C_CLEAR_FLAG(hi2c, I2C_FLAG_STOPF);
96
97
    /* Clear Configuration Register 2 */
98
    I2C_RESET_CR2(hi2c);
99
100
    hi2c->State = HAL_I2C_STATE_READY;
101
    hi2c->Mode  = HAL_I2C_MODE_NONE;
102
103
    /* Process Unlocked */
104
    __HAL_UNLOCK(hi2c);
105
106
    return HAL_OK;
107
  }
108
  else
109
  {
110
    return HAL_BUSY;
111
  }
112
}

von grundschüler (Gast)


Lesenswert?

D. I. schrieb:
> Was mir aber irgendwie fehlt ist, die Registeradresse des Device in
> dieser Funktion.

je nach modul die ersten Werte in 'uint8_t *pData'

von Karl M. (Gast)


Lesenswert?

Hallo,

hilf mir bitte, ich finde nicht "das Manual zum I2C".

von D. I. (Firma: Fa) (buell)


Lesenswert?

grundschüler schrieb:
> D. I. schrieb:
>> Was mir aber irgendwie fehlt ist, die Registeradresse des Device in
>> dieser Funktion.
>
> je nach modul die ersten Werte in 'uint8_t *pData'

Vielen Dank
Also das klingt jetzt sicher etwas dumm, aber dann brauch ich mich 
wirklich auch protokollmässig um nichts mehr kümmern. Da ist mir in 
diesem Falle einiges Arbeit abgenommen worden?

von D. I. (Firma: Fa) (buell)


Lesenswert?


Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.