Перейти к содержанию
    

индикация

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

Все писалось на кодевижионе.

 

#include "Mega16.h"

#define WGM01 3

#define CS00 0

#define CS01 1

#define OCIE0 1

 

short int i = 1;

char sec,min,hour; //переменные для времени

unsigned char j, k = 0;

//long int counter = 0; //счетчик временных интервалов

long int tick = 0; //счетчик часов

unsigned char Dig[10],Bufer[4]; // Массив, в котором хранятся числа, которые нужно

// вывести через порт на индикатор, чтобы он показал цифру, равную номеру

// элемента массива. Числа зависят только от макросов.

void io_init()

{

DDRD = 0xFF; // К порту D подключен индикатор

PORTD = 0xFF;

DDRC |= (1 << 4) | (1 << 5) | (1 << 6) |(1 << 7);//к порту С подключены аноды индикаторов

PORTC = 0xF0;

Bufer[1]=Bufer[2]=Bufer[3]=Bufer[4]=0;

}

void timer0_init()

{

#asm("sei");

OCR0 = 124; // Таймер срабатывает каждые 64 такта. Прерывание каждые 125*16 тактов.

TCCR0 |= (1 << WGM01) | (1 << CS00) | (1 << CS01); //

TIMSK |= (1 << OCIE0);

}

void clock()

{

if (tick>999)

{

tick=0;

sec++;

}

if (sec>59)

{

sec=0;

min++;

}

if (min>59)

{

min=0;

hour++;

}

if (hour>23)

{

hour=0;

}

}

void Dig_init()

{

Dig[0] = 0x3F;

Dig[1] = 0x06;

Dig[2] = 0x5B;

Dig[3] = 0x4F;

Dig[4] = 0x66;

Dig[5] = 0x6D;

Dig[6] = 0x7D;

Dig[7] = 0x07;

Dig[8] = 0x7F;

Dig[9] = 0x6F;

}

void convert()

{

Bufer[1]=Dig[sec%10];

Bufer[2]=Dig[sec/10];

Bufer[3]=Dig[hour%10];

Bufer[4]=Dig[hour/10];

}

void display()

{

for (k=0; k<=20;k++)

{

PORTC=0;

PORTC=(0<<7);

PORTD=Bufer[1];

}

for (k=0; k<=20;k++)

{

PORTC=0;

PORTC=(0<<6);

PORTD=Bufer[2];

}

 

 

}

 

void main()

{

io_init();

timer0_init();

Dig_init();

while(1)

{clock();

convert();

display();

}

}

interrupt [TIM0_COMP] void inc_delay_counter()

{

tick++;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Вы бы для начала в паре слов описали, что у вас получилось на дисплее с этой программой.

После беглого просмотра программы:

void display() написана не правильно.

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

 

з.ы. Таблицу констант можно хранить в памяти программ:

const unsigned char Dig[10] = {0x3F;0x06;0x5B;0x4F;0x66;0x6D;0x7D;0x07;0x7F;0x6F;}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы бы для начала в паре слов описали, что у вас получилось на дисплее с этой программой.

После беглого просмотра программы:

void display() написана не правильно.

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

 

з.ы. Таблицу констант можно хранить в памяти программ:

const unsigned char Dig[10] = {0x3F;0x06;0x5B;0x4F;0x66;0x6D;0x7D;0x07;0x7F;0x6F;}

да блин я сам типо понимаю тока вот занимаюсь авр наверное неделю вторуюю и вот ваши замечания не смогли мне помочь в индикации, а на индикаторе херня типо могет быть и 6 и 8 и от времени ни как не зависит, не могли бы помочь с примером более менее развернутым типо пояснения и б уже подогнал к себе

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для динамической индикации общий рефреш дисплея можно сделать 50-100 Гц. То есть 50 Гц = 20 мс/дисплей. 5 мс на одно знакоместо. Вот и организуйте рефреш прямо в прерывании TIM0_COMP.

Как я понял, оно у вас должно вызываться раз в 1 мс. Примерно типа-опа так (то, чего здесь нет, у вас правильно):

 

unsigned char MilliSecCnt;
unsigned char SegmentNum;
const unsigned char AnodeCod[4]={0x70,0xB0,0xD0,0xE0};

interrupt [TIM0_COMP] void inc_delay_counter() // 1 ms past
  {
  tick++;
  if (++MilliSecCnt >= 5)   // 5 ms past
    {
    MilliSecCnt = 0;
    PORTC = 0xF0;                   // All segments off
    PORTD = Bufer[SegmentNum];      // Write next digit
    PORTC = AnodeCod[SegmentNum];   // Next segment on
    SegmentNum = (SegmentNum + 1) & 0x03;
    }
  }

void clock(void)
  {
  if (tick >= 1000)
    {
    tick=0; sec++;
    if (sec >= 60) { sec=0;  min++;  }
    if (min >= 60) { min=0;  hour++; }
    if (hour >= 24)  hour=0;
    Bufer[1]=Dig[sec%10];
    Bufer[2]=Dig[sec/10];
    Bufer[3]=Dig[hour%10];
    Bufer[4]=Dig[hour/10];
    }
  }

void main(void)
  {
  io_init();
  timer0_init();
  while(1)
    {
    clock();
    }
  }

Еще уточнения. О чем вы умолчали, но мне так кажется. У вас индикаторы с общим анодом, подключенные через PNP ключи, т.е. всё включается нулем. Знакогенератор при этом нужен инверсный вашему:

const unsigned char Dig[10] = {~0x3F;~0x06;~0x5B;~0x4F;~0x66;~0x6D;~0x7D;~0x07;~0x7F;~0x6F;}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще уточнения. О чем вы умолчали, но мне так кажется. У вас индикаторы с общим анодом, подключенные через PNP ключи, т.е. всё включается нулем. Знакогенератор при этом нужен инверсный вашему:

const unsigned char Dig[10] = {~0x3F;~0x06;~0x5B;~0x4F;~0x66;~0x6D;~0x7D;~0x07;~0x7F;~0x6F;}

сенкс пойду проверять.

 

Еще уточнения. О чем вы умолчали, но мне так кажется. У вас индикаторы с общим анодом, подключенные через PNP ключи, т.е. всё включается нулем. Знакогенератор при этом нужен инверсный вашему:

const unsigned char Dig[10] = {~0x3F;~0x06;~0x5B;~0x4F;~0x66;~0x6D;~0x7D;~0x07;~0x7F;~0x6F;}

 

сенкс пойду проверять.

хм что-то не пляшет в общем знакогенератор нужен как я и написал тоесть прямой, когда ввел ваш текст и просимулировал в протеусе то вижу только три первых разряда(ну это может быть глюк симуляции) в живую еще не прошивал, обьясните мне что делает вот эта строка из вашего листинга SegmentNum = (SegmentNum + 1) & 0x03; что дает &0x03? обьясните новичку плз. и в дальнейшем я хочу из этого сделать блок управления аквариумом могу ли я у вас дальше это все спрашивать?!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

сенкс пойду проверять.
Ну, так вы так и не написали, как у вас подключены индикаторы и какого они типа :07:

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

 

обьясните мне что делает вот эта строка из вашего листинга SegmentNum = (SegmentNum + 1) & 0x03; что дает &0x03?
Это просто счетчик от 0 до 3. Если вам такая запись непонятна, можно написать по-другому:

SegmentNum++;
if (SegmentNum >= 4) SegmentNum = 0;

 

могу ли я у вас дальше это все спрашивать?!
Спрашивайте, конечно, кто-нибудь да ответит. Только не утаивайте технические подробности, необходимые для ответа.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну, так вы так и не написали, как у вас подключены индикаторы и какого они типа :07:

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

 

Это просто счетчик от 0 до 3. Если вам такая запись непонятна, можно написать по-другому:

SegmentNum++;
if (SegmentNum >= 4) SegmentNum = 0;

 

Спрашивайте, конечно, кто-нибудь да ответит. Только не утаивайте технические подробности, необходимые для ответа.

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

общие аноды подключены на pin7-4анод pin6-3анод,pin5-2анод,pin4-1анод.(4анод отвеч за единицы секунд, 3 анод за десятки сек) в чем гемор?

interrupt [TIM0_COMP] void inc_delay_counter()

{

tick++;

if (++MilliSecCnt >= 5) // 5 ms past

{

MilliSecCnt = 0;

PORTC = 0xF0; // All segments off

SegmentNum = (SegmentNum + 1)&0x03;

PORTD = Bufer[segmentNum]; // Write next digit

PORTC = AnodeCod[segmentNum]; // Next segment on

 

}

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

общие аноды подключены на pin7-4анод pin6-3анод,pin5-2анод,pin4-1анод.(4анод отвеч за единицы секунд, 3 анод за десятки сек) в чем гемор?
Вы были бы хорошим партизаном :wacko:

Информацию из вас не вытянешь в нужном объеме: вы можете, наконец, ответить подробно, как у вас подключены индикаторы? Ваши данные противоречивы. У вас есть транзисторы на каждую цифру? Еще, если дисплеи с общим анодом, то таблица знакогенератора не может быть такой как у вас.

 

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

Bufer[0]=Dig[sec%10];
Bufer[1]=Dig[sec/10];
Bufer[2]=Dig[hour%10];
Bufer[3]=Dig[hour/10];

 

Прерывание вы зря поменяли, так будет меньше время свечения и соотв.яркость. Лучше даже так:

interrupt [TIM0_COMP] void inc_delay_counter()
{
tick++;
if (++MilliSecCnt >= 5)   // 5 ms past
    {
    unsigned char dignum = SegmentNum;

    MilliSecCnt = 0;
    PORTC = 0xF0;               // All segments off
    PORTD = Bufer[dignum];      // Write next digit
    PORTC = AnodeCod[dignum];   // Next segment on
    SegmentNum = (dignum + 1)&0x03;
    }
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы были бы хорошим партизаном :wacko:

Информацию из вас не вытянешь в нужном объеме: вы можете, наконец, ответить подробно, как у вас подключены индикаторы? Ваши данные противоречивы. У вас есть транзисторы на каждую цифру? Еще, если дисплеи с общим анодом, то таблица знакогенератора не может быть такой как у вас.

 

Измените набивку буфера, там ошибка. Разве компилятор на это не ругался?

Bufer[0]=Dig[sec%10];
Bufer[1]=Dig[sec/10];
Bufer[2]=Dig[hour%10];
Bufer[3]=Dig[hour/10];

 

Прерывание вы зря поменяли, так будет меньше время свечения и соотв.яркость. Лучше даже так:

interrupt [TIM0_COMP] void inc_delay_counter()
{
tick++;
if (++MilliSecCnt >= 5)   // 5 ms past
    {
    unsigned char dignum = SegmentNum;

    MilliSecCnt = 0;
    PORTC = 0xF0;               // All segments off
    PORTD = Bufer[dignum];      // Write next digit
    PORTC = AnodeCod[dignum];   // Next segment on
    SegmentNum = (dignum + 1)&0x03;
    }
}

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

 

все получилось гуд с вашей помошью, пошел разбираться с дс18б20 подскажите его обработку тоже лучше сделать в прерываниии или в теле майин, и след вопрос обработку кнопок как сделать в теле майн или в прерывании? полный ответ с примером не давайте хочется самому попариться, если не получиться тогда буду спрашивать(хочется изучить а не как мартышка по примерам шпарить?!) Заранее благодарю.у мя нет транзисторов на прямую к выходам (пока не сгорели) но как доберусь то обязаловка куплю транзисторы (суть такова что если на общий индикатора подаю - то цифры видны) извините не та спецуха по образованию инж. зоотехник к сожалению, а не электронщик или что еще, все это получено путем чтения книг и тока не давно буквально месяца два как есть нет , знаю англ язык сносно(могу общаться с иностранцами к нам приезжали и я с ними вел беседу) так что строго в знании программирования строго не судите.

Изменено пользователем Andrew82

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я думаю с точки зрения языка написал то я правильно вот компил и не ругался.
При объявлении: unsigned char Bufer[4]; на строчку Bufer[4]=Dig[hour/10]; компилятор обязан был ругаться, поскольку такого элемента нет.

 

пошел разбираться с дс18б20 подскажите его обработку тоже лучше сделать в прерываниии или в теле майин, и след вопрос обработку кнопок как сделать в теле майн или в прерывании?
И обработку кнопок и работу с 1-wire нужно делать в основном цикле (main).

Рекомендации, как это все можно глобально организовать, я давал тут, посмотрите.

 

у мя нет транзисторов на прямую к выходам (пока не сгорели) но как доберусь то обязаловка куплю транзисторы (суть такова что если на общий индикатора подаю - то цифры видны)
Ясно, у вас индикаторы с общим катодом. А транзисторы обязательно поставьте. Даже если порты не сгорят, то нормальной яркости не получите. При динамической индик. токи через сегменты должны быть в (кол-во цифр) больше. То есть, если норм. ток 10-15 мА, то динамический должен быть (10-15)*4=40-60 мА.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...