Содержание
Урок 1. Первый проект
Урок 2. Управление кнопками
Урок 3. Подключение LCD
Урок 4. Использование ШИМ
Урок 5. Таймеры
Урок 6.1. Статическая индикация
Урок 6.2. Динамическая индикация
Урок 7.1. Генерация звука
Урок 7.2. Генерация звука. Продолжение
Урок 8.1. Передача данных через UART
Урок 8.2. Передача данных через UART. Продолжение»
Урок 9. Передача данных через SPI
Урок 10. Изучение АЦП. Простой вольтметр
Урок 11. Получение синуса при помощи ШИМ
Урок 12. Измерение температуры
Урок 13. Внешние прерывания.
Урок 14. Использование отладчика
Урок 15.1. Управление инкрементальным энкодером
Урок 15.2. Управление громкостью, при помощи энкодера
Урок 16. Управление RGB светодиодом
Урок 17. Использование ИК
Урок 18.1. Знакомство с графическим дисплеем
Урок 18.2 Вывод изображения на графический дисплей
Урок 18.3 Вывод русскоязычного текста
Урок 19. Формирование сигнала, при помощи ЦАП (R2R)
Урок 20. Опрос матричной клавиатуры
Урок 21. Сторожевой таймер
Урок 22.1 Воспроизведение wav. Введение.
Урок 22.2 Воспроизведение wav. Продолжение.
Урок 23.1 Работа с внешней памятью
Урок 23.2 Работа с файловой системой Fat

Судя по всему прошлый пример, не смотря на простоту идеи получился весьма не удачным. Суть идеи была поделить входную частоту кварца (100МГц), до воспринимаемых человеком 1-2Гц. Вроде как получилось, но осталось больше вопросов, чем ответов, поэтому я решил продолжить изыскания в этой области.

Начнем с вопросов. Оказалось самым сложным сформировать точную задержку. Попытаюсь донести идею. У нас в распоряжении только логика, никаких переменных, циклов и пр. В прошлой статье, я пытался донести, что можно использовать делитель частоты на D триггерах. Но если все время делить частоту пополам, после первого триггера 50Мгц, после второго 25 и т.д. В итоге у нас будет дробная частота, самое близкое к 1Гц это 1,49Гц, на это потребуется 26 D триггеров(делителей). Для компиляции прошлого проекта было «скушано» 62 логических элемента из 240, на мой взгляд это слишком круто, для того чтобы просто помигать диодом.

Но хотелось более точных формирований временных промежутков. В долгих поисках, ничего лучше чем сделать счетчик и считать до определенного значения я не нашел. Работает это так: считаем например от 0 до 100, при достижении 100 сбрасываем счетчик в 0 и инвертируем некий регистр, который будет входной частотой для какого то другого процесса, делитель при этом получится 200, ибо 100 это половина периода.

Реализовать это в виде схемы сложно, зато на Verilog написать легко: входная частота osc, счетчик count, выход clk

module reduced_osc (osc, clk);

input osc;               // Output of internal osc
output clk;              // Reduced frequency clock

reg [25:0] count;
reg clk;

initial
begin
count = 0;
clk = 0;
end

always @ (posedge osc) begin
count <= count + 1;
if(count == 100)begin
clk <= !clk;
end
end
endmodule

Сразу видно, чем ниже выходная частота, тем больше жрет ресурсов, а если посмотреть RTL схему, то волосы зашевелятся даже там где их нет. Но зато работает точно и исправно. Я запросто намутил себе меандр 1Гц, 10кГц, и 100кГц, поделив соответственно на 50 000 000, 5 000 и 500.
1hz

10khz

100khz

Можно заметить что счетчик count в зависимости от того, на сколько будем делить, можно делать разной разрядности, поэтому, если в схеме не нужна большая скорость, нет смысла ставить большой кварц, это сэкономит ресурсы.

Для отсчета секундных промежутков можно тактироваться от часового кварца на 32768Гц, но на мой взгляд весь кайф в том, чтобы все реализовывать внутри плисины, при этом максимально уменьшая габариты конечного устройства. В общем, сделать можно, но следует несколько раз подумать, ибо формирование длинных промежутков времени не та задача, ради которой стоит юзать ПЛИС, микроконтроллер с этим явно справится лучше.

После того, как стало понятно как отмерить временной промежуток, я решил сделать себе таймер. Но возможности марсохода оказались весьма ущербными, ибо доступных юзеру ножек совсем мало, поэтому я не стал цеплять больше одного индикатора. Мой индикатор с общим анодом, т.е. сегмент включается при наличии нуля на ножке, а не единицы.
sa56

Очень важно!!! У платы марсоход 1, некоторые ножки объединены по схеме, по умолчанию не настроенные ножки сидят на земле. Таким образом когда вы включаете ножку и если она объединена с другой, можно устроить коротыш. В общем, не подключенные ножки нужно обязательно настроить как входы (Tri-z). Привязку ножек к сегментам можно посмотреть в Pin planner, резисторы на 100 Ом.

Теперь к прошивке. Если бы мы жили в средние века, инквизиторы наверняка сожгли бы меня на костре, за такой код. В общем понятно, что можно заюзать BCD, как скилл прокачаю, дополню статью. Пока как есть.

module test_timer (osc, clk, e, d, c, b, a, f, g);

input osc;               // Output of internal osc
output clk;              // Reduced frequency clock
output e;output d;output c;output b; //ножки сегментов
output a;output f;output g;

reg [26:0] count;
reg [3:0] sek;
reg clk;
reg e;reg d;reg c;reg b;reg a;reg f; reg g;

initial
begin
count = 0;
clk=0;
e=1;d=1;c=1; b=1;a=1;f=1; g=1;
end

always @ (posedge clk) begin
sek <= sek + 1;
if(sek==0)begin
e <= 0; d <= 0; c <= 0; b <= 0;
a <= 0; f <= 0; g <= 1;  
end
if(sek==1)begin
e <= 1; d <= 1; c <= 0; b <= 0;
a <= 1; f <= 1; g <= 1;  
end
if(sek==2)begin 
e <= 0; d <= 0; c <= 1; b <= 0;
a <= 0; f <= 1; g <= 0;  
end
if(sek==3)begin
e <= 1; d <= 0; c <= 0; b <= 0;
a <= 0; f <= 1; g <= 0;  
end
if(sek==4)begin
e <= 1; d <= 1; c <= 0; b <= 0;
a <= 1; f <= 0; g <= 0;  
end
if(sek==5)begin
e <= 1; d <= 0; c <= 0; b <= 1;
a <= 0; f <= 0; g <= 0;  
end
if(sek==6)begin
e <= 0; d <= 0; c <= 0; b <= 1;
a <= 0; f <= 0; g <= 0;  
end
if(sek==7)begin
e <= 1; d <= 1; c <= 0; b <= 0;
a <= 0; f <= 1; g <= 1;  
end
if(sek==8)begin
e <= 0; d <= 0; c <= 0; b <= 0;
a <= 0; f <= 0; g <= 0;  
end
if(sek==9)begin
e <= 1; d <= 0; c <= 0; b <= 0;
a <= 0; f <= 0; g <= 0;
sek<=0;  
end
end

always @ (posedge osc) begin  
count <= count + 1;
if(count == 50000000)
begin
clk <= !clk;
count <= 0;
end
end
endmodule

Пояснять тут особо нечего, если секунда 0, то включаем сегменты e, d, c, b, a, f. При этом g выключаем. Когда секунда равна 1, c и b включены, а остальные выключены и т.д. Второй блок это делитель частоты. Собственно все.

Проект кактуса

5 комментариев: Таймер на CPLD

  • иван:

    Про tri-state на ножки и коротыш написано у марсохода в статье по сборке первого проекта.

  • admin:

    Да, но не забывайте, когда человек впервые берет в руки совершенно новую для него девайсину, то не знаешь всех тонкостей. Был у меня программатор, у которого не было никакой защиты по питанию, а узнал я об этом, когда случайно перепутал концы, сдох сразу. Поэтому стараюсь избегать всех возможных ситуаций, где можно накосячить, ибо рано или поздно это все равно случится.

  • иван:

    Правильно, что написали про особенность, я не спорю. За плевок в сторону довольно неплохого проекта обидно.

  • admin:

    Написал помягче дабы не обидеть никого) Мои претензии к первой плате, в моем видении она должна быть другой, вот и все.

  • Олег:

    Светодиодик мигает еще на плате =)

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Счетчик
Яндекс.Метрика