ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
21 апреля
1511305
vesago (11.04.2025 14:00, просмотров: 2579)
А кто-нибудь применял такую связку stm32f103 + LL + i2c. Я сваял, но как-то на тонкого работает 
void I2C_Open(void)

{

LL_I2C_InitTypeDef I2C_InitStruct = {0};

LL_GPIO_InitTypeDef GPIO_InitStruct = {0};

LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);

GPIO_InitStruct.Pin = (SCL_PIN | SDA_PIN);

GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;

GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;

GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_OPENDRAIN;

LL_GPIO_Init(GPIOB, &GPIO_InitStruct);

LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);

LL_I2C_DisableOwnAddress2(I2C1);

LL_I2C_DisableGeneralCall(I2C1);

LL_I2C_EnableClockStretching(I2C1);

I2C_InitStruct.PeripheralMode = LL_I2C_MODE_I2C;

I2C_InitStruct.ClockSpeed = 100000ul;

I2C_InitStruct.DutyCycle = LL_I2C_DUTYCYCLE_2;

I2C_InitStruct.OwnAddress1 = 0;

I2C_InitStruct.TypeAcknowledge = LL_I2C_ACK;

I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT;

LL_I2C_Init(I2C1, &I2C_InitStruct);

LL_I2C_SetOwnAddress2(I2C1, 0);

}

void M24_ReadBytes (uint32_t addr, uint8_t *buf, uint16_t bytes_count)

{

uint16_t i;

uint8_t page_number = ((addr >> 16) & 3);

#ifdef I2C_WAIT_WRITE_ALLOW

while (i2c.timer != 0);

#endif

//Disable Pos

LL_I2C_DisableBitPOS(I2C1);

LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_ACK);

LL_I2C_GenerateStartCondition(I2C1);

while(!LL_I2C_IsActiveFlag_SB(I2C1)){};

//read state

(void) I2C1->SR1;

LL_I2C_TransmitData8(I2C1, (M24_ADDR | (page_number<<1) | I2C_REQUEST_WRITE));

while(!LL_I2C_IsActiveFlag_ADDR(I2C1)){};

LL_I2C_ClearFlag_ADDR(I2C1);

LL_I2C_TransmitData8(I2C1, (uint8_t) (addr>>8));

while(!LL_I2C_IsActiveFlag_TXE(I2C1)){};

LL_I2C_TransmitData8(I2C1, (uint8_t) addr);

while(!LL_I2C_IsActiveFlag_TXE(I2C1)){};

LL_I2C_GenerateStartCondition(I2C1);

while(!LL_I2C_IsActiveFlag_SB(I2C1)){};

(void) I2C1->SR1;

LL_I2C_TransmitData8(I2C1, (M24_ADDR | (page_number<<1) | I2C_REQUEST_READ));

while (!LL_I2C_IsActiveFlag_ADDR(I2C1)){};

LL_I2C_ClearFlag_ADDR(I2C1);

for(i=0;i<bytes_count;i++){

if(i<(bytes_count-1)){

while(!LL_I2C_IsActiveFlag_RXNE(I2C1)){};

buf[i] = LL_I2C_ReceiveData8(I2C1);

}else{

LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_NACK);

LL_I2C_GenerateStopCondition(I2C1);

while(!LL_I2C_IsActiveFlag_RXNE(I2C1)){};

buf[i] = LL_I2C_ReceiveData8(I2C1);

}

}

LL_I2C_DisableBitPOS(I2C1);

LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_ACK);

}


Если в конце функции чтения не поставить

LL_I2C_DisableBitPOS(I2C1);

LL_I2C_AcknowledgeNextData(I2C1, LL_I2C_ACK);

То вообще клинит. Ну и на частоте выше 100 кГц не работает. Подтяжка 2к. Понятно, можно осциллографом посмотреть. Или вообще на регистрах переписывать. Но может что подскажете? Простите. Не выходит как-то отформатировать красиво исходник.