Cortex M3 I2C timingproblem

OP #2376348
Lesenswert?

Hi Leute, ich habe ein Timingproblem bei der Programmierung des I2C Bus 
des Cortex M3:
Ich flashe das Programm mit Eqlipse im Debugmodus auf meinen Cortex. Das 
Ergebnis schaue ich mir mit Hilfe des ARRDVARK auf meinem Rechner an. 
Wenn ich nun in meinem GoEther() Task über den I2C Bus ein Datenarray 
verschicken möchte, dann funktioniert es nur, wenn ich nach jedem Byte 
eine kleine Wartezeit einbaue. Das verstehe ich schon mal nicht so 
richtig. Das wirkliche seltsame ist aber, dass das Programm nicht läuft, 
sobald ich den Controller "alleine" starte, also mit Reset, oder einfach 
so an die Spannung anschliesse. Es funktioniert nur, direkt nach dem 
Eqlipse flashen.
Hat jemand eine Erklärung dafür?
Zum Code:
ich poste meinen gesammten Code, nicht wundern, ich möchte mit meinem 
Controller später noch  einen ENC28J60 ansteuern, zusätzlich spielt CAN 
auch noch eine Rolle. Deshalb sind da Codefragmente darin, die nichts 
mit I2C zu tun haben, ich dachte mir aber ich lasse mal alles drinn, 
vielleicht spielen sie eine Rolle für das Timing....

Hier die I2C Codes:
1
/**
2
  * @brief  Initialize all stuff you need for I2C
3
  * @retval None.
4
  */
5
void I2C_config(void)
6
{
7
  I2C_InitTypeDef  I2C_InitStructure1;
8
  I2C_InitTypeDef  I2C_InitStructure2;
9

10
 //zuerste I2C1 initialisieren------------------------------------------------
11
  I2C_DeInit(I2C1);
12

13
  /* I2C configuration */
14
  I2C_InitStructure1.I2C_Mode = I2C_Mode_I2C;
15
  I2C_InitStructure1.I2C_DutyCycle = I2C_DutyCycle_2;
16
  I2C_InitStructure1.I2C_OwnAddress1 = I2C1_SLAVE_ADDRESS7;
17
  I2C_InitStructure1.I2C_Ack = I2C_Ack_Enable;
18
  I2C_InitStructure1.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
19
  I2C_InitStructure1.I2C_ClockSpeed = I2C_Speed;
20

21

22
  /* Apply I2C configuration (war in der vorlage erst nach I2C_Cmd()) */
23
  I2C_Init(I2C1, &I2C_InitStructure1);
24
  /* I2C Peripheral Enable */
25
  I2C_Cmd(I2C1, ENABLE);
26

27
  //GPIO Configs
28
  GPIO_InitTypeDef  GPIO_InitStructure1;
29

30
   /* GPIOB clock enable */
31
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //??????????????wurde schon bei SPI Init erledigt
32
    /* I2C1 clock enable */
33
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
34

35
   /* Configure I2C1 pins: SCL and SDA to communicate with outside */
36
   GPIO_InitStructure1.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
37
   GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_50MHz;
38
   GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_AF_OD;
39
   GPIO_Init(GPIOB, &GPIO_InitStructure1);
40

41

42
   //danach I2C2 initialisieren------------------------------------------------
43
   I2C_DeInit(I2C2);
44

45
   // GPIOB clock enable  wurde oben schon erledigt
46
       // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
47
       // I2C2 clock enable
48
       RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);
49

50
    // I2C configuration
51
    I2C_InitStructure2.I2C_Mode = I2C_Mode_I2C;
52
    I2C_InitStructure2.I2C_DutyCycle = I2C_DutyCycle_2;
53
    I2C_InitStructure2.I2C_OwnAddress1 = I2C2_SLAVE_ADDRESS7;
54
    I2C_InitStructure2.I2C_Ack = I2C_Ack_Enable;
55
    I2C_InitStructure2.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
56
    I2C_InitStructure2.I2C_ClockSpeed = I2C_Speed;
57

58
    //Apply I2C configuration (war in der vorlage erst nach I2C_Cmd())
59
     I2C_Init(I2C2, &I2C_InitStructure2);
60
     // I2C Peripheral Enable
61
     I2C_Cmd(I2C2, ENABLE);
62

63
     //GPIO Configs
64
      GPIO_InitTypeDef  GPIO_InitStructure2;
65

66

67

68
   // Configure I2C2 pins: SCL and SDA for the administrative bus
69
    GPIO_InitStructure2.GPIO_Pin =  GPIO_Pin_10 | GPIO_Pin_11;
70
    GPIO_InitStructure2.GPIO_Speed = GPIO_Speed_50MHz;
71
    GPIO_InitStructure2.GPIO_Mode = GPIO_Mode_AF_OD;
72
    GPIO_Init(GPIOB, &GPIO_InitStructure2);
73

74

75
}
76

77

78
/**
79
  * @brief  Transmits one byte to  the  selected slave device.
80
  * @param  I2Cx: where x can be 1 or 2 to select the I2C peripheral.
81
  * @param  Address: specifies the slave address to which the data will be transmitted
82
  * @param  Data: the data byte which will be transmitted
83
  * @retval None.
84
  */
85
void I2C_Master_Transmit_Byte(I2C_TypeDef* I2Cx, uint8_t Adress, uint8_t Data)
86
{
87
  if(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
88
     I2C_GenerateSTOP(I2C1, ENABLE);
89

90
  // I2Cx->CR1 = 0xC01; /* ACK=1, POS =1, PE = 1  */
91
    /* Send STRAT condition */
92
      I2C_GenerateSTART(I2Cx, ENABLE);
93

94
       /* Test on EV5 and clear it */
95
      while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
96

97
      I2C_Send7bitAddress(I2C1, Adress, I2C_Direction_Transmitter);
98

99
      /* Test on EV6 and clear it */
100
       while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
101

102
       /*Send Data*/
103
       I2C_SendData(I2C1,Data);
104

105
       /* Test on EV8 and clear it */
106
      while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));
107

108
      /* Test on EV8_2 and clear it */
109
       //    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
110

111
      /* Send STOP condition */
112
         I2C_GenerateSTOP(I2C1, ENABLE);
113
}

und hier meine main:
1
#include "stm32f10x.h"
2
#include "FreeRTOSSource/FreeRTOS.h"
3
#include "FreeRTOSSource/task.h"
4
#include "lib/can.h"
5
#include "lib/outpin.h"
6
#include "lib/canids.h"
7
#include "lib/i2c.h"
8
#include "Std_lib/misc.h"
9
#include "Std_lib/stm32f10x_it.h"
10
#include "Std_lib/stm32f10x_rcc.h"
11
#include "Std_lib/stm32f10x_dma.h"
12
#include "lib/SPI.H"
13

14
#include "lib/enc28j60.h"
15

16

17
const unsigned char enc28j60_MAC[6] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
18
/**
19
 * FreeRTOS task prototypes.
20
 */
21

22
portTASK_FUNCTION(goEther, param);
23

24

25
portTASK_FUNCTION(vQueryCAN, param);
26

27
portTASK_FUNCTION(vBlinkLEDs, param);
28

29
/* Private define ------------------------------------------------------------*/
30

31

32
/* Private macro -------------------------------------------------------------*/
33
/* Private variables ---------------------------------------------------------*/
34

35
DMA_InitTypeDef DMA_InitStructure;
36

37

38
volatile portTickType lastErrorTimeStamp;
39
outpin_t led_ready, led_error, led_3,led_4, ready,sck;
40

41

42
/**
43
  * @brief  Configures NVIC and Vector Table base location.
44
  * @param  None
45
  * @retval : None
46
  */
47
void NVIC_Configuration(void)
48
{
49

50
    /* 1 bit for pre-emption priority, 3 bits for subpriority */
51
  //  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
52

53
    NVIC_SetPriority(I2C1_EV_IRQn, 0x00);
54
    NVIC_EnableIRQ(I2C1_EV_IRQn);
55

56
    NVIC_SetPriority(I2C1_ER_IRQn, 0x01);
57
    NVIC_EnableIRQ(I2C1_ER_IRQn);
58

59

60
    NVIC_SetPriority(I2C2_EV_IRQn, 0x00);
61
    NVIC_EnableIRQ(I2C2_EV_IRQn);
62

63
    NVIC_SetPriority(I2C2_ER_IRQn, 0x01);
64
    NVIC_EnableIRQ(I2C2_ER_IRQn);
65

66
}
67

68

69

70

71
///////////////////////////////////////////////////////////////////////////////
72
// MAIN
73
///////////////////////////////////////////////////////////////////////////////
74
int main(void) {
75

76
  outpin_init(&led_ready, 'C', 0);
77
  outpin_init(&ready, 'C', 14);
78
  outpin_init(&led_3, 'C', 2);
79
  outpin_init(&led_4, 'C', 3);
80
  outpin_init(&led_error, 'C', 1);
81

82

83
  // this sets up the oscilator
84
  SystemInit();
85
  // Initialization
86
  NVIC_Configuration();
87
  CAN_inits();
88
  SPI2_Init();
89
  I2C_config();
90

91

92
         //zu testzwecken
93
    outpin_enable(&led_3);
94
    outpin_enable(&led_4);
95
    outpin_enable(&led_error);
96
    
97

98
  enc28j60Init((unsigned char *)enc28j60_MAC);
99

100
    
101

102
  enc_powerdown();
103

104
  //initialization terminated
105
  outpin_enable(&ready);
106

107
  // launch CAN query task one priority level below
108
  xTaskCreate(vQueryCAN, (const int8_t*)"QCAN", 100, NULL, tskIDLE_PRIORITY, NULL);
109
  // launch blink
110
  xTaskCreate(vBlinkLEDs, (const int8_t*)"BLINK", 100, NULL, tskIDLE_PRIORITY, NULL);
111

112

113
  xTaskCreate(goEther, (const int8_t*)"Ether", 200, NULL, tskIDLE_PRIORITY, NULL);
114

115
  vTaskStartScheduler();
116
  return 0;
117
}
118

119

120
portTASK_FUNCTION(goEther, param) {
121
  outpin_t CS_Ether, MOSI, SCK;
122
  outpin_init(&CS_Ether, 'B', 12); // SS Ethernetmodul
123

124
  uint8_t buffer[16] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F};
125

126
    int i;
127

128
  for (i = 0;i<=15;i++)
129
  {
130
    int a = 1000;
131
         while(--a);
132
    I2C_Master_Transmit_Byte(I2C1,0x00,buffer[i]);
133
  }
134

135
  while (1) {
136
    
137

138
  }
139

140
}
141

142

143
/**
144
 * This task grabs actor messages from the CAN bus and forwards their
145
 * content.
146
 * ERROR messages are also evaluated.
147
 */portTASK_FUNCTION(vQueryCAN, param) {
148
  // Register all CAN ids that could contain interesting
149
  // messages.
150

151
  CAN_subscribeId(CANID_ERROR);
152

153
  uint32_t message;
154
  static float norm;
155
  static uint8_t brake;
156
  static portTickType timeStamp;
157

158
  while (1) {
159
    timeStamp = xTaskGetTickCount();
160

161
    if (CAN_receive(CANID_ERROR, &message)) {
162
      if (message == ERRORID_PWM_FREQUENCY || message
163
          == ERRORID_PWM_OUTOFBOUNDS || message
164
          == ERRORID_RECEIVER_NOSIGNAL)
165
        lastErrorTimeStamp = timeStamp;
166
    }
167
    // and sleep for 10ms before trying to fetch new messages again
168
    vTaskDelay(10 / portTICK_RATE_MS);
169
  }
170
}
171
/**
172
 * Task to blink the "RUNS" LED
173
 * Slow blinking for normal operation, fast for indicating some error.
174
 */portTASK_FUNCTION(vBlinkLEDs, param) {
175

176

177
  //outpin_init(&led_ready, 'C', 0);
178
  while (1) {
179
    outpin_toggle(&led_ready);
180
    if (xTaskGetTickCount() - lastErrorTimeStamp > 1000 / portTICK_RATE_MS) {
181
      // blink slow if ok
182
      vTaskDelay(250 / portTICK_RATE_MS);
183
      //for(int i=0;i<0xffff;i++){
184

185

186
    } else {
187
      // hectic blink if error present now or in the last second
188
      //for(int i=0;i<0xffff;i++);
189
      vTaskDelay(75 / portTICK_RATE_MS);
190

191
    }
192
  }
193
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren