Вт апр 28, 2015 18:31:17
/* Macros */
#define SET_BIT(REG, BIT) ((REG) |= (BIT))
#define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))
#define READ_BIT(REG, BIT) ((REG) & (BIT))
#define SET_REG(REG, VAL) ((REG) = (VAL))
#define CLEAR_REG(REG) ((REG) = (0))
#define READ_REG(REG) ((REG))
#define MODIFY_REG(REG, CLEARMASK, SETMASK) SET_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
/* Macros */
#define EEPROM_PAGE_SIZE 16
void I2C_EEPROM_Read(void);
uint32_t I2C_EEPROM_Write(void);
uint32_t I2C_EEPROM_WritePage(uint32_t argAddress, uint8_t *argData, uint32_t argDataSize);
/* I2C Initialization */
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN);
SET_BIT(RCC->CFGR3, RCC_CFGR3_I2C1SW);
MODIFY_REG(I2C1->TIMINGR,
I2C_TIMINGR_PRESC | I2C_TIMINGR_SCLDEL | I2C_TIMINGR_SDADEL | I2C_TIMINGR_SCLH | I2C_TIMINGR_SCLL,
(1 << 28) | (8 << 20) | (0 << 16) | (94 << 8) | (137 << 0)); /* 0x10805E89 */
/* I2C Initialization */
/* EEPROM */
I2C_EEPROM_Read();
if(globalData.firstRun != 13)
{
SB_Init();
while(I2C_EEPROM_Write() != 0);
}
/* EEPROM */
void I2C_EEPROM_Read(void)
{
uint8_t localDataBuf[sizeof(EEPROM_Data)];
uint32_t localCounter;
SET_BIT(I2C1->CR1, I2C_CR1_PE);
SET_REG(I2C1->CR2, (1 << 16) | I2C_CR2_START | 0xA0);
while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
SET_REG(I2C1->TXDR, 0x00);
while((I2C1->ISR & I2C_ISR_TC) != I2C_ISR_TC);
SET_REG(I2C1->CR2, I2C_CR2_AUTOEND | (sizeof(EEPROM_Data) << 16) | I2C_CR2_START | I2C_CR2_RD_WRN | 0xA0);
for(localCounter = 0; localCounter < sizeof(EEPROM_Data); localCounter++)
{
while((I2C1->ISR & I2C_ISR_RXNE) != I2C_ISR_RXNE);
localDataBuf[localCounter] = (uint8_t)I2C1->RXDR;
}
CLEAR_BIT(I2C1->CR1, I2C_CR1_PE);
memcpy(&globalData, localDataBuf, sizeof(EEPROM_Data));
}
uint32_t I2C_EEPROM_Write(void)
{
uint8_t localDataBuf[sizeof(EEPROM_Data)];
uint32_t localCounter;
uint32_t localLast;
uint32_t localOffset;
memcpy(localDataBuf, &globalData, sizeof(EEPROM_Data));
for(localCounter = 0; localCounter < (sizeof(EEPROM_Data) / EEPROM_PAGE_SIZE); localCounter++)
{
localOffset = localCounter * EEPROM_PAGE_SIZE;
if(I2C_EEPROM_WritePage(localOffset, &localDataBuf[localOffset], EEPROM_PAGE_SIZE) != 0)
{
return 1;
}
}
localLast = sizeof(EEPROM_Data) % EEPROM_PAGE_SIZE;
if(localLast > 0)
{
localOffset += EEPROM_PAGE_SIZE;
if(I2C_EEPROM_WritePage(localOffset, &localDataBuf[localOffset], localLast) != 0)
{
return 1;
}
}
return 0;
}
uint32_t I2C_EEPROM_WritePage(uint32_t argAddress, uint8_t *argData, uint32_t argDataSize)
{
uint32_t localCounter;
SET_BIT(I2C1->CR1, I2C_CR1_PE);
SET_REG(I2C1->CR2, I2C_CR2_RELOAD | (1 << 16) | I2C_CR2_START | 0xA0);
while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
SET_REG(I2C1->TXDR, argAddress);
while((I2C1->ISR & I2C_ISR_TCR) != I2C_ISR_TCR);
SET_REG(I2C1->CR2, I2C_CR2_AUTOEND | (argDataSize << 16) | 0xA0);
for(localCounter = 0; localCounter < argDataSize; localCounter++)
{
if((I2C1->ISR & I2C_ISR_NACKF) == I2C_ISR_NACKF)
{
CLEAR_BIT(I2C1->CR1, I2C_CR1_PE);
return 1;
}
while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
I2C1->TXDR = (uint32_t)argData[localCounter];
}
CLEAR_BIT(I2C1->CR1, I2C_CR1_PE);
return 0;
}
Пт май 01, 2015 06:11:42
Ср май 06, 2015 15:59:22
void I2C_Initialization(void)
{
RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
GPIOB->MODER |= GPIO_MODER_MODER9_1 | GPIO_MODER_MODER8_1;
GPIOB->OTYPER |= GPIO_OTYPER_OT_9 | GPIO_OTYPER_OT_8;
GPIOB->AFR[1] |= (1 << (1 * 4)) | (1 << (0 * 4));
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;
RCC->CFGR3 |= RCC_CFGR3_I2C1SW;
I2C1->TIMINGR = 0x10805E89;
I2C1->CR1 |= I2C_CR1_PE;
}
void I2C_EEPROMRead(void)
{
uint8_t localDataBuf[sizeof(EEPROM_Data)];
uint32_t localCounter;
I2C1->CR2 = (1 << 16) | I2C_CR2_START | 0xA0;
while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
I2C1->TXDR = 0;
while((I2C1->ISR & I2C_ISR_TC) != I2C_ISR_TC);
I2C1->CR2 = I2C_CR2_AUTOEND | (sizeof(EEPROM_Data) << 16) | I2C_CR2_START | I2C_CR2_RD_WRN | 0xA0;
for(localCounter = 0; localCounter < sizeof(EEPROM_Data); localCounter++)
{
while((I2C1->ISR & I2C_ISR_RXNE) != I2C_ISR_RXNE);
localDataBuf[localCounter] = (uint8_t)I2C1->RXDR;
}
SYSTICK_DelayMs(5);
memcpy(&globalData, localDataBuf, sizeof(EEPROM_Data));
}
void I2C_EEPROMWrite(void)
{
uint8_t localDataBuf[sizeof(EEPROM_Data)];
uint32_t localCounter1;
uint32_t localCounter2;
uint32_t localPtr;
memcpy(localDataBuf, &globalData, sizeof(EEPROM_Data));
localPtr = 0;
for(localCounter2 = 0; localCounter2 < (sizeof(EEPROM_Data) / EEPROM_PAGE_SIZE); localCounter2++)
{
I2C1->CR2 = I2C_CR2_RELOAD | (1 << 16) | I2C_CR2_START | 0xA0;
while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
I2C1->TXDR = localPtr;
while((I2C1->ISR & I2C_ISR_TCR) != I2C_ISR_TCR);
I2C1->CR2 = I2C_CR2_AUTOEND | (EEPROM_PAGE_SIZE << 16) | 0xA0;
for(localCounter1 = 0; localCounter1 < EEPROM_PAGE_SIZE; localCounter1++)
{
while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
I2C1->TXDR = (uint32_t)localDataBuf[localPtr];
localPtr++;
}
SYSTICK_DelayMs(5);
}
if(sizeof(EEPROM_Data) % EEPROM_PAGE_SIZE)
{
I2C1->CR2 = I2C_CR2_RELOAD | (1 << 16) | I2C_CR2_START | 0xA0;
while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
I2C1->TXDR = localPtr;
while((I2C1->ISR & I2C_ISR_TCR) != I2C_ISR_TCR);
I2C1->CR2 = I2C_CR2_AUTOEND | ((sizeof(EEPROM_Data) % EEPROM_PAGE_SIZE) << 16) | 0xA0;
for(localCounter1 = 0; localCounter1 < (sizeof(EEPROM_Data) % EEPROM_PAGE_SIZE); localCounter1++)
{
while((I2C1->ISR & I2C_ISR_TXIS) != I2C_ISR_TXIS);
I2C1->TXDR = (uint32_t)localDataBuf[localPtr];
localPtr++;
}
SYSTICK_DelayMs(5);
}
}
Ср май 06, 2015 19:58:53
Сб июн 01, 2019 13:36:55
MX_I2C1_Init();
uint8_t slave_address = 0xA0; // Адрес ведомого устройства в шине I2C (микросхема памяти EEprom)
uint16_t write_address = 0x0007; // Адрес в памяти EEprom, по которому будем записывать байт
uint8_t wr_byte = 0xA4; // Записывать будем такой байт
/* Запись байта.
* Номер I2C, по которому передавать данные, адрес ведомого устройства, к которому обращаемся, режим адресации 7 бит,
* количество передаваемых байт 3, после завершения передачи сгенерировать СТОП-сигнал,
* перед началом сгенерировать СТАРТ-сигнал с признаком записи байта
*/
LL_I2C_HandleTransfer(I2C1, slave_address , LL_I2C_ADDRSLAVE_7BIT, 3, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_WRITE);
while(!(LL_I2C_IsActiveFlag_TXE(I2C1)));
LL_I2C_TransmitData8(I2C1, (uint8_t)(write_address >> 16));
while(!(LL_I2C_IsActiveFlag_TXE(I2C1)));
LL_I2C_TransmitData8(I2C1, (uint8_t)(write_address));
while(!(LL_I2C_IsActiveFlag_TXE(I2C1)));
LL_I2C_TransmitData8(I2C1, wr_byte);
// Передача закончилась, автоматически сгенерирован СТОП-сигнал
HAL_Delay(3); // Ждем 3 мс, пока микросхема памяти прожует полученное.
uint16_t read_address = 0x0000; // Адрес в памяти EEprom, с которого начнем считывать байты (начнем с нуля)
/* Чтения байтов начиная с заданного адреса.
* Номер I2C, по которому передавать данные, адрес ведомого устройства, к которому обращаемся, режим адресации 7 бит,
* количество передаваемых байт 3, после завершения передачи НЕ генерировать СТОП-сигнал,
* перед началом сгенерировать СТАРТ-сигнал с признаком записи байта (ДА, ЗАПИСИ, сначала отправляем адрес в памяти,
* с которого хотим начать чтение)
*/
LL_I2C_HandleTransfer(I2C1, slave_address, LL_I2C_ADDRSLAVE_7BIT, 2, LL_I2C_MODE_SOFTEND, LL_I2C_GENERATE_START_WRITE);
while(!(LL_I2C_IsActiveFlag_TXE(I2C1))); // Флаг означает, что Выходной буфер свободен и можно записывать следующее значение
LL_I2C_TransmitData8(I2C1, (uint8_t)(read_address >> 16));
while(!(LL_I2C_IsActiveFlag_TXE(I2C1)));
LL_I2C_TransmitData8(I2C1, (uint8_t)(read_address));
while(!(LL_I2C_IsActiveFlag_TC(I2C1))); // Флаг означает, что все (два) байта переданы
// Передача закончилась, но СТОП-сигнал не генерируется (такой формат общения с памятью)
/*
* Генерируем СТАРТ-сингал с признаком чтения байта. Будем принимать 13 байт, после окончания приема сгенерировать
* СТОП-сигнал.
*/
LL_I2C_HandleTransfer(I2C1, slave_address, LL_I2C_ADDRSLAVE_7BIT, 13, LL_I2C_MODE_AUTOEND, LL_I2C_GENERATE_START_READ);
uint8_t i;
uint8_t receive_buf[32] = {0}; // Массив для записи принятых байт
for(i=0; i<13; i++){
while(!(LL_I2C_IsActiveFlag_RXNE(I2C1))); // Флаг означает, что в Приемном буфере появились данные
receive_buf[i] = LL_I2C_ReceiveData8(I2C1); // Списываем байт из Приемного буфера
}
// Все байты приняты, автоматически генерируется СТОП-сигнал
Вс июн 09, 2019 20:31:04
Чт авг 20, 2020 03:44:59
Пт ноя 27, 2020 03:11:23
Пт ноя 27, 2020 21:15:17
Видимо нужно научится правильно собирать проект и оптимально выбирать опции сборки потому что вы не правы.Ironium писал(а):например на STM32F030F4 с 16 кб, оный сожрет 2\3 флэша, после чего вы откроете референс мануал, обматерите HAL LL SPL
Program size (bytes): 1356
Data size (bytes): 4
BSS size (bytes): 4
Total size (bytes): 1364 (R/W Memory: 8)
=== Сборка закончена: 0 errors, 0 warnings (0 minutes, 3 seconds) ===
Program size (bytes): 676
Data size (bytes): 0
BSS size (bytes): 0
Total size (bytes): 676 (R/W Memory: 36)
=== Сборка закончена: 0 errors, 0 warnings (0 minutes, 2 seconds) ===
Вт июл 20, 2021 08:12:38
Вт июл 20, 2021 12:51:39
Из файла проектаsteklobiz писал(а):с какими настройками Вы собираете проект?
<Compiler>
<Add option="-fdata-sections" />
<Add option="-ffunction-sections" />
<Add option="-O2" />
<Add option="-g2" />
</Compiler>
<Linker>
<Add option="-Wl,--gc-sections" />
<Add option="-flto" />
</Linker>
Вт июл 20, 2021 12:57:45
Вт июл 20, 2021 14:00:07
Из файла проекта
Вт июл 20, 2021 23:17:09
Ср июл 21, 2021 07:31:25
steklobiz писал(а):Я пишу в CubeIDE и не смог найти такой файл
Пн авг 02, 2021 18:18:57
Короче, все таки набил код для записи, а потом чтения памяти. Без прерываний, просто, чтобы кто-то потратил на 2 дня меньше времени на освоение этой дури.
//Transfer byte 1 of memory address
LL_I2C_TransmitData8(I2C1, ((Reg & 0xFF00) >> 8));
while(!LL_I2C_IsActiveFlag_TXE(I2C1))
{
}
//Transfer byte 0 of memory address
LL_I2C_TransmitData8(I2C1, (Reg & 0x00FF));
while(!LL_I2C_IsActiveFlag_TXE(I2C1))
{
}