Страница 1 из 3

STM32F103C6T6

Добавлено: Пн сен 30, 2024 10:56:32
aleksey chilov
Добрый день!
Не могу поднять передачу данных
в OLED 12864 по I2C через DMA!!!
Всё вроде бы написано уже всё проверил 100 раз
а на шине полный штиль!
Контролер STM32F103C6T6.
Без DMA всё едет но хотелось бы через DMA.
Прошу помощи опытных людей кто шарит
взгляните на мою писанину и укажите на ошибку
пожалуйста или может быть чего-то не достаёт.
Но не знаю... Референс уже и так и сяк читал
ничего в голову не идёт что не так...
Спасибо.

Изображение Изображение Изображение Изображение

Re: STM32F103C6T6

Добавлено: Пн сен 30, 2024 11:06:57
Аlex
aleksey chilov писал(а):взгляните на мою писанину и укажите на ошибку
Серьёзно ? По скриншотам ? Вы издеваетесь ? :)))

Re: STM32F103C6T6

Добавлено: Пн сен 30, 2024 11:13:41
Базилюк
В RM0008 прочитать 26.3.7 DMA requests, Transmission using DMA и сделать так, как написано.
Для I2C1 на передачу работает только DMA1 Channel 4.
При настройке CCR регистра в DMA не нужно использовать макрос MODIFY_REG. Просто записывайте за один раз все биты этого регистра напрямую, через операцию =, без всяких изменений.
Логический анализатор есть? Хотябы простейший клон Saleae8 с Алиэкспресса за 400 руб. Подключите, посмотрите, что реально на шине происходит.

На случай сложности с чтением и переводом копирую сюда гуглоперевод параграфа из мануала:

26.3.7 Запросы DMA
Запросы DMA (если включены) генерируются только для передачи данных. Запросы DMA генерируются при пустом регистре данных при передаче и заполнении регистра данных при приеме. DMA должен быть инициализирован и включен до передачи данных I2C. Бит DMAEN должен быть установлен в регистре I2C_CR2 до события ADDR. В режиме ведущего или ведомого устройства, когда включено растяжение тактовой частоты, бит DMAEN также может быть установлен во время события ADDR, перед очисткой флага ADDR. Запрос DMA должен быть обработан до окончания текущей передачи байтов. Когда достигается количество передач данных, запрограммированное для соответствующего потока DMA, контроллер DMA отправляет сигнал End of Transfer EOT на интерфейс I2C и генерирует прерывание Transfer Complete, если включено:

 Ведущий передатчик: в процедуре прерывания после прерывания EOT отключите запросы DMA, затем дождитесь события BTF, прежде чем программировать условие Stop.


Передача с использованием DMA
Режим DMA может быть включен для передачи путем установки бита DMAEN в регистре I2C_CR2. Данные будут загружены из области памяти, настроенной с использованием периферийного устройства DMA (см. спецификацию DMA), в регистр I2C_DR всякий раз, когда установлен бит TxE. Чтобы отобразить поток DMA x для передачи I2C (где x — номер потока), выполните следующую последовательность:

1. Установите адрес регистра I2C_DR в регистре DMA_SxPAR. Данные будут перемещены по этому адресу из памяти после каждого события TxE.

2. Установите адрес памяти в регистре DMA_SxMA0R (и в регистре DMA_SxMA1R в случае режима двойного буфера). Данные будут загружены в I2C_DR из этой памяти после каждого события TxE.

3. Настройте общее количество байтов для передачи в регистре DMA_SxNDTR.
После каждого события TxE это значение будет уменьшаться.

4. Настройте приоритет канала DMA с помощью битов PL[0:1] в регистре DMA_SxCR.

5. Установите бит DIR в регистре DMA_SxCR и настройте прерывания после половинной передачи или полной передачи в зависимости от требований приложения.

6. Активируйте канал, установив бит EN в регистре DMA_SxCR.

Когда достигается количество передач данных, запрограммированное в регистрах контроллера DMA, контроллер DMA отправляет сигнал End of Transfer EOT/EOT_1 на интерфейс I2C, а DMA генерирует прерывание, если оно включено, на векторе прерывания потока DMA.

Примечание: не включайте бит ITBUFEN в регистре I2C_CR2, если для передачи используется DMA

Re: STM32F103C6T6

Добавлено: Пн сен 30, 2024 14:58:23
aleksey chilov
Анализатор есть. пользоваться умею. Толку от него когда data b и clk +3v
Без DMA всё транслирует, всё как нада экран отвечает затем принимает вобщем всё как нужно. Сейчас буду делать как в инструкции что вы прислали.

Re: STM32F103C6T6

Добавлено: Пн сен 30, 2024 15:00:14
Martian
[uquote="Аlex",url="/forum/viewtopic.php?p=4630495#p4630495"]Серьёзно ? По скриншотам?[/uquote] :)))

Re: STM32F103C6T6

Добавлено: Пн сен 30, 2024 15:10:51
Базилюк
[uquote="aleksey chilov",url="/forum/viewtopic.php?p=4630567#p4630567"]Анализатор есть. пользоваться умею. Толку от него когда data b и clk +3v .[/uquote]
О, так это главный толк! Вы выяснили главное - если вообще никаких сигналов на шине не появляется, значит, интерфейс вообще не запускается. А почему он не запускается? Да потому что состояние Strart на шине DMA не формирует. Я ж говорю - мануал читали, но не с той строчки и не на той странице. DMA, он же обеспечивает только автоматическую запись из SRAM в регистр DR и обратно, а больше ничего он не делает.

PS. "Смотрим в книгу - видим фигу" :) Вкл/выкл - канал 4, а посередине конфигурация канала 7 :) Внимательно надо писать, винимательно.
Изображение

Re: STM32F103C6T6

Добавлено: Пн сен 30, 2024 18:38:15
aleksey chilov
Изображение Изображение

Добавлено after 1 minute 26 seconds:
Это без DMA

Добавлено after 17 minutes 16 seconds:
Спасибо за помощь!
Буду разбираться с этим DMA
пробовать что-то делать постараюсь
код правильно писать. Позже сюда скину
результат похвастаюсь если будет чем...

Re: STM32F103C6T6

Добавлено: Пн сен 30, 2024 21:58:07
Базилюк
Коммуникация без DMA, регистрации и смс:
Спойлер

Код: Выделить всё

/*---- Начало связи, Start + Slave address  ----*/
	I2C1->CR1 |= I2C_CR1_START;			// генерация Start
	while(!(I2C1->SR1 & I2C_SR1_SB));	// ожидание формирования Start
	I2C1->DR = 0x78;					// передача адреса слейва
	while(!(I2C1->SR1 & I2C_SR1_ADDR));	// ожидание завершения передачи адреса
	I2C1->SR2;

	/*---- Передача байтов данных ------------------*/
	while(!(I2C1->SR1 & I2C_SR1_TXE));
	I2C1->DR = 0x00;					// байт Co, C/D = 0

	while(!(I2C1->SR1 & I2C_SR1_TXE));
	I2C1->DR = 0x8D;					// DC/DC

	while(!(I2C1->SR1 & I2C_SR1_TXE));
	I2C1->DR = 0x14;					// Power On

	while(!(I2C1->SR1 & I2C_SR1_TXE));
	I2C1->DR = 0xAF;					// Display On

	/*---- Завершение связи, передача Stop ---------*/
	while(!(I2C1->SR1 & (I2C_SR1_TXE | I2C_SR1_BTF)));
	I2C1->CR1 |= I2C_CR1_STOP;
Изображение

А это - уже с ДМА-й, но тоже без регистрации и смс, то есть, решение "в лоб":

Код: Выделить всё

	const uint8_t config[] = {0x00, 0x8D, 0x14, 0xAF};  // массив для передачи

	/*---- Конфиг DMA Channel 6 для I2C1 TX --------*/
	DMA1->IFCR = DMA_IFCR_CGIF6;		// сброс флагов канала
	DMA1_Channel6->CCR = DMA_CCR4_DIR | // из памяти в периферию
						 DMA_CCR4_MINC; // инкремент адресов памяти
	DMA1_Channel6->CMAR = (uint32_t)config;
	DMA1_Channel6->CPAR = (uint32_t)&I2C1->DR;
	DMA1_Channel6->CNDTR = 4;
	DMA1_Channel6->CCR |= DMA_CCR6_EN;	// канал включен

	/*---- Начало связи, Start + Slave address  ----*/
	I2C1->CR1 |= I2C_CR1_START;			// генерация Start
	while(!(I2C1->SR1 & I2C_SR1_SB));	// ожидание формирования Start
	I2C1->DR = 0x78;					// передача адреса слейва

	/*--- Включение запросов DMA -------------------*/
	I2C1->CR2 |= I2C_CR2_DMAEN;

	/*--- Ожидание передачи адреса ------------------*/
	while(!(I2C1->SR1 & I2C_SR1_ADDR));	// ожидание завершения передачи адреса
	I2C1->SR2;

	/*---- Передача байтов данных ------------------*/
	while(!(DMA1->ISR & DMA_ISR_TCIF6)); // ожидание завершения передачи по DMA

	/*---- Завершение связи, передача Stop ---------*/
	while(!(I2C1->SR1 & (I2C_SR1_TXE | I2C_SR1_BTF)));
	I2C1->CR1 |= I2C_CR1_STOP;
Изображение
Как видим, изменения в порядке действий касаются только включения запросов DMA перед завершением передачи адреса слейва и после подтверждения адреса слейва остается только ожидать завершения полной передачи по DMA. После этого, как и в предыдущем варианте, формируется сигнал Stop на шине.
Канал DMA предварительно конфигурируется. И для I2C1 TX используется канал 6, а не 4 и не 7! Мануалы надо читать, а не пролистывать. Если сложно запомнить, то записывать на бумажке.

Кстати, в ревизии 21 документа RM0008 заметил ошибку в описании запросов DMA в I2C. Там дается отсылка на модуль DMA, стоящий в других МК, таких как F4xx. А я то думаю, почему это каналы тут названы потоками, и рассказывается о раздельных буферах для многобуферного DMA. Странно, в предыдущих ревизиях документа, по-моему, такого косяка не было.

ЗЫ. Для дисплея SSD1306 эти 4 байта - это минимально необходимый набор для включения панели. Все остальные настройки дисплея - опциональны. Работать он будет и без них. Единственная дополнительная настройка - настройка порядка проходки развертки. И по желанию - настройка яркости свечения.

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 12:34:20
aleksey chilov
Добрый день!
Капец!
Это просто капец!
Эта хрень не работает!
Уже что только не придумывал!
Даже ваш код копировал и вставлял!
Одно и тоже!

Изображение



//------------------ I2C_DMA -----------------
void I2C_send_data_Dma(uint8_t *data, uint8_t len){
SET_BIT(DMA1_Channel6->CCR, DMA_CCR_EN_Pos); // Канал 6 DMA отключить!
SET_BIT(DMA1->IFCR, DMA_IFCR_CGIF6_Pos); // сброс флагов канала
SET_BIT(DMA1_Channel6->CCR, DMA_CCR_DIR_Pos); // из памяти в периферию
SET_BIT(DMA1_Channel6->CCR, DMA_CCR_MINC_Pos); // Включить инкремент адреса памяти
//DMA1_Channel6->CMAR = (uint32_t)data; // заносим адрес данных в регистр CMAR
//DMA1_Channel6->CPAR = (uint32_t)&I2C1->DR; // заносим адрес I2C регистра DR в CPAR
//DMA1_Channel6->CNDTR = len;
SET_BIT(DMA1_Channel6->CCR, DMA_CCR_EN_Pos); // Канал 6 DMA включить!

//CLEAR_BIT(I2C1->CR1, I2C_CR1_POS); // Сбросить бит POS в регистре CR1

//MODIFY_REG(I2C1->CR1, I2C_CR1_ACK, I2C_CR1_ACK); // Включить генерирование условия ACK

SET_BIT(I2C1->CR1, I2C_CR1_START); //---------------------- Сигнал "START"

while (!READ_BIT(I2C1->SR1, I2C_SR1_SB));// Ожидаем установки Сигнал "START".

MODIFY_REG(I2C1->DR, I2C_DR_DR, SLAVE_ADDRESS | I2C_WRITE);// Передадим адрес

SET_BIT(I2C1->CR2, I2C_CR2_DMAEN_Pos); // Запрос в DMA

while (!READ_BIT(I2C1->SR1, I2C_SR1_ADDR));// Ожидаем конца передачи

//(void) I2C1->SR1; // Читаем регистр

(void) I2C1->SR2;

while (!READ_BIT(I2C1->SR1, I2C_SR1_TXE));

while(!(DMA1->ISR & DMA_ISR_TCIF6)); // ожидание завершения передачи по DMA

while (!(I2C1->SR1 & (I2C_SR1_TXE | I2C_SR1_BTF)));

SET_BIT(I2C1->CR1, I2C_CR1_STOP_Pos);
}

Добавлено after 1 minute 13 seconds:
Швыряет адрес и потом STOP

Добавлено after 1 minute 48 seconds:
В теории должно всё работать аш бегом!
Второй день на этом месте торчу!
Стена прям какая то...

Добавлено after 3 minutes 39 seconds:
Не едет короче ни как и ни куда...

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 12:37:46
Базилюк
И опять элементарная невнимательность. Если закомментить установку регистров CMAR, CPAR, CNDTR в DMA, то конечно DMA не перешлет данные куда нужно.
И сигнал Stop на картинке анализатора не сформирован. CLK в низком уровне - это clock stretch, ожидание дальнейших действий. Оно и стоит в ожидании флага TCIF от DMA, но его нет, поскольку передачи не могут стартовать - не сконфигурирован до конца канал.
Тяжко вам будет с такой рассеянностью. Программирование предполагает внимательность к деталям.

ЗЫ.
Щас вот специально закомменчиваю эти строчки конфига ДМА - и всё, код повесился в ожидании TCIF6.

Изображение

Вы, господин, разве не можете взять и один-в-один перекопировать? Вот даже вот так:
Спойлер

Код: Выделить всё

int main(void)
{
	/* RCC */
	RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN;
	RCC->AHBENR |= RCC_AHBENR_DMA1EN;
	RCC->APB1ENR |= RCC_APB1ENR_I2C1EN;

	/* GPIO */
	GPIOB->CRL |= GPIO_CRL_CNF6 | GPIO_CRL_CNF7 | GPIO_CRL_MODE6_1 | GPIO_CRL_MODE7_1;

	/* I2C1 */
	I2C1->CR2 = 8;	// 8 МГц частота шины APB1
	I2C1->CCR = 40; // для 100 кГц I2C
	I2C1->TRISE = 9;
	I2C1->CR1 = I2C_CR1_PE;

	const uint8_t config[] = {0x00, 0x8D, 0x14, 0xAF};

	/*---- Конфиг DMA Channel 6 для I2C1 TX --------*/
	DMA1->IFCR = DMA_IFCR_CGIF6;		// сброс флагов канала
	DMA1_Channel6->CCR = DMA_CCR4_DIR | // из памяти в периферию
						 DMA_CCR4_MINC; // инкремент адресов памяти
	DMA1_Channel6->CMAR = (uint32_t)config;
	DMA1_Channel6->CPAR = (uint32_t)&I2C1->DR;
	DMA1_Channel6->CNDTR = 4;
	DMA1_Channel6->CCR |= DMA_CCR6_EN;	// канал включен

	/*---- Начало связи, Start + Slave address  ----*/
	I2C1->CR1 |= I2C_CR1_START;			// генерация Start
	while(!(I2C1->SR1 & I2C_SR1_SB));	// ожидание формирования Start
	I2C1->DR = 0x78;					// передача адреса слейва

	/*--- Включение запросов DMA -------------------*/
	I2C1->CR2 |= I2C_CR2_DMAEN;

	/*--- Ожидание передачи адреса ------------------*/
	while(!(I2C1->SR1 & I2C_SR1_ADDR));	// ожидание завершения передачи адреса
	I2C1->SR2;

	/*---- Передача байтов данных ------------------*/
	while(!(DMA1->ISR & DMA_ISR_TCIF6)); // ожидание завершения передачи по DMA

	/*---- Завершение связи, передача Stop ---------*/
	while(!(I2C1->SR1 & (I2C_SR1_TXE | I2C_SR1_BTF)));
	I2C1->CR1 |= I2C_CR1_STOP;


	while(1)
	{

	}
}

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 13:18:01
aleksey chilov
Тоже самое...

Изображение Изображение

Добавлено after 47 seconds:
После 9 импульса всё...

Добавлено after 2 minutes 23 seconds:

Добавлено after 4 minutes 36 seconds:
Я копировал сегодня ваш версию кода и получил точно такую же картинку. Я копировал потому что уже не представляю что не так. Уже пробовал всё! уже и мысли и догадки закончились почему не так. Не хочет он работать и всё!

Добавлено after 1 minute:
Вот init i2c самого у меня вот такой:


void I2C_init(void){
(void)I2C1->CR2;

SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C1EN); // Подключить тактирование I2C
// -------------------------- PORTB_6_SCL_I2C1------------------------------------------
MODIFY_REG(GPIOB->CRL, GPIO_CRL_CNF6_Msk, 0b11 << GPIO_CRL_CNF6_Pos); // Альтернатив.функции
MODIFY_REG(GPIOB->CRL, GPIO_CRL_MODE6_Msk, 0b11 << GPIO_CRL_MODE6_Pos); // PB6_50mHz
// -------------------------- PORTB_7_SDA_I2C1------------------------------------------
MODIFY_REG(GPIOB->CRL, GPIO_CRL_CNF7_Msk, 0b11 << GPIO_CRL_CNF7_Pos); // Альтернатив.функции
MODIFY_REG(GPIOB->CRL, GPIO_CRL_MODE7_Msk, 0b11 << GPIO_CRL_MODE7_Pos); // PB7_50mHz
// ---------- Рестарт I2C -----------------------------------------------
//SET_BIT(I2C1->CR1, I2C_CR1_SWRST);
//while(READ_BIT(I2C1->CR1, I2C_CR1_SWRST) == 0);
//CLEAR_BIT(I2C1->CR1, I2C_CR1_SWRST);
//while(READ_BIT(I2C1->CR1, I2C_CR1_SWRST));
// ---------- Рестарт I2C -----------------------------------------------
//----------- Настройки I2C_CR1 -----------------------------------------
//CLEAR_BIT(I2C1->CR1, I2C_CR1_SMBUS); // SMBUS "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_SMBTYPE); // SMBTYPE "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_ENARP); // ENARP "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_ENPEC); // ENPEC "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_NOSTRETCH); // NOSTRETCH "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_START); // START "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_STOP); // STOP "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_ACK); // ACK "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_POS); // POS "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_PEC); // PEC "OFF"
//CLEAR_BIT(I2C1->CR1, I2C_CR1_ALERT); // ALERT "OFF"
//SET_BIT(I2C1->CR1, I2C_CR1_PE); // I2C "0N"
//----------- Настройки I2C_CR1 -----------------------------------------

//----------- Настройки I2C_CR2 -----------------------------------------
//CLEAR_BIT(I2C1->CR2, I2C_CR2_LAST); // "OFF"
//CLEAR_BIT(I2C1->CR2, I2C_CR2_DMAEN); // "OFF"
//CLEAR_BIT(I2C1->CR2, I2C_CR2_ITBUFEN); // "OFF"
//CLEAR_BIT(I2C1->CR2, I2C_CR2_ITEVTEN); // "OFF"
//CLEAR_BIT(I2C1->CR2, I2C_CR2_ITERREN); // "OFF"
// ----------------- Частота 36 мГц APB шины ----------------------------
MODIFY_REG(I2C1->CR2, I2C_CR2_FREQ_Msk, 36 << I2C_CR2_FREQ_Pos);
//----------- Настройки I2C_CR2 -----------------------------------------
//CLEAR_BIT(I2C1->CCR, I2C_CCR_FS); // Стандарт mode 100 кГц.
SET_BIT(I2C1->CCR, I2C_CCR_FS); // Быстрый 400 кГц
CLEAR_BIT(I2C1->CCR, I2C_CCR_DUTY); // 1/2
//SET_BIT(I2C1->CCR, I2C_CCR_DUTY); // 16/9
//MODIFY_REG(I2C1->CCR, I2C_CCR_CCR_Msk, 180 << I2C_CCR_CCR_Pos);// standart mode
MODIFY_REG(I2C1->CCR, I2C_CCR_CCR_Msk, 10 << I2C_CCR_CCR_Pos);// fast mode "30"
//MODIFY_REG(I2C1->TRISE, I2C_TRISE_TRISE_Msk, 37 << I2C_TRISE_TRISE_Pos);// standart mode
MODIFY_REG(I2C1->TRISE, I2C_TRISE_TRISE_Msk, 4 << I2C_TRISE_TRISE_Pos);// fast mode "12"
//SET_BIT(I2C1->CR2, I2C_CR2_ITBUFEN_Pos); // Включение прерывания буфера
//SET_BIT(I2C1->CR2, I2C_CR2_DMAEN_Pos); // Бит 11 DMAEN: запросы DMA разрешены.
SET_BIT(I2C1->CR1, I2C_CR1_PE); // Включаем I2C
}

Добавлено after 48 seconds:
Это настройки DMA вот такие:

void DMA_init(void){
SET_BIT(RCC->AHBENR, RCC_AHBENR_DMA1EN_Pos); // разрешение тактирования DMA1
MODIFY_REG(DMA1_Channel6->CCR, DMA_CCR_PL_Msk, 0b01 << DMA_CCR_PL_Pos); // приоритета канала средний
MODIFY_REG(DMA1_Channel6->CCR, DMA_CCR_MSIZE_Msk, 0b00 << DMA_CCR_MSIZE_Pos);//разрядность данных в памяти 8 бит
MODIFY_REG(DMA1_Channel6->CCR, DMA_CCR_PSIZE_Msk, 0b01 << DMA_CCR_PSIZE_Pos);//разрядность регистра данных 16 бит
SET_BIT(DMA1_Channel6->CCR, DMA_CCR_MINC_Pos); //Включить инкремент адреса памяти
CLEAR_BIT(DMA1_Channel6->CCR, DMA_CCR_PINC_Pos); //Инкремент адреса периферии отключен
CLEAR_BIT(DMA1_Channel6->CCR, DMA_CCR_CIRC_Pos); //кольцевой режим отключен
SET_BIT(DMA1_Channel6->CCR, DMA_CCR_DIR_Pos); // из памяти в периферию
SET_BIT(DMA1_Channel6->CCR, DMA_CCR_EN_Pos); // Канал 6 DMA Включён
}

Добавлено after 1 minute 6 seconds:
И не едет!

Добавлено after 42 seconds:
Что тут может быть не так???
Всёж стандартно ёлки-палки!!!

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 13:36:49
linkov1959
aleksey chilov, хорошо бы поднять скорость работы таких дисплеев! А какую прибавку ожидаете?

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 14:30:45
Базилюк
После передачи адреса принимается NACK - дисплей отвалился.
Я ж говорю - внимание к деталям. Лог. анализатор - хороший в этом помощник

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 14:56:03
smacorp
Если всего лишь второй день "стены проблем" при программировании вызывает взрыв эмоций, напоминающий истерику, есть повод задуматься "а стоит ли вообще заниматься программированием". Страшно представить, что будет с человеком, если стена не падёт и через неделю.

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 15:46:08
aleksey chilov
Да не в прибавке скорости.
Я легко сделаю что хотел без DMA.
Более того в проекте который я делаю там вовсе не
обязательно брать контролер STM32 там легко проканает
даже Atmega8. Там просто нужно рулить тембр блоком по
i2c и выводить всё на OLED. Но вопрос то в другом, что за STM без DMA???

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 15:46:49
Базилюк
Да, знавал я таких человеков, которые методом тыка искали проблемы. Так бывает, когда у человека нет склонностей к электронике и программированию. Мы ж все разные.
Вообще, здесь вначале нужно разобраться, что есть интерфейс I2C, какие у него виды сигналов и состояний есть, как выглядит состояния Start, Stop, что такое и как выглядит Ack и "Не-Ack" - Nack (он же NAK в другой мнемонике), какие есть фазы обмена между устройствами.
И когда будут знания этой базы, одного взгляда на запись лог.анализатора будет достаточно, чтобы понять, почему не идет обмен, если после передачи адреса ведомого получен ответ Nack. После передачи мастером каждого байта (в том числе и адреса), на девятый импульс SLC мастер отпускает управление линией SDA, и ведомое устройство, если оно есть на линии и его адрес совпал, должно прижать линию SDA, выставив в 0. Это будет Ack ("подтверждаю принятие байта"). А если ведомого на линии нет, то и прижать эту линию некому, она находится в высоком уровне. Это будет Nack, "не подтверждено" - ведомого нет на линии или оно хочет завершить обмен по своей инициативе.

Изображение

[uquote="aleksey chilov",url="/forum/viewtopic.php?p=4630961#p4630961"]что за STM без DMA???[/uquote]
Так дело то не в STM-е и не в DMA. Дело - в отвалившемся физически дисплее! NACK - дисплея нет на линии!

[uquote="linkov1959",url="/forum/viewtopic.php?p=4630916#p4630916"]хорошо бы поднять скорость работы таких дисплеев! А какую прибавку ожидаете?[/uquote]
I2C - очень медленный интерфейс сам по себе. Поэтому, никакие DMA не поднимут скорость передачи байтов в дисплей. Максимальная частота тактового сигнала I2C для этого дисплея - 400 кГц. А в варианте SPI эта частота уже составляет 10 МГц - разница в 25 раз!

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 15:54:36
aleksey chilov
Дорогой товарищ!
Я и так это понимаю.
Это всё присутствует.
Я не понимаю почему нет
передачи из DMA?
Проблема в коде или в контролере?

Изображение

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 16:02:59
Базилюк
Нет, проблема - в жуткой невнимательности и неумении читать мануалы!
MODIFY_REG(DMA1_Channel6->CCR, DMA_CCR_PSIZE_Msk, 0b01 << DMA_CCR_PSIZE_Pos);//разрядность регистра данных 16 бит

Ну откуда там 16 бит в DR то? Ну откуда возьмутся 16 бит, если I2C от своей природы - 8-битный интерфейс? Невнимательность, помноженная на непонимание основ.

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 16:14:07
aleksey chilov
Понимаете в чём дело, я откидываю DMA и дисплей работает не плохо!
На прямую он работает!
Яб показал но сюда не могу загрузить видео.

Добавлено after 1 minute 59 seconds:
Там регистр 16 битный. Просто старшие 8 в зарезервированы.

Добавлено after 1 minute 43 seconds:
Изображение

Re: STM32F103C6T6

Добавлено: Вт окт 01, 2024 16:15:19
Базилюк
А это точно STM32? Потому что бывают его клоны типа GD, CH, AMP или CS