stm32f4 usart+DMA
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: stm32f4 usart+DMA
[uquote="tonyk",url="/forum/viewtopic.php?p=4172782#p4172782"]Особенно когда дойдёте до управления трансивером интерфейса EIA-485, тогда сразу эта ошибка вылезет.[/uquote]У современных контроллеров нога управления RW есть, там вообще ничего не надо делать. Если вдруг нет или нет возможности использовать, то сразу после запуска DMA включаешь TCIE, а в прерывании TCIE сбрасываешь RW и выключаешь TCIE.
- Реклама
Re: stm32f4 usart+DMA
[uquote="VladislavS",url="/forum/viewtopic.php?p=4172818#p4172818"][uquote="tonyk",url="/forum/viewtopic.php?p=4172782#p4172782"]Особенно когда дойдёте до управления трансивером интерфейса EIA-485, тогда сразу эта ошибка вылезет.[/uquote]У современных контроллеров нога управления RW есть, там вообще ничего не надо делать. Если вдруг нет или нет возможности использовать, то сразу после запуска DMA включаешь TCIE, а в прерывании TCIE сбрасываешь RW и выключаешь TCIE.[/uquote]
Управление направлением есть в полноценных UART, кстати, у них же есть и RTO.
Так ведь я этим чудикам и толкую, что они не правильно определяют завершение передачи именно потому, что UART_TC не_обрабатывают.
Управление направлением есть в полноценных UART, кстати, у них же есть и RTO.
Так ведь я этим чудикам и толкую, что они не правильно определяют завершение передачи именно потому, что UART_TC не_обрабатывают.
- AlanDrakes
- Прорезались зубы
- Сообщения: 236
- Зарегистрирован: Пн июл 04, 2016 16:51:22
- Откуда: Россия, Омск
Re: stm32f4 usart+DMA
[uquote="Dimon456",url="/forum/viewtopic.php?p=4172652#p4172652"]AlanDrakes, провел я сравнительный тест с вашим кодом.
В качестве теста использовал переменную ms_tick из SysTick_Handler, в общем результат впечатляющий, 24 против 5637 (по идеи это милли секунды должны, но мне кажется что тестовый светодиод быстрее в два раза моргает), но мне потребовалось 3кБайта буфер, 2к мало было. Весь упор в оперативную память, хорошо когда ее много.[/uquote]
Если я правильно понял, то вы использовали часть моего кода у себя. Я так понял, тоже подружили вывод декста в кольцевой буфер и отправку этого всего посредством DMA. Смеха ради, можете посмотреть логическим анализатором активность на пине TX.
Надеюсь, помогло ^_^
ms_tick - счётчик милисекунд, да. Его я больше нигде не меняю, только время от времени в разных местах программы считываю.
А по поводу приёма - у меня приём на линии обмена идёт через DMA в обратную сторону (там, где жесть и индексы на указатели) и посимвольно на приём в отладочном буфере. Он обычно работает с USB-UART'ом, так что скорость на приём крайне низкая и ловить IDLE действительно можно после каждого символа. Так что байты перенаправляются в фукицю приёма microrl, а библиотека уже сама разбирается что там делать с символами.
Кстати, можете посмотреть в её же сторону для приёма ответа от GMS модулей.
PS: Как вывод выглядит в консоли:
После третьей строки таймер инициализируется и начинает считать настоящее время, до этого милисекунды используются из systick'a. 751мс - время запуска часового кварца с нуля. Потом милисекунды сбрасываются (из-за начальной установка часов).
В качестве теста использовал переменную ms_tick из SysTick_Handler, в общем результат впечатляющий, 24 против 5637 (по идеи это милли секунды должны, но мне кажется что тестовый светодиод быстрее в два раза моргает), но мне потребовалось 3кБайта буфер, 2к мало было. Весь упор в оперативную память, хорошо когда ее много.[/uquote]
Если я правильно понял, то вы использовали часть моего кода у себя. Я так понял, тоже подружили вывод декста в кольцевой буфер и отправку этого всего посредством DMA. Смеха ради, можете посмотреть логическим анализатором активность на пине TX.
Надеюсь, помогло ^_^
ms_tick - счётчик милисекунд, да. Его я больше нигде не меняю, только время от времени в разных местах программы считываю.
А по поводу приёма - у меня приём на линии обмена идёт через DMA в обратную сторону (там, где жесть и индексы на указатели) и посимвольно на приём в отладочном буфере. Он обычно работает с USB-UART'ом, так что скорость на приём крайне низкая и ловить IDLE действительно можно после каждого символа. Так что байты перенаправляются в фукицю приёма microrl, а библиотека уже сама разбирается что там делать с символами.
Кстати, можете посмотреть в её же сторону для приёма ответа от GMS модулей.
PS: Как вывод выглядит в консоли:
Спойлер
Код: Выделить всё
[2000-01-01 00:00:00.000] System started
SDIO: Power OFF
[2000-01-01 00:00:00.000] RTC is NOT started. Activating...
[2000-01-01 00:00:00.751] DONE
[2017-01-01 00:00:00.001] Firmware Build Date: 2018-05-22 17:22:36
[2017-01-01 00:00:00.001] Chip ID: 2C0052001051353334393035
[2017-01-01 00:00:00.001] Flash size: 512 KiB
[2017-01-01 00:00:00.001] System Frequency: 50MHz
[2017-01-01 00:00:00.001] I2C Init... DONE.
[2017-01-01 00:00:00.003] VCell = 0xC5D0 3956mV Charge: 69%
Adestro SPI flash detected: AT25DF/AT26DF series. Capacity: 4096 kiB. Cells type: SLC, Product Ver.: 1
[2017-01-01 00:00:00.011] LCD_ID: 9431
[2017-01-01 00:00:00.110] LCD Init Done.
[2017-01-01 00:00:00.113] uSD Card present
SDIO: Power ON
[2017-01-01 00:00:00.714] FatFS: Card Mount OK
FS Type: FAT-32. Free space: 7812 / 15279MiB
[2017-01-01 00:00:00.716] Starting FreeRTOS.
[2017-01-01 00:00:00.718] Lan PHY Init Done.Re: stm32f4 usart+DMA
[uquote="VladislavS",url="/forum/viewtopic.php?p=4172818#p4172818"]У современных контроллеров нога управления RW есть, там вообще ничего не надо делать. Если вдруг нет или нет возможности использовать, то сразу после запуска DMA включаешь TCIE, а в прерывании TCIE сбрасываешь RW и выключаешь TCIE.[/uquote]Только в случае с RS-485 и другими подобными интерфейсами, TC мало полезно. Так как часто им необходима задержка переключения передача/приём и обратно. Особенно если они гальванически развязаны медленными оптопарами.
А раз задержка всё равно нужна, то почти без разницы - есть TC или нет.
Ну разве что будет через раз работать на паразитных задержках кода.
А раз задержка всё равно нужна, то почти без разницы - есть TC или нет.
Ну разве что будет через раз работать на паразитных задержках кода.
Re: stm32f4 usart+DMA
[uquote="jcxz",url="/forum/viewtopic.php?p=4172927#p4172927"][uquote="VladislavS",url="/forum/viewtopic.php?p=4172818#p4172818"]У современных контроллеров нога управления RW есть, там вообще ничего не надо делать. Если вдруг нет или нет возможности использовать, то сразу после запуска DMA включаешь TCIE, а в прерывании TCIE сбрасываешь RW и выключаешь TCIE.[/uquote]Только в случае с RS-485 и другими подобными интерфейсами, TC мало полезно. Так как часто им необходима задержка переключения передача/приём и обратно. Особенно если они гальванически развязаны медленными оптопарами.
А раз задержка всё равно нужна, то почти без разницы - есть TC или нет.
Ну разве что будет через раз работать на паразитных задержках кода.[/uquote]
Ты алгоритм управления направлением представляешь? Похоже, что не_представляешь. И с задержками даже у гальванически развязанных трансиверов не знаком. Обработав UART_TC, можно сразу переключаться на приём без всяких задержек, прямо в обработчике прерывания от UART. Правильно приведённый выше код будет работать только с трансиверами, имеющими функцию автоматического определения направления передачи.
А раз задержка всё равно нужна, то почти без разницы - есть TC или нет.
Ну разве что будет через раз работать на паразитных задержках кода.[/uquote]
Ты алгоритм управления направлением представляешь? Похоже, что не_представляешь. И с задержками даже у гальванически развязанных трансиверов не знаком. Обработав UART_TC, можно сразу переключаться на приём без всяких задержек, прямо в обработчике прерывания от UART. Правильно приведённый выше код будет работать только с трансиверами, имеющими функцию автоматического определения направления передачи.
- Реклама
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32f4 usart+DMA
Спойлер
Код: Выделить всё
void USART1_DMA2_stream7init(void)
{
GPIOA->MODER |= GPIO_MODER_MODE9_1 | GPIO_MODER_MODE10_1;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10;
GPIOA->AFR[1]|=_VAL2FLD(GPIO_AFRH_AFSEL9,7);
GPIOA->AFR[1]|=_VAL2FLD(GPIO_AFRH_AFSEL10,7);
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
RCC->AHB1ENR |=RCC_AHB1ENR_DMA2EN;
USART1->CR1 |= USART_CR1_TE; // ��������� ����������
USART1->CR1 |= USART_CR1_RE;
USART1->BRR=(APBCLK+BAUDRATE/2)/BAUDRATE;
MODIFY_REG(USART1->CR1,
USART_CR1_M | USART_CR1_PCE | USART_CR1_PS,USART_CR1_TE |USART_CR1_RE);
USART1-> CR3|=USART_CR3_DMAT;
//USART1->CR1 |= USART_CR1_RXNEIE;
USART1->CR1 |= USART_CR1_UE; // ��������� USART
// ��������� ���������� �� ������ ������
// NVIC_EnableIRQ (USART1_IRQn);
DMA2_Stream7->PAR |=(uint32_t)&USART1->DR;
DMA2_Stream7->M0AR |=(uint32_t)&txData;
// DMA2_Stream7->NDTR =3;
DMA2_Stream7->CR&=~DMA_SxCR_PINC;
DMA2_Stream7->CR|=DMA_SxCR_MINC;
DMA2_Stream7->CR|= DMA_SxCR_PSIZE_0;
DMA2_Stream7->CR|= DMA_SxCR_MSIZE_0;
DMA2_Stream7->CR|=_VAL2FLD(DMA_SxCR_CHSEL,4 );
DMA2_Stream7->CR&=~ DMA_SxCR_PFCTRL;//DMA ma
DMA2_Stream7->CR|= DMA_SxCR_PL; //DMA ma
//DMA2_Stream0->FCR|=DMA_SxFCR_DMDIS;//��������� fIFO
DMA2_Stream7->CR|=_VAL2FLD( DMA_SxCR_DIR,0);
DMA2_Stream7->CR|= DMA_SxCR_CIRC;
DMA2_Stream7->CR|=DMA_SxCR_TCIE;
DMA2_Stream7->CR|=DMA_SxCR_TEIE;
DMA2->HIFCR|=DMA_HIFCR_CFEIF7|DMA_HIFCR_CDMEIF7| DMA_HIFCR_CTEIF7|DMA_HIFCR_CHTIF7 |DMA_HIFCR_CTCIF7 ;
//DMA2_Stream0->CR|=DMA_SxCR_DMEIE;
DMA2_Stream7->CR|= DMA_SxCR_EN;//��� DMA2_Stream0
NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}Спойлер
Код: Выделить всё
void Usart1_send(uint8_t *data, uint8_t len)
{
uint8_t i;
DMA2_Stream7-> CR &=~ DMA_SxCR_EN; //wait transmit all data
DMA2->HIFCR |= DMA_HIFCR_CTCIF6; //clear flag transmit
for(i = 0; i < len; i++)
{
txData[i] = *data++; //copy data to buff
}
DMA2_Stream7->M0AR |=(uint32_t)&txData;
DMA2_Stream7->NDTR = len; //Set len
DMA2_Stream7->CR |= DMA_SxCR_EN; //enable DMA
}- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: stm32f4 usart+DMA
ivan dimir, рекомендую очень сильно подумать над вот этими строчками
Код: Выделить всё
DMA2_Stream7->PAR |=(uint32_t)&USART1->DR;
DMA2_Stream7->M0AR |=(uint32_t)&txData;-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32f4 usart+DMA
Вы имеете ввиду что эти строки не там записаны?
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: stm32f4 usart+DMA
Нет, я имел в виду ПОДУМАТЬ что там написано. Не работает, кстати, не из-за них.
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32f4 usart+DMA
Первая строка правильная.А вот вторая?
Добавлено after 4 minutes 44 seconds:
Ну я код в нете скачал.
Добавлено after 4 minutes 44 seconds:
Ну я код в нете скачал.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: stm32f4 usart+DMA
Обе неправильные. Мне вооооооообще пофиг где вы их скачали. Вижу какашку - говорю какашка.
А не работает, скорее всего, из-за DMA_SxCR_DIR.
А не работает, скорее всего, из-за DMA_SxCR_DIR.
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32f4 usart+DMA
Я настраивал по аналогии с АЦП-ДМА.Но ацп не usart
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: stm32f4 usart+DMA
Мне всё равно 
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32f4 usart+DMA
Спойлер
Код: Выделить всё
DMA2_Stream7->CR|=_VAL2FLD( DMA_SxCR_DIR,0);Спойлер
Код: Выделить всё
Bits 7:6 DIR[1:0]: Data transfer direction
These bits are set and cleared by software.
00: Peripheral-to-memory
01: Memory-to-peripheral
10: Memory-to-memory
11: reserved
These bits are protected and can be written only if EN is ‘0’Нужно подумать.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: stm32f4 usart+DMA
В этой строке две ошибки минимум.
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32f4 usart+DMA
Спойлер
Код: Выделить всё
DMA2_Stream7->CR &=~( DMA_SxCR_DIR);Re: stm32f4 usart+DMA
Я предпочитаю при настройке прописывать все флаги и записывать одной командой. И сразу видно, где-что не так настроено, да ведь, ivan dimir?
Код: Выделить всё
// RM0385, p.283
dma_stream_tx -> CR =
(
( dma_tx_ch_n << DMA_SxCR_CHSEL_Pos ) | // select channel
( 0x0 << DMA_SxCR_MBURST_Pos ) | // memory burst: single transfer
( 0x0 << DMA_SxCR_PBURST_Pos ) | // perifery burst: single transfer
( 0 << DMA_SxCR_CT_Pos ) | // curr. target (only in DB-mode)
( 0 << DMA_SxCR_DBM_Pos ) | // double-buffer mode
( 0x0 << DMA_SxCR_PL_Pos ) | // 0 - low priority
( 0 << DMA_SxCR_PINCOS_Pos ) | // perifery offset size
( 0x0 << DMA_SxCR_MSIZE_Pos ) | // memory data size is 8 bits
( 0x0 << DMA_SxCR_PSIZE_Pos ) | // perifery data size is 8 bits
( 1 << DMA_SxCR_MINC_Pos ) | // memory increment mode
( 0 << DMA_SxCR_PINC_Pos ) | // perifery increment mode
( 0 << DMA_SxCR_CIRC_Pos ) | // circular mode
( 0x1 << DMA_SxCR_DIR_Pos ) | // direction: 0-p2m, 1-m2p
( 0 << DMA_SxCR_PFCTRL_Pos ) | // perifery flow control
( 1 << DMA_SxCR_TCIE_Pos ) | // transf. complete int. enable
( 0 << DMA_SxCR_HTIE_Pos ) | // half-transf. complete int. enable
( 1 << DMA_SxCR_TEIE_Pos ) | // transf. error int. enable
( 0 << DMA_SxCR_DMEIE_Pos ) // direct-mode err. int. enable
);
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32f4 usart+DMA
я кажется понял.Посмотрел одно видео.Дюдюка прав .3 строчки неправильно настроены.Да Usart не ADC.Там всё наоборот.Настренно как на приём .
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: stm32f4 usart+DMA
[uquote="ivan dimir",url="/forum/viewtopic.php?p=4173017#p4173017"]В зтой строке?[/uquote]О, хомячки начали о чём-то догадываться. А правильное значение DMA_SxCR_DIR таки какое?
И что насчёт тех двух строк с адресами?
Добавлено after 20 minutes 8 seconds:
tonyk, с макросом _VAL2FLD безопасней (он маску на значение накладывает) и короче запись. В случае с DMA бит вкл/выкл приходится дёргать - удобно задать конфиг константой и добавлять только бит включения когда надо.
И что насчёт тех двух строк с адресами?
Добавлено after 20 minutes 8 seconds:
tonyk, с макросом _VAL2FLD безопасней (он маску на значение накладывает) и короче запись. В случае с DMA бит вкл/выкл приходится дёргать - удобно задать конфиг константой и добавлять только бит включения когда надо.
-
ivan dimir
- Мучитель микросхем
- Сообщения: 440
- Зарегистрирован: Вс дек 29, 2019 08:05:21
Re: stm32f4 usart+DMA
Спойлер
Код: Выделить всё
void USART1_DMA2_stream7init(void)
{
GPIOA->MODER |= GPIO_MODER_MODE9_1 | GPIO_MODER_MODE10_1;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9;
GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR10;
GPIOA->AFR[1]|=_VAL2FLD(GPIO_AFRH_AFSEL9,7);
GPIOA->AFR[1]|=_VAL2FLD(GPIO_AFRH_AFSEL10,7);
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
RCC->AHB1ENR |=RCC_AHB1ENR_DMA2EN;
USART1->CR1 |= USART_CR1_TE; // ��������� ����������
// USART1->CR1 |= USART_CR1_RE;
USART1->BRR=(APBCLK+BAUDRATE/2)/BAUDRATE;
MODIFY_REG(USART1->CR1,
USART_CR1_M | USART_CR1_PCE | USART_CR1_PS,USART_CR1_TE );
USART1-> CR3|=USART_CR3_DMAT;
//USART1->CR1 |= USART_CR1_RXNEIE;
USART1->CR1 |= USART_CR1_UE; // ��������� USART
// ��������� ���������� �� ������ ������
DMA2_Stream7->CR = 0;
DMA2_Stream7->PAR |=(uint32_t)&txData;
DMA2_Stream7->M0AR |=(uint32_t)&USART1->DR;
DMA2_Stream7->CR&=~DMA_SxCR_PINC;
DMA2_Stream7->CR|=DMA_SxCR_MINC;
DMA2_Stream7->CR|= DMA_SxCR_PSIZE_0;
DMA2_Stream7->CR|= DMA_SxCR_MSIZE_0;
DMA2_Stream7->CR|=_VAL2FLD(DMA_SxCR_CHSEL,4 );
DMA2_Stream7->CR&=~ DMA_SxCR_PFCTRL;//DMA ma
DMA2_Stream7->CR|= DMA_SxCR_PL; //DMA ma
//DMA2_Stream0->FCR|=DMA_SxFCR_DMDIS;//��������� fIFO
DMA2_Stream7->CR |= DMA_SxCR_DIR_0;
DMA2_Stream7->CR|= DMA_SxCR_CIRC;
DMA2_Stream7->CR|=DMA_SxCR_TCIE;
DMA2_Stream7->CR|=DMA_SxCR_TEIE;
DMA2->HIFCR|=DMA_HIFCR_CFEIF7|DMA_HIFCR_CDMEIF7| DMA_HIFCR_CTEIF7|DMA_HIFCR_CHTIF7 |DMA_HIFCR_CTCIF7 ;
DMA2_Stream7->CR|=DMA_SxCR_DMEIE;
DMA2_Stream7->CR|= DMA_SxCR_EN;//��� DMA2_Stream0
// USART1-> CR3|=USART_CR3_DMAT;
NVIC_EnableIRQ(DMA2_Stream7_IRQn);
}

