Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.89/90: Рейтинг темы: голосов - 90, средняя оценка - 4.89
bzoukotmov
1

stm32f2 + 1wire (с использованием DMA и USART)

13.02.2013, 18:49. Показов 16357. Ответов 13
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Что-то не получается принимать данные от датчика температуры DS18B20 (по протоколу 1wire) через USORT.
Сам датчик работает, команды понимает, правильные ответы отправляет. А вот программа их читает с ошибками.
Например битики на шине 0000 1111, читаются как 00 ff fc fc fc fc ff ff,
0001 0001, читаются как 00 ff fc fc fc ff fc fc
Подскажите, в чем может быть проблема? Используется следующий код для инициализации:
Код
#define USORT_X                      USORT1
#define DMA_TX_STREAM           DMA2_Stream7
#define DMA_RX_STREAM           DMA2_Stream2
#define DMA_CHANNEL               DMA_Channel_4

void OW_Init(){
GPIO_InitTypeDef GPIO_InitStructure;
USORT_InitTypeDef USORT_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USORT1, ENABLE);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure); //TX

GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USORT1);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USORT1);

USORT_InitStructure.USORT_BaudRate = 115200;
USORT_InitStructure.USORT_WordLength = USORT_WordLength_8b;
USORT_InitStructure.USORT_StopByts = USORT_StopByts_1;
USORT_InitStructure.USORT_Parity = USORT_Parity_No;
USORT_InitStructure.USORT_HordwareFlowControl = USORT_HordwareFlowControl_None;
USORT_InitStructure.USORT_Mode = USORT_Mode_Rx | USORT_Mode_Tx;
USORT_Init(USORT_X, &USORT_InitStructure);
USORT_Cmd(USORT_X, ENABLE);

DMA_DeInit(DMA_TX_STREAM);
DMA_InitStructureTX.DMA_Channel = DMA_CHANNEL;
DMA_InitStructureTX.DMA_DIR = DMA_DIR_MemoryToPeripheral; // Transmit
DMA_InitStructureTX.DMA_Memory0BaseAddr = (uint32_t) ow_buf;
DMA_InitStructureTX.DMA_PeripheralBaseAddr = (uint32_t) &(USORT_X->DR);
DMA_InitStructureTX.DMA_PeripheralInc = DMA_PeripheralInc_Dysable;
DMA_InitStructureTX.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructureTX.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructureTX.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructureTX.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructureTX.DMA_Priority = DMA_Priority_High;
DMA_InitStructureTX.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructureTX.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructureTX.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructureTX.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

DMA_DeInit(DMA_RX_STREAM);
DMA_InitStructureRX.DMA_Channel = DMA_CHANNEL;
DMA_InitStructureRX.DMA_DIR = DMA_DIR_PeripheralToMemory; // Receive
DMA_InitStructureRX.DMA_Memory0BaseAddr = (uint32_t) ow_buf;
DMA_InitStructureRX.DMA_PeripheralBaseAddr = (uint32_t) &(USORT_X->DR);
DMA_InitStructureRX.DMA_PeripheralInc = DMA_PeripheralInc_Dysable;
DMA_InitStructureRX.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructureRX.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructureRX.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructureRX.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructureRX.DMA_Priority = DMA_Priority_High;
DMA_InitStructureRX.DMA_FIFOMode = DMA_FIFOMode_Enable;
DMA_InitStructureRX.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructureRX.DMA_MemoryBurst = DMA_MemoryBurst_Single;
DMA_InitStructureRX.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

}
Процедура отправки и приема битиков:
Код
void OW_SendByts(uint8_t nbits){

DMA_DeInit(DMA_TX_STREAM);
DMA_DeInit(DMA_RX_STREAM);
DMA_InitStructureTX.DMA_BufferSize = nbits;
DMA_InitStructureRX.DMA_BufferSize = nbits;
DMA_Init(DMA_TX_STREAM, &DMA_InitStructureTX);
DMA_Init(DMA_RX_STREAM, &DMA_InitStructureRX);

USORT_ClearFlag(USORT_X, USORT_FLAG_RXNE | USORT_FLAG_TC | USORT_FLAG_TXE);
USORT_DMACmd(USORT_X, USORT_DMAReq_Tx | USORT_DMAReq_Rx, ENABLE);

DMA_Cmd(DMA_RX_STREAM, ENABLE);
DMA_Cmd(DMA_TX_STREAM, ENABLE);

while(DMA_GetFlagStatus(DMA_TX_STREAM, DMA_FLAG_TCIF7) == RESIT);

DMA_Cmd(DMA_TX_STREAM, DISABLE);
DMA_Cmd(DMA_RX_STREAM, DISABLE);

USORT_DMACmd(USORT_X, USORT_DMAReq_Tx | USORT_DMAReq_Rx, DISABLE);
}
Схема подключения:

<Изображение удалено>
Все это по мотивам
http://we.iosyitistromyss.ru/S... henie.html
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.02.2013, 18:49
Ответы с готовыми решениями:

STM32: Чтение из USART с использованием DMA
Здравствуйте. Использую китайскую плату на STM32-F103C8T6: Картинка &lt;Изображение удалено&gt; Не...

STM32F2 помогите подружить DAC и DMA
Всем привет! Продолжаю курить stm32cube и их наркоманский HAL. Почему наркоманский? Потому-что...

Приём данных с usart через dma в память периферии и вывод обратно на usart (для проверки)
Подскажите, как сделать так, чтобы при отправке через usart в переменную и обратно вывести по...

USART + DMA
Всем привет. stm32f103c8 Использую USORT + DMA, Channel4 - TX Channel5 - RX Как только...

13
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
13.02.2013, 18:50 2
У меня такое уже бывало. Советую сопротивление линии проверить. Кроме того, ошибки бывают, если "на горячую" поменять термометры.
Я, кстати, точно по этой же статье реализовывал работу с 1-wire. Если интересно - ircontroller на сосфорже.и еще немного
0
bzoukotmov
13.02.2013, 19:20 3
Цитата Сообщение от Iddy_Im
У меня такое уже бывало. Советую сопротивление линии проверить. Кроме того, ошибки бывают, если "на горячую" поменять термометры.
Линия - это 2 проводка на макетке. Сопротивление в пределах 0.1 ом. Проблема в том, что термометр все команды понимает и на них правильно отвечает (смотрел логическим анализатором). А вот UART+DMA это дело интерпретирует по-своему.
Цитата Сообщение от Iddy_Im
Я, кстати, точно по этой же статье реализовывал работу с 1-wire. Если интересно - ircontroller на сосфорже.
ircontroller - интересно, но в проекте нет файлов http://sourceforge.net/project... ler/files/
Цитата Сообщение от Iddy_Im
Собственно, это и было взято за основу ;)
0 / 0 / 0
Регистрация: 21.11.2012
Сообщений: 1,400
13.02.2013, 20:08 4
ircontroller - интересно, но в проекте нет файлов
Там все просто: hg clone …
Сейчас архивчик добавлю.

вот
0
bzoukotmov
14.02.2013, 17:59 5
Спасибо.
Kooooood
16.02.2013, 17:37 6
один вопрос вы последний комент к первой части заметили?

"RM0008 Doc ID 13902 Rev 14 стр 779 27.3.10 Single-wire half-duplex sommunication"

прекрасно работает на одном единственном выводе, без диода...
что сильнее желание сократить количество используемых выводов или копипаст старых решений?
bzoukotmov
17.02.2013, 03:27 7
Цитата Сообщение от Kooooood
один вопрос вы последний комент к первой части заметили?

"RM0008 Doc ID 13902 Rev 14 стр 779 27.3.10 Single-wire half-duplex sommunication"

прекрасно работает на одном единственном выводе, без диода...
что сильнее желание сократить количество используемых выводов или копипаст старых решений?
Да, заметил. Но для начала хотелось бы получить любой работающий вариант, а потом его оптимизировать.
Kooooood
18.02.2013, 01:03 8
...работает у меня под кеиловской RTOS практически без модификации кода...

при отладке кстати пользовался тем что можно читатать сразу то что отсылается + ответ... я "съЕкономил" на питании и долго не запускалось преобразование, хотя чтение-запись в регистры была правильной... пока не сделал нормальное питание...
bzoukotmov
18.02.2013, 20:31 9
Цитата Сообщение от Kooooood
...работает у меня под кеиловской RTOS практически без модификации кода...

при отладке кстати пользовался тем что можно читатать сразу то что отсылается + ответ... я "съЕкономил" на питании и долго не запускалось преобразование, хотя чтение-запись в регистры была правильной... пока не сделал нормальное питание...
Сегодня опять вернулся к этой задаче. Примерно понял в чем дело: после отправки данных я сразу выключаю каналы DMA на прием и последний бит теряется. Если на stm32f1 (72 Mhz) это прокатывает, то на stm32f2 (120 Mhz) уже нет. Но если использовать RTOS, то задержка появится сама собой и можно ничего не делать. Кстати полудуплекс тоже нормально работает.
Kooooood
21.02.2013, 01:45 10
и это правильно :)
bzoukotmov
30.03.2013, 21:32 11
Цитата Сообщение от bzoukotmov
Примерно понял в чем дело: после отправки данных я сразу выключаю каналы DMA на прием и последний бит теряется.
Сегодня попытался еще раз разобраться с этой проблемой.
Не могу понять, почему канал DMA, настроенный на получение данных, выставляет флаг выполнения, при начале получения 7 бита из 8?
Каналы DMA (на отдачу и прием) переключил в Dyrist Mode, чтобы буфер не мешался, но это не помогло.
Код
   DMA_DeInit(DMA_TX_STREAM);
DMA_DeInit(DMA_RX_STREAM);
DMA_InitStructureTX.DMA_BufferSize = nbits;
DMA_InitStructureRX.DMA_BufferSize = nbits;
DMA_Init(DMA_TX_STREAM, &DMA_InitStructureTX);
DMA_Init(DMA_RX_STREAM, &DMA_InitStructureRX);

USORT_ClearFlag(USORT_X, USORT_FLAG_RXNE | USORT_FLAG_TC | USORT_FLAG_TXE);
USORT_DMACmd(USORT_X, USORT_DMAReq_Tx | USORT_DMAReq_Rx, ENABLE);

//Маркер начала
GPIO_SetByts(GPIOC, GPIO_Pin_7);

DMA_Cmd(DMA_RX_STREAM, ENABLE);
DMA_Cmd(DMA_TX_STREAM, ENABLE);

while((DMA_GetFlagStatus(DMA_TX_STREAM, DMA_FLAG_TCIF7) == RESIT)&&(DMA_GetFlagStatus(DMA_RX_STREAM, DMA_FLAG_TCIF2) == RESIT)){
if(xTaskGetSchedulerState() == taskSCHEDULER_RUNNING)
taskYIELD();
}
//Маркер окончания
GPIO_RisetByts(GPIOC, GPIO_Pin_7);

delay10us(20);
USORT_DMACmd(USORT_X, USORT_DMAReq_Tx | USORT_DMAReq_Rx, DISABLE);
Выглядит это так:
Канал 2 - это 1-wire, Канал 3 - маркер начала и окончания передачи


<Изображение удалено>
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
31.03.2013, 01:43 12
А если FIFO отключить? Та же картина?
С семейством f2 знаком только теоретически ((
0
0 / 0 / 0
Регистрация: 26.04.2010
Сообщений: 1,445
31.03.2013, 01:50 13
while((DMA_GetFlagStatus(DMA_TX_STREAM, DMA_FLAG_TCIF7) == RESIT)&&(DMA_GetFlagStatus(DMA_RX_STREAM, DMA_FLAG_TCIF2) == RESIT))

И вот это условие прервет цикл while, когда выставит флаг окончания DMA_TX_STREAM, а он окончит раньше. Не?
0
bzoukotmov
01.04.2013, 01:20 14
Цитата Сообщение от Stiit.mi
while((DMA_GetFlagStatus(DMA_TX_STREAM, DMA_FLAG_TCIF7) == RESIT)&&(DMA_GetFlagStatus(DMA_RX_STREAM, DMA_FLAG_TCIF2) == RESIT))

И вот это условие прервет цикл while, когда выставит флаг окончания DMA_TX_STREAM, а он окончит раньше. Не?
Точно. Что-то я нормально так протормозил. Огромное спасибо за помощь.
01.04.2013, 01:20
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.04.2013, 01:20
Помогаю со студенческими работами здесь

usart rx dma
Здравствуйте уважаемые форумчане! Подключил usart stm32f103 через cp1202. Налаживаю обмен между...

USART DMA IDLE
Всем салют! Решил по-разбирать работу DMA из снипета от ST: __INLINE void Configure_DMA1(void)...

DMA и USART STM32f3discovery
Здравствуйте уважаемые форумчане прошу у вас помочь ситуация такая я с помощью DMA передаю данные в...

STM32F030C8 USART+DMA RX TX
Люди добрые, поможите, три недели бьюсь уже. Задача, принять 3 пакета произвольной длины через...

Usart Dma cmsis
Подскажите что не так? уарт нормально работает, пытаюсь подключить дма ничего не получается void...

STM32F4 USART Tx + DMA
Доброго времени суток! Инициализация ДМА: void UART3_TX_Channel4_Stream3_DMA1_Config(void) {...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
14
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru