Понадобилось по-быстрому запилить простой "программатор" EEPROM микросхемы, да чтоб читать/писать память её можно было через юзерское приложение в Windows. И что-то я подзатупил изначально с адресацией памяти.
Для работы с EEPROM (и не только) в STM32CubeF4 библиотеке есть функции HAL_I2C_Mem_Read и HAL_I2C_Mem_Write, инициализацию I2C генерит приложение STM32CubeMX, в общем-то халява, осталось использовать функции, передать данные из/в компьютер и девайс готов. Однако меня сбил с толка параметр функций uint16_t MemAddSize, который может быть равен I2C_MEMADD_SIZE_8BIT или I2C_MEMADD_SIZE_16BIT. В моей микросхеме 2048 байт памяти и логично предположить, что мне нужен вариант I2C_MEMADD_SIZE_16BIT, т.е. 16 бит на адрес,ибо 8 бит хватит только на адресацию 256 байт.
А вот и нет. Память "побита" на блоки по 256 байт, выбор ID блока происходит через запись соответствующего ID в биты 1,2,3 байта адреса устройства:
Их можно трактовать как ID 256-байтного блока или просто как старшие дополнительные 3 бита адреса памяти (как в таблице и указано). То есть адресация здесь 11 битная.
Собственно, адрес _устройства_ получаем таким образом: 0xA0 | ((memory_address >> 7) & 0xE). Нулевой бит по идее контроллируется библиотекой и делать операцию битового чтения & 0xF по идее не нужно. Но опыт подсказывает, что доверять библиотеке Cube от ST не стоит )
Вдруг кому сэкономит время )
Для работы с EEPROM (и не только) в STM32CubeF4 библиотеке есть функции HAL_I2C_Mem_Read и HAL_I2C_Mem_Write, инициализацию I2C генерит приложение STM32CubeMX, в общем-то халява, осталось использовать функции, передать данные из/в компьютер и девайс готов. Однако меня сбил с толка параметр функций uint16_t MemAddSize, который может быть равен I2C_MEMADD_SIZE_8BIT или I2C_MEMADD_SIZE_16BIT. В моей микросхеме 2048 байт памяти и логично предположить, что мне нужен вариант I2C_MEMADD_SIZE_16BIT, т.е. 16 бит на адрес,ибо 8 бит хватит только на адресацию 256 байт.
А вот и нет. Память "побита" на блоки по 256 байт, выбор ID блока происходит через запись соответствующего ID в биты 1,2,3 байта адреса устройства:
Их можно трактовать как ID 256-байтного блока или просто как старшие дополнительные 3 бита адреса памяти (как в таблице и указано). То есть адресация здесь 11 битная.
Собственно, адрес _устройства_ получаем таким образом: 0xA0 | ((memory_address >> 7) & 0xE). Нулевой бит по идее контроллируется библиотекой и делать операцию битового чтения & 0xF по идее не нужно. Но опыт подсказывает, что доверять библиотеке Cube от ST не стоит )
Вдруг кому сэкономит время )
while (1)
ОтветитьУдалить{
HAL_I2C_Mem_Read(&hi2c1, 0x50 << 1, 0x03, 1, &xBuffer[0], 1, 1000);
HAL_UART_Transmit(&huart1, &xBuffer[0], 1, 0xFFFF);
HAL_Delay(1000);
}
не читает 24lc01. во все ячейки 24lc01 программатором записано значение 55.
заработало. установил частоту 8Мгц вместо 16Мгц. камень stm32f103c8t6
ОтветитьУдалитьSTM32F030F4P6 F_CPU 48 MHz, F_I2C48 MHz, F_USART48 MHz
ОтветитьУдалить#define Device_ADD 0x00A0 // Адрес устройства
#define Mem_ADD 0x005 // Адрес внутренней памяти
#define Mem_ADD_Size 2 // Размер адреса внутренней памяти размер адреса 12 бит
#define BufferSize_1 26
uint8_t Data_Wrt [26];
uint8_t Data_Rd [26];
//================================================================================================================
for(uint8_t Txt = 0x41; Txt < 0x5B; Txt ++)
{
Data_Wrt [Txt] = Txt;
}
uint8_t Op = 0x41;
//================================================================================================================
//1010000(0) //0x005 // 2 // 26
if (HAL_I2C_Mem_Write(&hi2c1, Device_ADD, Mem_ADD, Mem_ADD_Size, & Data_Wrt[Op], BufferSize_1, 1000) == HAL_OK)
{
HAL_UART_Transmit (&huart1, (uint8_t*)"OK_W\r\n", 5, 0xFFFF);
HAL_Delay (20);
HAL_UART_Transmit (&huart1, & Data_Wrt[Op], 26, 0xFFFF);
HAL_UART_Transmit (&huart1, (uint8_t*) "\r\n", 2, 0xFFFF);
HAL_Delay (20);
}
else
{
HAL_UART_Transmit (&huart1, (uint8_t*)"EEROR_W\r\n", 8, 0xFFFF);
}
//================================================================================================================
HAL_Delay (2000);
//================================================================================================================if (HAL_I2C_Mem_Read (&hi2c1, Device_ADD, Mem_ADD, Mem_ADD_Size, & Data_Rd [0], BufferSize_1, 1000) == HAL_OK)
{
HAL_UART_Transmit (&huart1, (uint8_t*)"OK_R\r\n", 5, 0xFFFF);
HAL_Delay (20);
HAL_UART_Transmit (&huart1, & Data_Rd [0], 26, 0xFFFF);
HAL_UART_Transmit (&huart1, (uint8_t*) "\r\n", 2, 0xFFFF);
HAL_Delay (20);
}
else
{
HAL_UART_Transmit (&huart1, (uint8_t*)"EEROR_R\r\n", 8, 0xFFFF);
}
EEPROM_AT24C32D
ОтветитьУдалить