Дисплеи, датчики и прочие функциональные узлы, управляемые МК.
Ответить

Помогите вывести значение на семисегментники через 74HC595

Чт мар 12, 2015 10:32:29

Возможно у кого то есть программа с хорошо расжованным обьяснением работы, для вывода на 1-3 трехзначных семисегментника через 74HC595.
Те что находил были заточены под конкретное устройство.

Зарание благодарен.

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 10:56:32

Любая программа пишется под конкретное устройство. Ибо дуализм. Итого - вашу схему.

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:05:07

djrec писал(а):Те что находил были заточены под конкретное устройство
А чем они будут отличаться от тех, которые "возможно у кого то есть" ?
Они также будут заточены под конкретную схему подключения, которую, кстати, Вы не показали.
Или опять ищем экстрасенсов ?

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:12:03

любая задача разделяется на ряд подзадач. в частности, ваша делится на:
1. вывод информации на 595-е регистры. характер информации роли не играет, поэтому эта часть может быть взята из любого проекта и сводится в сущности к использованию аппаратного или программного SPI-подобного протокола.
2. преобразование числа в соответствующие символы. задача не связана с индикацией вообще. решается либо использованием стандартных функций типа itoa или sprintf, либо самодельных. решение этой задачи так же можно взять из любого проекта.
3. преобразование символа в соответствующие сегменты индикаторов. задача сводится к выбору из массива: в самом массиве хранятся представления символа в виде "сегментов" (т.е. байты, каждый бит которого отвечает за свечение определенного сегмента), номер элемента массива соответствует номеру соответствующего символа. для вывода чисел, соответственно хватит массива из 10 байтов. решение задачи очень простое, можно самому сделать, или поискать решения "два в одном" - для этого и предыдущего пункта одновременно.
4. последняя задача - вывод подготовленных байтов с сегментами в регистры. решение заключается в использоваии решения 1 пункта нужное количество раз для отправки в регистры байтов из решения 3-го пункта.

в чем проблема у вас? разве все, что я написал - непосильно?!

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:20:07

Функцию которую можно было бы не сложно переделать под любые три ноги мк. То есть с комментариями. Схемы нет, сделал бы отдельно под предложенный вариант.

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:22:50

в чем проблема у вас? разве все, что я написал - непосильно?!
А Вы посмотрите на его другие посты. Сплошные неоднозначные глупые вопросы, на которые нет однозначных ответов. Ни в одном вопросе нет описания конкретных проблем, только одни хотелки и сплошное "дайте" и "подайте".
ТС, в чём у Вас КОНКРЕТНО проблема или затык ?
Если не конкретизируете свои проблемы - тема полетит в помойку. Также, всех остальных подобных от Вас тем, ждёт та же учесть.
Надоело уже одно и тоже твердить!

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:23:53

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

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:28:39

djrec писал(а):сделал бы отдельно под предложенный вариант.
djrec писал(а):те что находил были заточены под конкретное устройство
В чём проблема ? Делайте !

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:32:03

ARV писал(а):любая задача разделяется на ряд подзадач. в частности, ваша делится на:
1. вывод информации на 595-е регистры. характер информации роли не играет, поэтому эта часть может быть взята из любого проекта и сводится в сущности к использованию аппаратного или программного SPI-подобного протокола.
2. преобразование числа в соответствующие символы. задача не связана с индикацией вообще. решается либо использованием стандартных функций типа itoa или sprintf, либо самодельных. решение этой задачи так же можно взять из любого проекта.
3. преобразование символа в соответствующие сегменты индикаторов. задача сводится к выбору из массива: в самом массиве хранятся представления символа в виде "сегментов" (т.е. байты, каждый бит которого отвечает за свечение определенного сегмента), номер элемента массива соответствует номеру соответствующего символа. для вывода чисел, соответственно хватит массива из 10 байтов. решение задачи очень простое, можно самому сделать, или поискать решения "два в одном" - для этого и предыдущего пункта одновременно.
4. последняя задача - вывод подготовленных байтов с сегментами в регистры. решение заключается в использоваии решения 1 пункта нужное количество раз для отправки в регистры байтов из решения 3-го пункта.

в чем проблема у вас? разве все, что я написал - непосильно?!


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

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:38:20

djrec писал(а):функцию которой пользуются многие

Приведите одну.

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:40:37

ARV писал(а):во-первых, пока схемы у вас не будет - не пойдет дело.
во-вторых, вы сами что умеете делать? любой ножкой самостоятельно программно можете дрыгнуть?


Уже могу и ножкой и выводил на семисегментник температуру с датчика 18в20, но семисегментник сьедает много ног.

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 11:47:29

djrec писал(а):Проблема наверное в плохом понимании работы регистров.

Чего там понимать-то? ST_CP опустили, 8 тактов на SH_CP дали одновременно с ними на DS данные побитно выдали, ST_CP подняли, все первый переданный бит на Q7, последний на Q0. Тема по SPI у вас есть уже, можно было и ей обойтись...
djrec писал(а): при их изучении, вывод бегущего огонька, так и не смог добиться стабильной работы. По этому ищу проверенную функцию которой пользуются многие с описанием.

Обычно показывают что набыдлокодили, тогда вам и покажут где криво сделано и как надо.

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 13:08:16

Первый 595
Q0-A
Q1-B
Q2-C
Q3-D
Q4-E
Q5-F
Q6-G
Q7-DP

Второй 595

Q0-1 сегмент
Q1-2 сегмент
Q2-3 сегмент

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

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 13:28:20

На форуме есть множество разделов, в том числе и "Есть работа", в которую и обращаются со словами "Хочу", "Надо" и т.д... , со всеми высасываниями из Вас необходимой информации и хотелок.
А тут - технический раздел !
Выкладывайте сами всю необходимую информацию - схемы, коды, и т.д... и объясняйте что конкретно у Вас не получается. Тогда будем разбираться.

Re: Помогите вывести значение на семисегментники через 74HC5

Чт мар 12, 2015 14:16:41

djrec писал(а):По тому что я разрабатываю устройства с нуля, а не просто копирую как многие. По этому и получается много не ясностей, и в процессе обсуждения с Вами и рождается истина. Зачем же так пинать, ведь я так полагаю форум и сделан для того что бы не знающий смог разобраться, пойти по дороге которую многие уже давно знают, а не каждый раз изобретать велосипед. Спасибо за понимание.

это очень похвально, что вы идете своей дорогой - я сам такой, что бывает велосипед изобретаю, но зато самостоятельно.
и тем не менее, советую более детально изучить проблему и показывать на форуме уже конкретные свои наработки, чтобы всем, кто готов вам помочь, было ясно, в чем у вас проблема. вот вам пример с этого же форума (не надо далеко ходить): viewtopic.php?f=61&t=112810
человек нарисовал схему
Изображение
и ему по этой схеме помогают. в частности, можно рассказывать, какие сигналы куда идут и для чего - это про регистры. можно показывать кусочки кода, которые эти сигналы формируют. можно про алгоритмы для этой схемы говорить... а что у вас?

я, например, 100500 раз приводил примеры кода для последовательного вывода, но раз вы ими не воспользовались, значит, либо не потрудились найти, либо не смогли их понять. как я могу еще вам помочь, если не знаю, по какой причине у вас проблема? где куски кода, которые у вас не работают? о чем мы вообще говорим?

Re: Помогите вывести значение на семисегментники через 74HC5

Пт мар 13, 2015 00:12:09

Взял за основу http://radioparty.ru/prog-avr/program-c ... on-74hc595

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

Изображение

Спойлер
Код:
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
 volatile unsigned int  temperature;
// Массив значениий для семисегментного индикатора
//----------                     
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D,
//----------
                   0x7D, 0x07, 0x7F, 0x6F, 0x00, 0x01, 0x02, 0x04};
 
// Функция вывода данных через регистр
 void write_display(unsigned char *data, unsigned char nbytes)
  {
    unsigned char mask,i;

  for(i = 0; i < nbytes; i++)
   
     {
       mask = 0x80;
      
       for(char k = 0; k < 8; k++)
        {
            // сравниваем каждый бит с единицей
          if(data[i] & mask)
            {
              PORTC |= (1 << PC0); // DATA 1
              PORTC |= (1 << PC2); // CLK 1
              PORTC &= ~(1 << PC2); // CLK 0
            }
          else
          {
             PORTC &= ~(1 << PC0); // DATA 0
             PORTC |= (1 << PC2); // CLK 1
             PORTC &= ~(1 << PC2); // CLK 0
          }
            mask = mask >> 1; // сдвигаем биты
          }
       
      }
         // защелкиваем регистр
      PORTC |= (1 << PC1);
      PORTC &= ~(1 << PC1);
 }
 
int main(void)
{
DDRC = 0b00000111;
PORTC = 0b00000000;
sei(); // Глобально разрешаем прерывания
 
unsigned char display[6];
 
while(1)
{


/*// Если температура меньше 100 градусов гасим незначащий ноль
if(temperature < 100)
{
display[0] =  SEGMENTE[temperature % 10];
display[1] =  SEGMENTE[(temperature / 10) % 10];
display[2] =  SEGMENTE[10];
}
// Иначе показываем все разряды
else */
{
   
temperature=123;

display[0] =  SEGMENTE[11];     
display[1] =  SEGMENTE[temperature % 10];
display[2] =  SEGMENTE[12];
display[3] =  SEGMENTE[(temperature / 10) % 10];
display[4] =  SEGMENTE[13];
display[5] =  SEGMENTE[(temperature / 100) % 10];
}
// Отправляем данные на индикатор
write_display(display,6);
}
}
Последний раз редактировалось Аlex Пт мар 13, 2015 08:17:09, всего редактировалось 1 раз.
Причина: Теги CODE, SPOLER

Re: Помогите вывести значение на семисегментники через 74HC5

Пт мар 13, 2015 06:57:23

во-первых, код надо вставлять в сообщение при помощи тегов Code
во-вторых, индикация у вас динамическая, т.е. вы просто обязаны постоянно и непрерывно обновлять состояние индикатора, зажигая поочередно все разряды, чтобы создавалась иллюзия одновременного свечения всех. то есть у вас алгоритм должен быть таким:
1. вывели сегменты 1-го разряда и соответственно включили его
2. подождали чуть-чуть
3. вывели сегменты 2-го разряда и соответственно включили его
4. подождали чуть-чуть
5. и так далее

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

лучше всего вышеописанный алгоритм реализуется по прерываниям от таймера. у вас, кстати, в коде есть команда разрешения прерываний, но никаких прерываний не используется. так вот, настройте любой таймер так, чтобы он генерировал прерывания примерно 30-100 раз в секунду, а в обработчике этого прерывания и занимайтесь выводом очередного разряда на индикатор. то есть в прерывании вы будете использовать вашу (кривенькую, правда) функцию write_display для вывода всего 2 байт: первый - это активация нужного разряда (в байте должен быть активным только 1 бит, подающий нужный уровень на общий анод или катод индикатора), а второй - это байт с нужными сегментами для этого разряда.

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

а в основной программе вам надо будет только обновлять содержимое тех ячеек памяти, которые содержат данные о сегментах для разрядов. в общем, читайте вышеописанную статью и пробуйте! :)

Re: Помогите вывести значение на семисегментники через 74HC5

Пт мар 13, 2015 08:15:51

djrec писал(а):// Отправляем данные на индикатор
write_display(display,6);
}
А почему 6 байт отправляете ? Регистров то всего 2, по одному байту.
Вам нужно поочерёдно выводить на шину пачки по 2 байта. В первом будет бегать нолик по битам, во втором - данные, которые нужно вывести конкретно на этот индикатор. И это нужно делать в каком-нибудь периодично-повторяющемся месте, например, как уже сказали выше, в обработчике прерываний от таймера.
С частотой. 30-100 Гц будет маловато. Частота вызовов должны быть не менее 50Гц * кол-во индикаторов. Т.е. в Вашем случае = 200 раз в секунду. Я обычно вывожу с частотой 1 Кгц. Совместно с системными тиками.
И ещё, подшаманьте с функцией вывода данных, её у Вас можно хорошо пооптимизировать.
Мало того, в Вашем случае нецелесообразно передавать в функцию кол-во байтов и перебирать их там в цикле, т.к. их у Вас всего 2. Логично сделать функцию вывода 1 байта и туда по-очереди передавать 2 байта.
Т.е., приблизительно так :
Код:
void write_data(unsigned char data){
unsigned char i=8;
  while(i--){
    if(data & 0x80) PORTB |= (1 << PB0); // DATA 1
    else            PORTB &= ~(1 << PB0); // DATA 0
    PORTB |= (1 << PB2); // CLK 1
    PORTB &= ~(1 << PB2); // CLK 0
    data<<=1;
  }
// защелкиваем регистр
PORTB |= (1 << PB1);
PORTB &= ~(1 << PB1);
}
.................
.................

write_data(aaaa);  // Выводим байт со сдвинутым нулём на позицию, соответствующей текущему индикатору
write_data(bbbb);  // Выводим байт данных, соответствующих текущему индикатору


Защёлкивание можно сделать отдельно, и вызывать после передачи обоих байтов. Дабы данные выводились на индикаторы одновременно.

Re: Помогите вывести значение на семисегментники через 74HC5

Пт мар 13, 2015 08:41:49

Аlex писал(а):С частотой. 30-100 Гц будет маловато. Частота вызовов должны быть не менее 50Гц * кол-во индикаторов. Т.е. в Вашем случае = 200 раз в секунду.

да, это я погорячился слегка: имел ввиду, что каждый индикатор должен мерцать с этой частотой, но написал совсем другое... виноват :oops:

да, главное: защелкивать регистр надо после вывода 2-х байтов, а не после каждого, иначе будет фигня, они же оба одновременно защелкиваются
Последний раз редактировалось ARV Пт мар 13, 2015 08:45:28, всего редактировалось 1 раз.

Re: Помогите вывести значение на семисегментники через 74HC5

Пт мар 13, 2015 08:44:58

Ничего страшного, бывает :)
Главное, что человек начал что-то делать сам. Теперь становится охота ему как-то помогать... :tea:
Ответить