реклама на сайте
подробности

 
 
> Проблемы при проектировании приёмника последовательного интерфейса, Коррекция частот
MIX@
сообщение Jan 21 2009, 22:58
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 53
Регистрация: 21-01-09
Пользователь №: 43 756



Доброго времени суток!

Делаю свой первый конфигурируемый приёмник асинхронного последовательного протокола. Конфигурация подразумевает возможность
программного задания скорости приёма.

Соответсвенно, что есть -
есть некоторая частота осциллятора и есть значения частот семплирования линии, рассчитанные
как скорость приёма (baud) умноженная на 64. Множитель 64 взял для более точного распознавания стартового перепада.

Скажем, baud = 115200 Гц => baud*64 = 7 372 800 Гц
Пусть частота осциллятора равна 40 МГц, тогда для получения baud*64 получаем коэффициент деления 5,42.
Тут и начинаются проблемы - если взять, например, 5-ку, то возникает погрешность...
Такая ситуация складывается с любыми значениями baud => нужно корректировать частоту, чтобы избежать рассогласования приёмника и передатчика и сделать это максимально прозрачно для всех остальных компонентов блока приёмника.
Единственный вариант, который пришёл мне в голову - вынести это в блок семплирования линии.

В чём суть, более подробно: рассчитанный коэффициент деления даёт нам в аккурат частоту в 1/64 baud,
но поскольку приходится его округлять, то новый коэффициент уже не будет отмерять ровно по 1/64 baud, т.е.
нужно рассчитать какова новая частота семплирования и подогнать под значение нашего множителя.
Проще говоря: при значении 5 - значение множителя будет 69, а не 64. Для baud 57600 - 63, а не 64 и т.д.
Только для 9600 получилось в аккурат 64 wink.gif
Но хочется, чтобы управляющий автомат так и работал с одним коэффициентом (64), чтобы его ещё больше не усложнять.

Следовательно - как вариант, в блоке семплирования завести внутренний служебный счётчик, который бы отсчитывал реальное кол-во импульсов,
а на выход выдавал уже скорректированное.

Вот пример verilog-кода, демонстрирующий сказанное:

Код
case (baud_num)
    1: begin
        value <= value + 1;  // baud = 9600
        inner_cnt <= 0;
       end
    default: begin    //baud = 115200
        inner_cnt <= inner_cnt + 1;
        value <= (inner_cnt == 12 ||
            inner_cnt == 24 ||      //Такое условие сделал, чтобы более равномерно
            inner_cnt == 36 ||      // провести коррекцию в статистическом смысле
            inner_cnt == 48 ||
            inner_cnt == 60) ? value : value + 1;
        end
endcase


И всё бы ничего - если бы данное решение занимало малое количество логических элементов, так нет...
Может быть, есть какие-то другие способы решить данную проблему, при этом более экономно расходуя ресурсы?

Заранее благодарю за советы.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Builder
сообщение Jan 22 2009, 07:58
Сообщение #2


iBuilder©
****

Группа: Свой
Сообщений: 519
Регистрация: 14-07-04
Из: Минск
Пользователь №: 322



Цитата(MIX@ @ Jan 22 2009, 02:58) *
И всё бы ничего - если бы данное решение занимало малое количество логических элементов, так нет...
Может быть, есть какие-то другие способы решить данную проблему, при этом более экономно расходуя ресурсы?

Если не передумаете использовать деление на 64, как Вам советовали, ещё вариант - использовать для деления
метод оценочной функции, получится типа того, как в алгоритме брезенхема делается, при отрисовке линии.

Получится делитель, с автоматическим учётом округлений. Вот только сколько ресурсов будет - надо пробовать, но
скорее всего меньше, чем Ваш вариант.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 13:28
Рейтинг@Mail.ru


Страница сгенерированна за 0.01361 секунд с 7
ELECTRONIX ©2004-2016