roboforum.ru

Технический форум по робототехнике.

Семисегментный светодиодный индикатор

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Семисегментный светодиодный индикатор

Сообщение Maxiik » 23 май 2011, 12:37

Доброго времени суток !!!
Подскажите пожалуста как можно управлять индикатором состоящим из нескольких светодиодных индикаторов ?
Точнее интересует как программа узнаёт какую конкретно цифру из большого числа нужно вывести на конкретный элемент индикатора ?
Тобишь как разделить число на отдельные цифры, при этом отбросив лишние цифры, которые "выходят" за границы индикатора, и как выделить десятичную точку если число дробное ?
Или может есть уже готовые функции или библиотеки для работы с этими индикаторами ?
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

Re: Семисегментный светодиодный индикатор

Сообщение HarryStar » 23 май 2011, 12:54

Библиотеки конечно есть, но раз у вас такие вопросы, вам лучше самому подумать как это можно сделать, будет хорошей задачей для освоения языка программирования.
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Семисегментный светодиодный индикатор

Сообщение dccharacter » 23 май 2011, 12:58

Число хранится в байт-массиве. Например число 1234 хранится в массиве chislo[4] = { 0x31, 0x32, 0x33, 0x34 }
Выводите нужное число байт начиная с нужного байта.

Добавлено спустя 2 минуты 17 секунд:
Если есть int, который надо показать, то используйте sprintf

int chislo_int;
unsigned char chislo_byte_array[10];
sprintf(chislo_byte_array, "%0.2u", chislo_int);
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: Семисегментный светодиодный индикатор

Сообщение Radist » 23 май 2011, 13:13

Maxiik писал(а):Доброго времени суток !!!
Подскажите пожалуста как можно управлять индикатором состоящим из нескольких светодиодных индикаторов ?


Есть шина данных (a,b,c,d,e,f,g,h) и шина управления транзисторами знакомест.

Maxiik писал(а):Точнее интересует как программа узнаёт какую конкретно цифру из большого числа нужно вывести на конкретный элемент индикатора ?


В памяти есть видеоОЗУ и есть переменная-указатель на текущее знакоместь. Переменная изменяется по кольцу, например (0,1,2,3,0,1,2,3)

Maxiik писал(а):Тобишь как разделить число на отдельные цифры, при этом отбросив лишние цифры, которые "выходят" за границы индикатора, и как выделить десятичную точку если число дробное ?


Как в школе учили, делением на 10 выделяем тысячи, сотни, десятки, единицы и так далее

Maxiik писал(а):Или может есть уже готовые функции или библиотеки для работы с этими индикаторами ?


Наверняка есть, кто ищет - тот найдет.
Аватара пользователя
Radist
 
Сообщения: 2253
Зарегистрирован: 01 июл 2009, 08:59
Откуда: Екатеринбург
прог. языки: асемблер AVR

Re: Семисегментный светодиодный индикатор

Сообщение Maxiik » 23 май 2011, 13:16

Если есть int, который надо показать, то используйте sprintf

int chislo_int;
unsigned char chislo_byte_array[10];
sprintf(chislo_byte_array, "%0.2u", chislo_int);

***
chislo_int; - это переменная которой присваивается число (например значение температуры, полученое от температурного датчика, например 45.356748 )

unsigned char chislo_byte_array[10]; - это наименование массива, содержащенго беззнаковые переменные целые числа.
Имя массива chislo_byte_array и содержит он 10 значений (цифер)
Что-то не совсем понимаю. что дальше идёт...
Функция вывода...
подскажите как она дальше работает и исправьте пожалуста, если я начало понял не правильно...
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

Re: Семисегментный светодиодный индикатор

Сообщение dccharacter » 23 май 2011, 14:21

chislo_byte_array содержит 10 байт. Дальше выводите на, допустим, трехсегментный индикатор байты с 4-го по 6-й. Через секунду двигаете - с 5-го по 7-й и т.д. Встроенный (или написанный вами) знакогенератор отобразит на дисплее символ, соответствующий отправленному байту.

Кстати, int не имеет дробной части - это целые числа.
Мой волшебник это я сам. Всю архитектуру программы придумал лично, а ребята помогли воплотить её. Я бы и сам мог написать, но лень учить язык и его конструкции.
Аватара пользователя
dccharacter
 
Сообщения: 4995
Зарегистрирован: 10 дек 2010, 13:16
Откуда: Красногорск МО
прог. языки: C, Python, wiring/processing
ФИО: Андрей

Re: Семисегментный светодиодный индикатор

Сообщение Maxiik » 25 май 2011, 00:29

В общем разобрался я с алгоритмом, но как-то не до конца :)
В общем, для начала вопросик задам, чтобы не забыть, а потом исходник выложу, можно будет в блокноте открыть посмотреть...
Почему при попытке изменить тип переменной с int на long int и компиляции кода выдаётся ошибка ???
А вот если просто int, то всё нормально работает, но длинна обрабатываемого числа ограничена размером переменной, тобишь 32767 - это максимальное число...
Подскажите как увеличить обрабатываемое число ???
***
Индикатор планирую использовать, для начала, для температурного показателя :)
Вот исходник ...
Вложения
en.c
(6.19 КиБ) Скачиваний: 394
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

Re: Семисегментный светодиодный индикатор

Сообщение boez » 25 май 2011, 10:35

А слабо прочитать, какая именно ошибка выдается? :)
boez
 
Сообщения: 1981
Зарегистрирован: 27 авг 2008, 10:45
Откуда: Харьков
прог. языки: С/С++

Re: Семисегментный светодиодный индикатор

Сообщение Maxiik » 25 май 2011, 18:59

Сейчсас только заметил, что выдаётся ошибка если присвоить long int всем переменным кроме L. А если присвоить этот тип переменной L, то всё нормально компилируется... :oops:
Выдаётся такое сообщение:

Добавлено спустя 34 минуты 12 секунд:
Перевёл как: "Предел размера файла ознакомительной версии превышен" :x
Это что теперь значит, типа покупай лицензионную CVavr ????
Подскажите как быть ???
Может где взять нормальную CVavr ???

Добавлено спустя 47 секунд:
Кстати, а сколько лицензионка стоит ???
Вложения
пирк.JPG
пирк.JPG (8.26 КиБ) Просмотров: 8234
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

Re: Семисегментный светодиодный индикатор

Сообщение HarryStar » 25 май 2011, 22:28

Учитывая насколько у вас не оптимально написанная прога, ее можно сократить раза в 2 и по кол-ву строк в ней и по размеру кода. Тогда обойдетесь без лицензионной версии. Насчет остальных вопросов - используйте поиск в Яндексе/Гугле.
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Семисегментный светодиодный индикатор

Сообщение Maxiik » 26 май 2011, 01:08

А подскажите пожалуста как сделать её более оптимальной ???)
:friends:
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

Re: Семисегментный светодиодный индикатор

Сообщение HarryStar » 26 май 2011, 11:20

Maxiik писал(а):А подскажите пожалуста как сделать её более оптимальной

Изучайте Си и больше практикуйтесь и поменьше пользуйтесь готовыми решениями.

Ну вот набросал примерно.
Ваша занимает 688 байт, моя 426. Плюс выглядит лучше и удобней пользоваться.

Код: Выделить всёРазвернуть
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.7a Evaluation
Automatic Program Generator
© Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l.
http://www.hpinfotech.com

Project :
Version :
Date    : 23.05.2011
Author  : Freeware, for evaluation and non-commercial use only
Company :
Comments:


Chip type           : ATmega8
Program type        : Application
Clock frequency     : 8,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/

#include <mega8.h>
#include <delay.h>
#include <stdio.h>

unsigned char n7segment[10]={
         0b11000000,
         0b11110011,
         0b10001001,
         0b10100001,
         0b10110010,
         0b10100100,
         0b10000100,
         0b11110001,
         0b10000000,
         0b10100000
         };
   
// Функция выводы 1 цифры
void cifra (int r)
{
   PORTD = n7segment[r];
   delay_ms(5); 
}
// Функция вывода целого положительного числа от 0 до 999
void s7display(int n)
{
   PORTB = 0b00000100; cifra(n%10); n = n/10;
   PORTB = 0b00000010; cifra(n%10); n = n/10;
   PORTB = 0b00000001; cifra(n%10);
}
       
void main(void)
{
// Declare your local variables here

// Input/Output Ports initialization
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out
// State7=T State6=T State5=T State4=T State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x07;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0
PORTD=0x00;
DDRD=0xFF;

while(1) s7display(123);

}
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Семисегментный светодиодный индикатор

Сообщение Maxiik » 28 май 2011, 12:05

void cifra (int r)
{
PORTD = n7segment[r];
delay_ms(5);
}

void s7display(int n)
{
PORTB = 0b00000100; cifra(n%10);
PORTB = 0b00000010; cifra(n%100);
PORTB = 0b00000001; cifra(n%1000);
}


HarryStar, спасибо вам огромное за помощь !!!)
Вот выше я выделил наиболее интересный для меня фрагмент кода из той программы которую вы написали...
Я так понимаю, что под n подразумевается число которое нужно вывести на дисплей.
Но тогда,( если я не прав, то прошу меня поправить ), это справедливо только для трёхзначного числа, тобишь не больше трёх знаков...
Я вот думаю, может добавить в начале функцию преобразования числа, до нужного количества знаков ???
Проверить полученое число на условие длинны в три знака, и если это условие не соблюдается, то делить число на 10 пока оно не будет соблюдаться. Что скажете ? :oops:

Добавлено спустя 31 минуту 9 секунд:
А вот ещё проблемка, как выводить дробное число, тобишь десятичную точку ?)
Сейчас сижу думаю....
Например если число 0.5
Вообще я сейчас делаю термометр, но не решив проблему с индикатором (дисплеем), я не могу заняться изучением датчика DS18B20...
Аватара пользователя
Maxiik
 
Сообщения: 262
Зарегистрирован: 28 сен 2009, 21:54
Откуда: Петербург
прог. языки: С++
ФИО: Бирюк Максим Викторович

Re: Семисегментный светодиодный индикатор

Сообщение HarryStar » 28 май 2011, 12:27

В коде была ошибка, я ее давно поправил уже.
Теперь этот участок выглядит так
Код: Выделить всёРазвернуть
void cifra (int r)
{
   PORTD = n7segment[r];
   delay_ms(5); 
}
// Функция вывода целого положительного числа от 0 до 999
void s7display(int n)
{
   PORTB = 0b00000100; cifra(n%10); n = n/10;
   PORTB = 0b00000010; cifra(n%10); n = n/10;
   PORTB = 0b00000001; cifra(n%10);
}

Да, вы правы, это для трехзначного числа от 0 до 999.
Но мне кажется код легко поправить для любого числа. Я просто не знаю как у вас подсоединен индикатор, у меня его нет. Кроме того ваша программа делала тоже самое, как я понял.
Аватара пользователя
HarryStar
 
Сообщения: 995
Зарегистрирован: 15 ноя 2010, 13:56
Откуда: Нижний Новгород
прог. языки: С, С++, РНР

Re: Семисегментный светодиодный индикатор

Сообщение igel » 28 май 2011, 22:20

если заподозрить библиотечную команду itoa в полной проработанности и оптимизации, то вместо вывода (n%10), а потом еще n=n/10
можно попробовать
str = itoa(x) преобразование int в ascii строку
а уже потом for (i=0; length(str); i++) сегмент[i]=str[i];
скомпилированное должно занимать меньше места чем алгоритм выше
всегда так делаю

p.s. на e-neon.ru в разделе драйверы светодиодов есть мироксхемы с последовательным входом для управления 7-сегм индикаторами, то есть понадобится только 1 нога проца чтобы управлять динамически несколькими индикаторами
igel
 
Сообщения: 63
Зарегистрирован: 07 апр 2011, 20:52
Откуда: г.Трёхгорный

След.

Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 11