Страница 1 из 1
отрицательное число на 7-сегментный индикатор
Добавлено: Чт ноя 12, 2009 15:18:56
sanic
не знаю как вывести знак минус на 7-сегментник . микроконтроллер Atmega8, 7-сегментник 3-х разрядный. Помогите с кодом на С++.
Добавлено: Чт ноя 12, 2009 16:33:35
sachok
Вау С++ для МК это круто.

Для вивода информации на индиктор я делаю массив со всеми мне нужними знаками. потом в порт отправляэтся нужный елемент массива
Код: Выделить всё
flash char digits[] = //маcсив з цифрами
{
0b00000011, //0
0b10011111, //1
0b00100101, //2
0b00001101, //3
0b10011001, //4
0b01001001, //5
0b01000001, //6
0b00011111, //7
0b00000001, //8
0b00001001, //9
0b11111101, //знак "-"
0b11111111 //пусто
};
Было бы не плохо написать что конкретно нужно селать.
Добавлено: Пт ноя 13, 2009 11:08:32
sanic
Хочу сделать термометр на термисторе NTC 10 kOm, для начала разобраться с выводом отрицательного числа.
flash char digits[] = { // массив для отображения на индикаторе
0b11000000, //0
0b11111001, //1
0b10100100, //2
0b10110000, //3
0b10011001, //4
0b10010010, //5
0b10000010, //6
0b11111000, //7
0b10000000, //8
0b10010000, //9
0b10111111, // знак'-'
0b11111111 // пусто
};
char digit_out[2], cur_dig ,a ; //переменные для работы с LED
unsigned long int i; //переменная для вывода
void rec(void) // функция для перекодировки
{
digit_out[0]=i%10; // Делим на 10 остаток в маcсив, 1-разряд (справа налево)
i=i/10;
digit_out[1]=i%10; // 2 разряд (если не ошибаюсь?)
i=i/10;
}
как вывести знак‘-‘ какой нужен код не знаю.
Пример: вывод числа 55 на 2-х разрядный 7-сегментник. 55%10 остаток 5 в массив, 1-разряд. 55/10=5 2-разряд. А как быть с -55?
[/code]
Добавлено: Пт ноя 13, 2009 11:55:51
Danko
Если речь идет от отрицательных числах:
во первых:
unsigned long int i; //переменная для вывода знаковая переменная, а не без знаковая.
во вторых: нужно почитать про отрицательные числа в двоичной системе исчисления.
Последнее:
должно быть что то подобное:
Код: Выделить всё
void rec(void) // функция для перекодировки
{
if (i < 0) {
digit_out[2]=10; // знак минус
i = ( ~i ) + 1; // если число отрицательное перевести его в норм.вид
}
digit_out[0]=i%10; // Делим на 10 остаток в маcсив, 1-разряд (справа налево)
i=i/10;
digit_out[1]=i%10; // 2 разряд
}
Добавлено: Вс ноя 15, 2009 23:52:10
Volly
i = ( ~i ) + 1; // если число отрицательное перевести его в норм.вид
Или

Добавлено: Пн ноя 16, 2009 02:03:53
kalobyte
ацп не оперирует отрицательными числами
автор, при отрицательных числах у тебя с ацп будет приходить какое-то значение, которое ты заранее должен измерить в виде напряжения или вывести его на индикатор в виде числа от 0 до 1023
хотя для точности можеш выкинуть 2 младших бита
вобщем суеш резистор в тающий лед и смотриш на индикатор
это число и будет 0 градусов
далее делаеш так
if(adc<t_null) ...;
в функции отображения надо первый разряд не включать полностью, а использовать только один сегмент, который заведен на 8й бит, который обычно делается точкой
там у тебя в функции преобразования числа в цифры надо будет сделать tmp|=1<<7 для первого разряда цифр
проще говоря выставить 8й бит в 1 и завести 8й пин на средний горизонтальный сегмент 4го индикатора
таким макаром тебе плату проще развести и не надо тратить еще один вывод для общего провода индикатора
у меня есть подобная плата на 1999 с управлением через регистры
там вот 1 как раз работает как твой минус
Добавлено: Пн ноя 16, 2009 10:59:19
ARV
Danko писал(а):Если речь идет от отрицательных числах:
во первых: unsigned long int i; //переменная для вывода знаковая переменная, а не без знаковая.
это с каких-таких пор
unsigned стало обозначать
ЗНАКОВАЯ ?!
прочтите
здесь и закройте для себя раз и на всегда тему с преобразованием чисел в семисегментыне символы.
Добавлено: Пн ноя 16, 2009 11:54:04
Danko
ARV писал(а):Danko писал(а):Если речь идет от отрицательных числах:
во первых: unsigned long int i; //переменная для вывода знаковая переменная, а не без знаковая.
это с каких-таких пор
unsigned стало обозначать
ЗНАКОВАЯ ?!
прочтите
здесь и закройте для себя раз и на всегда тему с преобразованием чисел в семисегментыне символы.
Большое
СПАСИБО от неуча за обучение !!!
Во первых то, что черным это цитата из поста, а во вторых автор поста пытался вывести на индикатор отрицательное число при этом объявил переменную как беззнаковое на что я акцентировал внимание.
Добавлено: Пн ноя 16, 2009 12:38:37
ARV
Danko писал(а):Большое СПАСИБО от неуча за обучение !!!
Во первых то, что черным это цитата из поста, а во вторых автор поста пытался вывести на индикатор отрицательное число при этом объявил переменную как беззнаковое на что я акцентировал внимание.
пожалуйста. прослушайте краткую лекцию о том, что свои мысли надо выражать адекватно: если бы у вас было написано "эта переменная
ДОЛЖНА быть знаковая, а не беззнаковая" - смысл ваших намеков был бы понятен даже такому олуху, как я. но вы написали явно утвердительное предложение, констатирующее, что это есть
знаковая переменная, а ваши тайные мысли остались для телепатов, к которым я не отношусь.
я когда-то уже говорил: взялся давать рекомендации начинающим - делай это так, чтобы в твоих словах не было неоднозначности, ибо если что-то можно понять неправильно, то оно и будет понято неправильно.
Добавлено: Пн ноя 16, 2009 14:48:20
Danko
Еще раз спасибо, в дальнейшем буду более точен в рекомендациях.
Но почему у sanic, после моей рекомендации вопросов не возникло?
И мне без разницы телепат Вы AVR или нет. Если бы я тыкал каждого носом за неточности то...
Добавлено: Пн ноя 16, 2009 17:09:17
ARV
Danko писал(а):Но почему у sanic, после моей рекомендации вопросов не возникло?
причин может быть 2: либо ему по барабану вся наша/ваша писанина, либо он так и не понял, что вы сказали или что он сделал не так.
Добавлено: Вт ноя 17, 2009 07:13:28
sanic
Ничего мне не по барабану. Вопросы у меня есть. Спасибо всем за помощь Sashку за массив, Danko за переменную: вместо unsigned long int i; надо signed long int i; . Volly за код i *= -1. kalobyte за АЦП. И ARV за статью. Вот что у меня получилось.
Не знаю, правильно ли я сделал? Но минус выводится.
---------------
char digit_out[2], cur_dig ,a ; //переменные для работы с LED
signed long int i; //переменная для вывода
void rec(void) // функция для перекодировки
{ if (i < 0) {
i*=-1; // само число берем по модулю
digit_out[0]=i%10; // Делим на 10 остаток в масcив, 1-разряд (справа налево)
i=i/10;
digit_out[1]=i%10; // 2 разряд
i=i/10;
digit_out[2]=10; // знак минус. Warnings: L79: array index is out of range. Почему??? Что не так сделал?
}
else{digit_out[0]=i%10; // Делим на 10 остаток в масcив, 1-разряд (справа налево)
i=i/10;
digit_out[1]=i%10; // 2 разряд
i=i/10; }
}
--------------------
При
while (1)
{
// Place your code here
i= -99;
rec();
В протеусе получилось -99
Взял формулу из книги «Программирование на языке С для AVR и PIC» автор Ю. А. Шпак
У меня NTC 10 кОм. -25 =0x00. 125=1023. отсюда формула t=150*ADCW/1023-25. Почему то так не получается. При 0 градусов в протеусе напряжение на АЦП=0,63в, а это ADCW=0,63*1024/5=129, t=150*129/1023-25= -6.08 не сходится. Это что надо подбирать делитель??? Я сделал так t=150*129/1023-18.9=0.
Проблема теперь в точности измерения температуры. У термистора NTC получается нелинейная зависимость.
Подскажите пожалуйста формулу, или другой способ расчета.
Добавлено: Вт ноя 17, 2009 09:24:01
GP1
самый простой способ борьбы с нелинейностью датчика - это табличный метод.
вычисление по формуле - это сложная формула (для расчета на мк), проще поставить датчик с линейной зависимостью.
Добавлено: Вт ноя 17, 2009 11:25:41
sanic
Что это за табличный метод и как его реализовать на Си?
Добавлено: Вт ноя 17, 2009 13:27:45
ARV
sanic писал(а): digit_out[2]=10; // знак минус. Warnings: L79: array index is out of range. Почему??? Что не так сделал?
у вас массив определен как
char digit_out[2], т.е. содержит 2 элемента -
нулевой и
первый, а вы обращаетесь ко
второму, т.е. по Си-шным правилам -
третьему 
вот и
Warning вам за это - индекс массива вне диапазона
Добавлено: Вт ноя 17, 2009 14:34:53
kalobyte
купи дс18с20 и не парься с терморезистором
или хотя бы бери полупроводниковый kty с нормальной линейностью
Добавлено: Вт ноя 17, 2009 15:32:04
pyzhman
Не копируйте механически формулу. Для вас она будет другая. 1.Нужно определиться с сопротивлением в нижнем плече делителя. 2.Какие напряжения будут на входе АЦП в зависимомти от температуры? У вас же другой терморезистор нежели в вырезке статьи. 3.И точьность по этой формуле будет хромать изначально, т.к. формула - линейная.
А посему! Берем даташит и смотрим по температурно-сопротивленческой характеристике данные. Либо меряем вручную. Составляем таблицу(массив) где каждому элементу соответствует значение температуры. Alles!
Добавлено: Вт ноя 17, 2009 16:23:08
sanic
Если можно по подробнее, как составить таблицу (массив)?

Добавлено: Вт ноя 17, 2009 16:48:42
pyzhman
Имеем 10-разрядный АЦП. Его данные надо укоротить до восьми разрядов, т.к. два младшие бита "гуляют"(согласно даташиту). Итого 256 значений. Температуры. берем контрольные точки 0 и 100 градусов, или по эталонному градуснику. Задаем массив на 256 элементов. Заполняем его по измерениям температуры. Т.е. элементу 0 соответствует значение -25, элементу 1 значение -24.....элементу 100 значение 7 и т.д. Это для примера, у вас будет свое. После этот массив лучше прописать во флэш. А далее использовать на свое усмотрение. Примерно так.
Добавлено: Ср ноя 18, 2009 08:29:34
BCluster
Кстати зря вы про С++ и контроллеры. Посмотрите на IAR, там можно писать на С++, Интересно использовать его иногда.