Hallo miteinander Ich möchte ein wenig mit dem I2C der STM-Familie herumspielen, aber bisher leider ohne Erfolg. Beim Versuch etwas zu senden oder Empfangen ist das Modul immer busy, ohne das etwas gemacht wird. Ich habe mich nun schon seit 3 Tagen an diesem ding generft. Vieleicht fällt einem ja auf, was falsch ist:
1 | void HMC5883L_init(void) |
2 | {
|
3 | GPIO_InitTypeDef GPIO_InitStructure; |
4 | I2C_InitTypeDef I2C_InitStructure; |
5 | |
6 | // write CONFIG_A register
|
7 | uint8_t tmp = (HMC5883L_AVERAGING_8 << (HMC5883L_CRA_AVERAGE_BIT - HMC5883L_CRA_AVERAGE_LENGTH + 1)) | |
8 | (HMC5883L_RATE_15 << (HMC5883L_CRA_RATE_BIT - HMC5883L_CRA_RATE_LENGTH + 1)) | |
9 | (HMC5883L_BIAS_NORMAL << (HMC5883L_CRA_BIAS_BIT - HMC5883L_CRA_BIAS_LENGTH + 1)) ; |
10 | |
11 | // Enable clock
|
12 | RCC_APB1PeriphClockCmd(HMC5883L_I2C_RCC_Periph, ENABLE); |
13 | RCC_AHB1PeriphClockCmd(HMC5883L_I2C_RCC_Port, ENABLE); |
14 | |
15 | // Performing a Reset
|
16 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); |
17 | RCC_APB1PeriphResetCmd(HMC5883L_I2C_RCC_Periph, ENABLE); |
18 | RCC_APB1PeriphResetCmd(HMC5883L_I2C_RCC_Periph, DISABLE); |
19 | |
20 | // Connect Pins to AF function
|
21 | GPIO_PinAFConfig(HMC5883L_I2C_Port, HMC5883L_I2C_SCL_Pin, HMC5883L_I2C_SCL_AF); |
22 | GPIO_PinAFConfig(HMC5883L_I2C_Port, HMC5883L_I2C_SDA_Pin, HMC5883L_I2C_SDA_AF); |
23 | |
24 | // Configure I2C SCL Pin(Pin10), SDA Pin (pin11)
|
25 | GPIO_InitStructure.GPIO_Pin = HMC5883L_I2C_SCL_Pin | HMC5883L_I2C_SDA_Pin; |
26 | GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; |
27 | GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; |
28 | GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; |
29 | GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; |
30 | GPIO_Init(HMC5883L_I2C_Port, &GPIO_InitStructure); |
31 | |
32 | // Configure I2C
|
33 | I2C_DeInit(HMC5883L_I2C); |
34 | I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; // I2C mode |
35 | I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // 50% duty cycle -> standard |
36 | I2C_InitStructure.I2C_OwnAddress1 = 0; // not relevant in master mode |
37 | I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; |
38 | I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; // Set address length to 7 bit addresses |
39 | I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; |
40 | I2C_Init(HMC5883L_I2C, &I2C_InitStructure); |
41 | |
42 | /*ENABLE*/
|
43 | I2C_Cmd(HMC5883L_I2C, ENABLE); |
44 | |
45 | HMC5883L_I2C_ByteWrite(HMC5883L_DEFAULT_ADDRESS, &tmp ,HMC5883L_RA_CONFIG_A); // <== Hier hängt er sich auf |
46 | }
|
1 | void HMC5883L_I2C_ByteWrite(uint8_t slaveAddr, uint8_t* pBuffer, uint8_t WriteAddr) |
2 | {
|
3 | // Diese Schlaufe wird nie verlassen
|
4 | while(I2C_GetFlagStatus(HMC5883L_I2C, I2C_FLAG_BUSY)); // wait until I2C is not busy anymore |
5 | |
6 | /* Send START condition */
|
7 | I2C_GenerateSTART(HMC5883L_I2C, ENABLE); |
8 | |
9 | /* Test on EV5 and clear it */
|
10 | while(!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_MODE_SELECT)); |
11 | |
12 | /* Send HMC5883 address for write */
|
13 | I2C_Send7bitAddress(HMC5883L_I2C, slaveAddr, I2C_Direction_Transmitter); |
14 | |
15 | /* Test on EV6 and clear it */
|
16 | while(!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); |
17 | |
18 | /* Send the HMC5883L internal address to write to */
|
19 | I2C_SendData(HMC5883L_I2C, WriteAddr); |
20 | |
21 | /* Test on EV8 and clear it */
|
22 | while(!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); |
23 | |
24 | /* Send the byte to be written */
|
25 | I2C_SendData(HMC5883L_I2C, *pBuffer); |
26 | |
27 | /* Test on EV8 and clear it */
|
28 | while(!I2C_CheckEvent(HMC5883L_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); |
29 | |
30 | /* Send STOP condition */
|
31 | I2C_GenerateSTOP(HMC5883L_I2C, ENABLE); |
32 | }
|
Testweise habe ich die I2C-Lib etwas angepasst:
1 | FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG) |
2 | {
|
3 | FlagStatus bitstatus = RESET; |
4 | __IO uint32_t i2creg = 0, i2cxbase = 0; |
5 | uint32_t SR1 = 0, SR2 = 0; |
6 | /* Check the parameters */
|
7 | assert_param(IS_I2C_ALL_PERIPH(I2Cx)); |
8 | assert_param(IS_I2C_GET_FLAG(I2C_FLAG)); |
9 | |
10 | /* Get the I2Cx peripheral base address */
|
11 | i2cxbase = (uint32_t)I2Cx; |
12 | |
13 | /* Read flag register index */
|
14 | i2creg = I2C_FLAG >> 28; |
15 | |
16 | /* Get bit[23:0] of the flag */
|
17 | I2C_FLAG &= FLAG_MASK; |
18 | |
19 | if(i2creg != 0) |
20 | {
|
21 | /* Get the I2Cx SR1 register address */
|
22 | i2cxbase += 0x14; |
23 | }
|
24 | else
|
25 | {
|
26 | /* Flag in I2Cx SR2 Register */
|
27 | I2C_FLAG = (uint32_t)(I2C_FLAG >> 16); |
28 | /* Get the I2Cx SR2 register address */
|
29 | i2cxbase += 0x18; |
30 | }
|
31 | SR1 = (*(__IO uint32_t *) (i2cxbase - 0x18 + 0x14)); |
32 | SR2 = (*(__IO uint32_t *)i2cxbase); |
33 | if(((*(__IO uint32_t *)i2cxbase) & I2C_FLAG) != (uint32_t)RESET) |
34 | {
|
35 | /* I2C_FLAG is set */
|
36 | bitstatus = SET; |
37 | }
|
38 | else
|
39 | {
|
40 | /* I2C_FLAG is reset */
|
41 | bitstatus = RESET; |
42 | }
|
43 | |
44 | /* Return the I2C_FLAG status */
|
45 | return bitstatus; |
46 | }
|
SR1 = 0; SR2 = 2; -> Busy Flag ist gesetzt Was habe ich falsch gemacht? Besten Dank für die Hilfe MFG Patrick