Jump to content

    
Sign in to follow this  
Andrew82

индикация

Recommended Posts

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

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

 

#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++;

}

Share this post


Link to post
Share on other sites
вот тут написал прогу и не могу допеткрить как выводить все символы на семисегментный индикатор.подскажите кто

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

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

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

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

 

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

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

Share this post


Link to post
Share on other sites
Вы бы для начала в паре слов описали, что у вас получилось на дисплее с этой программой.

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

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

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

 

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

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

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

Share this post


Link to post
Share on other sites

Для динамической индикации общий рефреш дисплея можно сделать 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;}

Share this post


Link to post
Share on other sites

Еще уточнения. О чем вы умолчали, но мне так кажется. У вас индикаторы с общим анодом, подключенные через 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? обьясните новичку плз. и в дальнейшем я хочу из этого сделать блок управления аквариумом могу ли я у вас дальше это все спрашивать?!

Share this post


Link to post
Share on other sites
сенкс пойду проверять.
Ну, так вы так и не написали, как у вас подключены индикаторы и какого они типа :07:

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

 

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

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

 

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

Share this post


Link to post
Share on other sites
Ну, так вы так и не написали, как у вас подключены индикаторы и какого они типа :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

 

}

}

Share this post


Link to post
Share on other sites
общие аноды подключены на 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;
    }
}

Share this post


Link to post
Share on other sites
Вы были бы хорошим партизаном :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 подскажите его обработку тоже лучше сделать в прерываниии или в теле майин, и след вопрос обработку кнопок как сделать в теле майн или в прерывании? полный ответ с примером не давайте хочется самому попариться, если не получиться тогда буду спрашивать(хочется изучить а не как мартышка по примерам шпарить?!) Заранее благодарю.у мя нет транзисторов на прямую к выходам (пока не сгорели) но как доберусь то обязаловка куплю транзисторы (суть такова что если на общий индикатора подаю - то цифры видны) извините не та спецуха по образованию инж. зоотехник к сожалению, а не электронщик или что еще, все это получено путем чтения книг и тока не давно буквально месяца два как есть нет , знаю англ язык сносно(могу общаться с иностранцами к нам приезжали и я с ними вел беседу) так что строго в знании программирования строго не судите.

Edited by Andrew82

Share this post


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

 

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

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

 

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this