Forum: Mikrocontroller und Digitale Elektronik STM32: I2C-Error-Handling IRQ wird nicht aufgerufen


von mh (Gast)


Lesenswert?

Hallo,
ich ärger mich mal wieder mit dem I2C des STM32F103 rum.
Er springt bei einem Acknowledge-Failure einfach nicht in die 
Error-IRQ-Routine.
Weiß jemand woran das liegen könnte?
Schonmal vielen Dank für Anregungen.

Hier noch der Code:

Init:
1
void i2c_init(void)
2
{
3
  GPIO_InitTypeDef GPIO_InitStructure;
4
  I2C_InitTypeDef I2C_InitStructure;
5
  NVIC_InitTypeDef NVIC_InitStructure;
6
  DMA_InitTypeDef DMA_InitStructure;
7
8
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
9
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
10
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
11
12
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
13
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
14
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
15
  GPIO_Init(GPIOB, &GPIO_InitStructure);
16
17
  I2C_DeInit(I2C1);
18
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
19
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
20
  I2C_InitStructure.I2C_ClockSpeed = 80000;
21
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
22
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
23
  I2C_InitStructure.I2C_OwnAddress1 = 0;
24
  I2C_Init(I2C1, &I2C_InitStructure);
25
26
  I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
27
  I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);
28
29
  I2C_Cmd(I2C1, ENABLE);
30
31
  I2C_DMACmd(I2C1, ENABLE);
32
33
  NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
34
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
35
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
36
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
37
  NVIC_Init(&NVIC_InitStructure);
38
39
  // DMA Channel 6 - I2C1 TX
40
  DMA_InitStructure.DMA_BufferSize = 0;
41
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
42
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
43
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) i2c_tx_buffer;
44
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
45
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
46
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
47
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & I2C1->DR;
48
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
49
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
50
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
51
  DMA_Init(DMA1_Channel6, &DMA_InitStructure);
52
53
  // DMA Channel 7 - I2C1 RX
54
  DMA_InitStructure.DMA_BufferSize = 0;
55
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
56
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
57
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) i2c_rx_buffer;
58
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
59
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
60
  DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
61
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & I2C1->DR;
62
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
63
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
64
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
65
  DMA_Init(DMA1_Channel7, &DMA_InitStructure);
66
67
  DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);
68
69
  NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;
70
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
71
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
72
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
73
  NVIC_Init(&NVIC_InitStructure);
74
75
  i2c_BusyFlag = 0;
76
  bldc_communication_enable = 0;
77
  bldc_communication_BusyFlag = 0;
78
}

Funktionen zur Interaktion mit dem I2C:
1
void i2c_send_data(uint8_t address, uint8_t data)
2
{
3
  while(i2c_BusyFlag);
4
  i2c_BusyFlag = 1;
5
6
  i2c_deviceAddress = address;
7
8
  i2c_tx_buffer[0] = data;
9
10
  i2c_DirectionWrite = 1;
11
  DMA_SetCurrDataCounter(DMA1_Channel6, 1);    // TX
12
  I2C_GenerateSTART(I2C1, ENABLE);
13
}
14
15
void i2c_read_data(uint8_t address, uint8_t size)
16
{
17
  while(i2c_BusyFlag);
18
  i2c_BusyFlag = 1;
19
20
  i2c_deviceAddress = address;
21
22
  i2c_DirectionWrite = 0;
23
  DMA_SetCurrDataCounter(DMA1_Channel7, size);  // RX
24
  I2C_GenerateSTART(I2C1, ENABLE);
25
}


IRQs:
1
void I2C1_EV_IRQHandler(void)
2
{
3
  if (I2C_GetFlagStatus(I2C1, I2C_FLAG_SB) == SET)  // Start bit gesendet
4
  {
5
    if(i2c_DirectionWrite)              // STM32 Transmitter
6
      I2C_Send7bitAddress(I2C1, i2c_deviceAddress, I2C_Direction_Transmitter);
7
    else                      // STM32 Receiver
8
      I2C_Send7bitAddress(I2C1, i2c_deviceAddress, I2C_Direction_Receiver);
9
  }
10
  else if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED) == SUCCESS ||
11
      I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED) == SUCCESS)  // entspricht EV6
12
  {
13
    if (i2c_DirectionWrite)              // STM32 Transmitter
14
    {
15
      DMA_Cmd(DMA1_Channel6, ENABLE);
16
    }
17
    else                      // STM32 Receiver
18
    {
19
      I2C_DMALastTransferCmd(I2C1, ENABLE);
20
      DMA_Cmd(DMA1_Channel7, ENABLE);
21
    }
22
  }
23
  else if(I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF))    // Byte transfer finished
24
  {
25
    if(i2c_DirectionWrite)              // STM32 Transmitter
26
    {
27
      I2C_GenerateSTOP(I2C1, ENABLE);
28
      DMA_Cmd(DMA1_Channel6, DISABLE);
29
      i2c_BusyFlag = 0;
30
    }
31
  }
32
}
33
34
35
void DMA1_Channel7_IRQHandler(void)
36
{
37
  DMA_ClearFlag(DMA1_FLAG_TC7);
38
  I2C_GenerateSTOP(I2C1, ENABLE);
39
  DMA_Cmd(DMA1_Channel7, DISABLE);
40
  i2c_BusyFlag = 0;
41
}
42
43
44
45
46
void I2C1_ER_IRQHandler(void)
47
{
48
  I2C_GenerateSTOP(I2C1, ENABLE);
49
50
  I2C_ClearFlag(I2C1, I2C_FLAG_AF);
51
  I2C_ClearFlag(I2C1, I2C_FLAG_ARLO);
52
  I2C_ClearFlag(I2C1, I2C_FLAG_BERR);
53
54
  i2c_BusyFlag = 0;
55
}

von Jim M. (turboj)


Lesenswert?

Ich sehe keine Aktivierung des ER Interrupts im NVIC.

von mh (Gast)


Lesenswert?

Oman....
Stimmt, habs ergänzt und jetzt gehts.
Vielen Dank!!!

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.