Я пытаюсь написать цифровые часы на vhdl для fpga, работающего на частоте 100 МГц. Я могу записать это на 4 анода, создав счетчик, как показано ниже (count1 = 249999), цифры кажутся довольно четкими. Однако, когда я хочу отобразить время в формате ЧЧ:ММ:СС (когда я хочу использовать 6 анодов вместо 4), я не могу четко отображать цифры. Когда я сильно увеличиваю значение count1, светодиоды начинают мигать, когда я уменьшаю значение count1, цифры трудно идентифицировать.
Есть ли какой-либо теоретический способ определить значение этого счетчика (counter1)? Можно ли четко показать 6 цифр так, как я пытаюсь?
Спасибо с этого момента.
код, отвечающий за отображение 4-х анодов:
anode_clock : process(count1, clk_in, A_counter) -- counter to display all digits using anodes
begin
if(rising_edge(clk_in)) then
count1 <= count1 + 1;
if(count1 = 249999) then -- ATTENTION HERE
A_counter <= A_counter + 1;
count1 <= 0;
end if;
end if;
end process;
anode_display : process (A_counter, tmp_AN, min0, min1, hour0) begin -- matching anodes to display
AN <= tmp_AN;
case A_counter is
when 0 =>
tmp_AN <= "1110";
if (min0 = 0) then
DISP <= "1000000";
elsif min0 = 1 then
DISP <= "1111001";
elsif min0 = 2 then
DISP <= "0100100";
elsif min0 = 3 then
DISP <= "0110000";
elsif min0 = 4 then
DISP <= "0011001";
elsif min0 = 5 then
DISP <= "0010010";
elsif min0 = 6 then
DISP <= "0000010";
elsif min0 = 7 then
DISP <= "1111000";
elsif min0 = 8 then
DISP <= "0000000";
elsif min0 = 9 then
DISP <= "0010000";
end if;
when 1 =>
tmp_AN <= "1101";
if (min1 = 0) then
DISP <= "1000000";
elsif min1 = 1 then
DISP <= "1111001";
elsif min1 = 2 then
DISP <= "0100100";
elsif min1 = 3 then
DISP <= "0110000";
elsif min1 = 4 then
DISP <= "0011001";
elsif min1 = 5 then
DISP <= "0010010";
elsif min1 = 6 then
DISP <= "1000000";
end if;
when 2 =>
tmp_AN <= "1011";
if (hour0 = 0) then
DISP <= "1000000";
elsif hour0 = 1 then
DISP <= "1111001";
elsif hour0 = 2 then
DISP <= "0100100";
elsif hour0 = 3 then
DISP <= "0110000";
elsif hour0 = 4 then
DISP <= "0011001";
elsif hour0 = 5 then
DISP <= "0010010";
elsif hour0 = 6 then
DISP <= "0000010";
elsif hour0 = 7 then
DISP <= "1111000";
elsif hour0 = 8 then
DISP <= "0000000";
elsif hour0 = 9 then
DISP <= "0010000";
elsif hour0 = 10 then
DISP <= "1000000";
elsif hour0 = 11 then
DISP <= "1111001";
elsif hour0 = 12 then
DISP <= "0100100";
elsif hour0 = 13 then
DISP <= "1000000";
end if;
when 3 =>
tmp_AN <= "0111";
if (hour0 = 10) then
DISP <= "1111001";
elsif hour0 = 11 then
DISP <= "1111001";
elsif hour0 = 12 then
DISP <= "1111001";
else
DISP <= "1000000";
end if;
end case;
end process;
код, отвечающий за отображение 6 анодов(цифры не читаются):
anode_clock : process(count1, clk_in, A_counter) -- counter to display all digits using anodes
begin
if(rising_edge(clk_in)) then
count1 <= count1 + 1;
if(count1 = 125000) then -- experimental value: 249999
A_counter <= A_counter + 1;
count1 <= 0;
end if;
end if;
end process;
anode_display : process (A_counter, tmp_AN, sec0,sec1, min0, min1, hour0) begin -- matching anodes to display
AN <= tmp_AN;
case A_counter is
when 0 =>
tmp_AN <= "111110";
if (sec0 = 0) then
DISP <= "1000000";
elsif sec0 = 1 then
DISP <= "1111001";
elsif sec0 = 2 then
DISP <= "0100100";
elsif sec0 = 3 then
DISP <= "0110000";
elsif sec0 = 4 then
DISP <= "0011001";
elsif sec0 = 5 then
DISP <= "0010010";
elsif sec0 = 6 then
DISP <= "0000010";
elsif sec0 = 7 then
DISP <= "1111000";
elsif sec0 = 8 then
DISP <= "0000000";
elsif sec0 = 9 then
DISP <= "0010000";
end if;
when 1 =>
tmp_AN <= "111101";
if (sec1 = 0) then
DISP <= "1000000";
elsif sec1 = 1 then
DISP <= "1111001";
elsif sec1 = 2 then
DISP <= "0100100";
elsif sec1 = 3 then
DISP <= "0110000";
elsif sec1 = 4 then
DISP <= "0011001";
elsif sec1 = 5 then
DISP <= "0010010";
elsif sec1 = 6 then
DISP <= "1000000";
end if;
when 2 =>
tmp_AN <= "111011";
if (min0 = 0) then
DISP <= "1000000";
elsif min0 = 1 then
DISP <= "1111001";
elsif min0 = 2 then
DISP <= "0100100";
elsif min0 = 3 then
DISP <= "0110000";
elsif min0 = 4 then
DISP <= "0011001";
elsif min0 = 5 then
DISP <= "0010010";
elsif min0 = 6 then
DISP <= "0000010";
elsif min0 = 7 then
DISP <= "1111000";
elsif min0 = 8 then
DISP <= "0000000";
elsif min0 = 9 then
DISP <= "0010000";
end if;
when 3 =>
tmp_AN <= "110111";
if (min1 = 0) then
DISP <= "1000000";
elsif min1 = 1 then
DISP <= "1111001";
elsif min1 = 2 then
DISP <= "0100100";
elsif min1 = 3 then
DISP <= "0110000";
elsif min1 = 4 then
DISP <= "0011001";
elsif min1 = 5 then
DISP <= "0010010";
elsif min1 = 6 then
DISP <= "1000000";
end if;
when 4 =>
tmp_AN <= "101111";
if (hour0 = 0) then
DISP <= "1000000";
elsif hour0 = 1 then
DISP <= "1111001";
elsif hour0 = 2 then
DISP <= "0100100";
elsif hour0 = 3 then
DISP <= "0110000";
elsif hour0 = 4 then
DISP <= "0011001";
elsif hour0 = 5 then
DISP <= "0010010";
elsif hour0 = 6 then
DISP <= "0000010";
elsif hour0 = 7 then
DISP <= "1111000";
elsif hour0 = 8 then
DISP <= "0000000";
elsif hour0 = 9 then
DISP <= "0010000";
elsif hour0 = 10 then
DISP <= "1000000";
elsif hour0 = 11 then
DISP <= "1111001";
elsif hour0 = 12 then
DISP <= "0100100";
elsif hour0 = 13 then
DISP <= "1000000";
end if;
when 5 =>
tmp_AN <= "011111";
if (hour0 = 10) then
DISP <= "1111001";
elsif hour0 = 11 then
DISP <= "1111001";
elsif hour0 = 12 then
DISP <= "1111001";
else
DISP <= "1000000";
end if;
end case;
end process;
вывод (цифры не такие, как я хотел, что-то не так с отображением счетчика):
Это неотъемлемое ограничение мультиплексирования: поскольку вы вводите только одну цифру за раз, ваш дисплей становится тусклее по мере увеличения количества цифр. Тем не менее, вы должны быть в состоянии нормально управлять 8 цифрами.
Я бы попытался явно обернуть ваш счетчик, чтобы убедиться, что вы вводите определенную цифру в любой момент времени:
if(count1 = 249999) then -- ATTENTION HERE
A_counter <= A_counter + 1;
if(A_counter < 6) then -- 6 or 4, depending on how many digits you drive
A_counter <= A_counter + 1;
else
counter <= 0;
end if;
count1 <= 0;
end if;
Похоже, что в 6-значном коде A_COUNTER постоянно зацикливается, что означает, что есть как минимум 2 состояния, состояние 6 и состояние 7, которые явно не декодируются. Попробуйте явно отключить все сегменты для состояний 6 и 7. Если A_COUNTER больше 3 бит, вам нужно выяснить, что происходит с дисплеем, когда A_COUNTER не от 0 до 5.
Поскольку активация дисплея активна на низком уровне (0 = включено), вполне вероятно, что все сегменты включены по умолчанию, когда вы не говорите им выключить, как это может происходить в состояниях 6 и 7.
В качестве диагностического подхода, возможно, вы можете увеличить COUNT1 настолько, чтобы цифры изменялись очень медленно, чтобы вы могли наблюдать шаги освещения в замедленном темпе.
Я не уверен, что есть дополнительные случаи 6 и 7. Но поскольку 2 неиспользуемые цифры (крайние слева) включены со всеми горящими сегментами, кажется, что некоторые цифры/сегменты горят по умолчанию, если вы их не выключите. Если дел всего 6, и для каждого включена 1 цифра, то не должно быть времени, чтобы разряды 6 и 7 горели, а горят. Я считаю, что и строка, и сегмент получают (00000000,00000000) по умолчанию в течение некоторого короткого интервала и включают все цифры и все сегменты.
Проверьте это, выводя значения включения цифр с 8 двоичными цифрами (11xxxxxx), а не с 6 (xxxxxx), чтобы 2 верхние неиспользуемые цифры были отключены. Крайние 2 цифры будут тусклее, но все еще частично освещены.
В вашем коде есть некоторые проблемы, которые я бы посоветовал вам исправить, чтобы упростить отладку. Во-первых, вы несколько раз продублировали декодирование катода [сегмента] - это нужно сделать только один раз - я бы предложил процесс, который имеет текущую десятичную цифру в качестве сигнала в списке чувствительности и устанавливает сегменты. Тогда основной процесс, управляемый часами, будет намного проще без дублированного декодирования. На практике инструменты синтеза, вероятно, будут эффективно отображать такое декодирование в таблицу циклов ОЗУ на FPGA - они могут быть не в состоянии сделать это для вашего кода, например
Маршрутизация, управляемая основным тактовым сигналом, затем циклически устанавливает соответствующий десятичный сигнал и анодный сигнал. Мой подход состоял бы в том, чтобы инициализировать выход анода на «111110» и циклически сдвигать его влево на каждом тактовом цикле в синхронизированном процессе и вводить логику для установки соответствующего цифрового сигнала для отображения.
Что не ясно, так это то, какие часы вы используете для управления этим процессом. Вероятно, он не должен работать на частоте системных часов 100 МГц или около того, если управляет светодиодами - я бы посоветовал использовать его на частоте около 1 кГц или около того.
Фотон
Тони Стюарт EE75
ЭренЛ
ЭренЛ
Тони Стюарт EE75
Тони Стюарт EE75
ЭренЛ
Фотон