Dima1060 0 11 ноября, 2015 Опубликовано 11 ноября, 2015 · Жалоба Здравствуйте! У меня есть несколько вопросов по работе кольцевого буфера и UART STM32F103. 1) Есть классический кольцевой буфер на 512 байт. По команде "Старт" он начинает заполняться в такой последовательности: в него записывается 38 байт, через 1,25 мс записывается 57 байт, через 1,25 мс снова 38, через 1,25 мс снова 57 байт и так далее в этой же последовательности. Чтение из кольцевого буфера осуществляется каждую 1 мс. То каждую 1 мс приходит команда, определяется кол-во данных в буфере и передаются дальше. Вопрос в том, как так получается, что в один прекрасный момент в буфере накапливается 38+57=95 байт? Я же читаю из буфера с большей частотой, чем пишу... 2) Когда задаю UART большое значение скорости (больше, чем 1,2 Мбит/с) иногда сбивается передача данных - не приходит прерывание Transmit Complete. Однако в даташите написано, что максимальная скорость 2,25 Мбит/с 3) Для передачи данных я использую прерывание Transmit Complete, но видел, некоторые используют флаг Tx Empty. Есть ли какая то принципиальная разница? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 11 ноября, 2015 Опубликовано 11 ноября, 2015 · Жалоба Вопрос в том, как так получается, что в один прекрасный момент в буфере накапливается 38+57=95 байт? Я же читаю из буфера с большей частотой, чем пишу... Ну чудес-то не бывает. Либо пропуск чтения, либо запись происходит чаще. 2) Когда задаю UART большое значение скорости (больше, чем 1,2 Мбит/с) иногда сбивается передача данных - не приходит прерывание Transmit Complete. Однако в даташите написано, что максимальная скорость 2,25 Мбит/с Значит, пропускаете прерывание. Наверное зависаете надолго в обрабротчике прерывания, или есть другие прерывания (не от UART). 3) Для передачи данных я использую прерывание Transmit Complete, но видел, некоторые используют флаг Tx Empty. Есть ли какая то принципиальная разница? Да. TXE взводится, когда опустошается буфер передатчика. Сдвиговый регистр в это время ещё занят, и передача ещё идёт. А вот когда заканчивается передача из сдвигового регистра, то взводится флаг TC. Для передачи лучше использовать TXE. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 11 ноября, 2015 Опубликовано 11 ноября, 2015 · Жалоба Ну чудес-то не бывает. Либо пропуск чтения, либо запись происходит чаще. Пропуск правда есть...я смотрел осциллографом. Перед тем как отправить 95 байт, запрос данных игнорируется. Значит, пропускаете прерывание. Наверное зависаете надолго в обрабротчике прерывания, или есть другие прерывания (не от UART). Зависаю не на долго, инкрементирую счетчик, отправляю байт и все. Другие прерывания есть, но такого же или меньшего приоритета. Например прерывание DMA такого же приоритета и зависаю я там 22 мкс, но какая разница сколько. По идее, прерывание Transmit Complete должно сколь угодно долго дожидаться... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 11 ноября, 2015 Опубликовано 11 ноября, 2015 · Жалоба Вопрос в том, как так получается, что в один прекрасный момент в буфере накапливается 38+57=95 байт? Я же читаю из буфера с большей частотой, чем пишу... Вы же не мгновенно записываете в буфер, так же и читаете из него (там еще медленнее, определяется скоростью передачи). Добавьте к 1 мс эти времена. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 11 ноября, 2015 Опубликовано 11 ноября, 2015 · Жалоба Вы же не мгновенно записываете в буфер, так же и читаете из него (там еще медленнее, определяется скоростью передачи). Добавьте к 1 мс эти времена. Не совсем понял... Ну да, не мгновенно, 38 байт переписываются в буфер примерно 44 мкс, соответственно 57 байт - 66 мкс. Читать из буфера я должен с такой скоростью, чтобы успевать передавать данные до следующего запроса - то есть должен успевать все передать за 1 мс. Скорость нормальная, если бы не приходилось вдруг передавать 95 байт - на это уже скорости не хватает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 11 ноября, 2015 Опубликовано 11 ноября, 2015 · Жалоба Читать из буфера я должен с такой скоростью, чтобы успевать передавать данные до следующего запроса - то есть должен успевать все передать за 1 мс. Скорость нормальная, если бы не приходилось вдруг передавать 95 байт - на это уже скорости не хватает. Так сколько времени нужно на передачу 57 байтов? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 11 ноября, 2015 Опубликовано 11 ноября, 2015 · Жалоба Так сколько времени нужно на передачу 57 байтов? На скорости 1,2 Мбит/с, на передачу одного бита уходит 0,84 мкс Соответственно 57 байт х 11 бит = 627 бит 627*0,84=527 мкс Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 11 ноября, 2015 Опубликовано 11 ноября, 2015 · Жалоба А времена эти, 1 мс, 1,25 мс вы жестко задаете, таймерами? Если в это время процессор занят записью или передачей, ждете, когда освободится, или ждете следующего срабатывания таймера? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 12 ноября, 2015 Опубликовано 12 ноября, 2015 · Жалоба А времена эти, 1 мс, 1,25 мс вы жестко задаете, таймерами? Если в это время процессор занят записью или передачей, ждете, когда освободится, или ждете следующего срабатывания таймера? Прерывание таймера (1,25 мс) имеет низший приоритет. Прерывания DMA на него не влияют, поскольку они этим таймером и вызываются (по таймеру начинается прием данных, окончание приема вызывает прерывание DMA, передача четко укладывается в 1,25 мс, с запасом). Прерывание UART с запросом данных (чтение из кольцевого буфера) имеет такой же приоритет, как прерывание DMA (чтобы запись и чтение из буфера были атомарными, если можно так выразиться) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 ноября, 2015 Опубликовано 12 ноября, 2015 · Жалоба Для начала измените работу с УСАРТом на от TXE. Потому что ваши расчеты времени верны для непрерывного потока битов. А с ТС есть пустое время между байтами. А 1 мс интервалы кто задает? По УСАРТУ принимаете команду? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 12 ноября, 2015 Опубликовано 12 ноября, 2015 · Жалоба Для начала измените работу с УСАРТом на от TXE. Потому что ваши расчеты времени верны для непрерывного потока битов. А с ТС есть пустое время между байтами. Меня немного смущает кое что. Если я разрешу это прерывание в main USART_ITConfig(USARTz, USART_IT_TXE, ENABLE); Меня же тут же выкинет в обработчик этого прерывания, буфер то после сброса пуст, или оно только после отправки сработает? А 1 мс интервалы кто задает? По УСАРТУ принимаете команду? Да, по USART каждую 1 мс приходит команда - запрос данных. В теле данного прерывания я считаю кол-во данных и отправляю первый байт. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 ноября, 2015 Опубликовано 12 ноября, 2015 · Жалоба Я после настроек USART делаю NVIC_ClearPendingIRQ(USART3_IRQn); потом NVIC_EnableIRQ(USART3_IRQn); Не знаю, надо ли. Может, прерывание возникает при освобождении буфера, а не когда он пустой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 12 ноября, 2015 Опубликовано 12 ноября, 2015 · Жалоба Я после настроек USART делаю NVIC_ClearPendingIRQ(USART3_IRQn); потом NVIC_EnableIRQ(USART3_IRQn); Не знаю, надо ли. Может, прерывание возникает при освобождении буфера, а не когда он пустой. а потом, когда весь массив данных передали, запрещаете это прерывание? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 12 ноября, 2015 Опубликовано 12 ноября, 2015 · Жалоба Да, когда нужно послать массив, посылаю байт, разрешаю прерывание TXE. Остальные байты посылаются по прерыванию. При передаче последнего байта запрещаю прерывание TXE. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 1 12 ноября, 2015 Опубликовано 12 ноября, 2015 · Жалоба Да, когда нужно послать массив, посылаю байт, разрешаю прерывание TXE. Остальные байты посылаются по прерыванию. При передаче последнего байта запрещаю прерывание TXE. +1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться