Страница 1 из 2

Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 07:46:54
Gin87
Всем привет!

Потребовалась динамическая индикация на разных портах одновременно. Написал код, но цифры сливаются. Вывожу 123, так вот первый разряд 1 светит ярко,но на нем же проступает 2 и 3 тусклее.
Помогите советом. Камень Мега 8, среда Avr Studio 4.

Код: Выделить всё


//#define F_CPU 8000000UL		// Тактовая частота микроконтроллера 8 МГц

// Подключаю стандартные библиотеки
#include <avr/io.h>			// Ножки ввода-вывода
#include <util/delay.h>		// Задержки
#include <avr/interrupt.h>	// Прерывания

volatile unsigned int segcounter = 0;


//создаем глобальные переменные для хранения разрядов выводимого числа
volatile char R1=0;
volatile char R2=0;
volatile char R3=0;

//======динамическая индикация============

void segment (char N)
{
switch (N)
{
case 0:
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<0)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 0
case 1:
 PORTD|=(1<<5);
 PORTB|=(1<<4);   
 break; // число 1
case 2: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<1)|(1<<2)|(1<<3);  
 break; // число 2
case 3: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<1)|(1<<3)|(1<<4);  
 break; // число 3
case 4: 
 PORTD|=(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<4); 
 break; // число 4
case 5: 
 PORTD|=(1<<6);
 PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4);  
 break; // число 5
case 6: 
 PORTD|=(1<<6)|(1<<7);
 PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 6
case 7: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<4);   
 break; // число 7
case 8: 
 PORTD|=(1<<6)|(1<<7)|(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 8
case 9: 
 PORTD|=(1<<6)|(1<<7)|(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); 
 break; // число 9
case 10: 
 PORTB|=(1<<1); 
 break; // знак минус
case 11: 
 PORTD|=(1<<6)|(1<<5); 
 PORTB|=(1<<0)|(1<<1);  
 break; // знак градуса
}
}
 

void print_led (int chislo)
{
R1=chislo%10;  // 1ый разряд 
R2=(chislo%100)/10; // 2ой разряд
R3=(chislo%1000)/100; // 3ий разряд
}


//======динамическая индикация конец======
	


// Прерывание по переполнению T2, динамическая индикация
ISR (TIMER2_OVF_vect)
{
 
PORTC &=~((1<<2)|(1<<4)|(1<<5));//гасим все разряды
PORTB &=~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)); // Гасим все сегменты
PORTD &=~((1<<5)|(1<<6)|(1<<7)); // Гасим все сегменты	


if(segcounter==0) PORTC|=(1<<5);
if(segcounter==1) PORTC|=(1<<2);
if(segcounter==2) PORTC|=(1<<4);

switch (segcounter)
 {	
  case 0: segment(R1); break;  // Выводим первый разряд
  case 1: segment(R2); break;  // Выводим второй разряд
  case 2: segment(R3); break;  // Выводим третий разряд 
 }


segcounter++;

if(segcounter>2) segcounter=0;

}

// Главная программа
int main (void)            
{

DDRB=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4);
DDRD=(1<<5)|(1<<6)|(1<<7);
DDRC=(1<<2)|(1<<4)|(1<<5);


// Настройка Таймера 2
TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру2
TCCR2 |= (1 << CS22)|(1 << CS20);  // Предделитель на 128



asm volatile ("sei");					// Глобально разрешаю прерывания

while(1)
{
                              



R1=1;
R2=1;
R3=1;


}

}




Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 08:28:28
ARV
реализация ужасна.
ознакомьтесь хотя бы бегло с принципами генерации символов...

что касается паразитной засветки, то:
1. гашение индикатора осуществляется ТОЛЬКО подачей нужного уровня на ОБЩИЕ КАТОДЫ или АНОДЫ, сегменты трогать не надо. гасите сразу все общие линии одновременно, если линии на разных портах - последовательно, но обязательно все.
2. после гашения выводите новое состояние сегментов.
3. потом включаете НУЖНЫЙ ОБЩИЙ КАТОД/АНОД - только один.

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

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 08:36:52
Gin87
1) Совет не помог. Все равно все три цифры горят одновременно.

2) Уважаемый, ARV, подскажите, пжлст, как ПРАВИЛЬНО генерить цифры? При условии, что нужно зажигать/тушить ОТДЕЛЬНЫЕ биты РАЗНЫХ портов.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 09:51:26
metan

Код: Выделить всё

if(segcounter==0) PORTC|=(1<<5);
if(segcounter==1) PORTC|=(1<<2);
if(segcounter==2) PORTC|=(1<<4);

switch (segcounter)
 {   
  case 0: segment(R1); break;  // Выводим первый разряд
  case 1: segment(R2); break;  // Выводим второй разряд
  case 2: segment(R3); break;  // Выводим третий разряд 
 }
заменить на

Код: Выделить всё

switch (segcounter)
 {   
  case 0: {
                segment(R1); PORTC|=(1<<5); break;  // Выводим первый разряд
           }
  case 1: {
                segment(R2); PORTC|=(1<<2); break;  // Выводим второй разряд
           }
  case 2: {
               segment(R3); PORTC|=(1<<4); break;  // Выводим третий разряд 
           }
 }

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 10:57:09
Gin87
Спасибо, получился такой код:

Код: Выделить всё

//#define F_CPU 8000000UL		// Тактовая частота микроконтроллера 8 МГц

// Подключаю стандартные библиотеки
#include <avr/io.h>			// Ножки ввода-вывода
#include <util/delay.h>		// Задержки
#include <avr/interrupt.h>	// Прерывания

volatile unsigned int segcounter = 0;


//создаем глобальные переменные для хранения разрядов выводимого числа
volatile char R1=0;
volatile char R2=0;
volatile char R3=0;

//======динамическая индикация============

void segment (char N)
{
switch (N)
{
case 0:
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<0)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 0
case 1:
 PORTD|=(1<<5);
 PORTB|=(1<<4);   
 break; // число 1
case 2: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<1)|(1<<2)|(1<<3);  
 break; // число 2
case 3: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<1)|(1<<3)|(1<<4);  
 break; // число 3
case 4: 
 PORTD|=(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<4); 
 break; // число 4
case 5: 
 PORTD|=(1<<6);
 PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4);  
 break; // число 5
case 6: 
 PORTD|=(1<<6)|(1<<7);
 PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 6
case 7: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<4);   
 break; // число 7
case 8: 
 PORTD|=(1<<6)|(1<<7)|(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 8
case 9: 
 PORTD|=(1<<6)|(1<<7)|(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); 
 break; // число 9
case 10: 
 PORTB|=(1<<1); 
 break; // знак минус
case 11: 
 PORTD|=(1<<6)|(1<<5); 
 PORTB|=(1<<0)|(1<<1);  
 break; // знак градуса
}
}
 

 
//Эта функция принимает как аргумент число которое необходимо вывести. Эта функция меняет глобальные переменные разрядов чисел в соответствии с аргументом функции
void print_led (int chislo)
{
R1=chislo%10;  // 1ый разряд 
R2=(chislo%100)/10; // 2ой разряд
R3=(chislo%1000)/100; // 3ий разряд
}


//======динамическая индикация конец======
	


// Прерывание по переполнению T2, динамическая индикация
ISR (TIMER2_OVF_vect)
{
 
PORTC &=~((1<<2)|(1<<4)|(1<<5));//гасим все разряды
PORTB &=~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)); // Гасим все сегменты
PORTD &=~((1<<5)|(1<<6)|(1<<7)); // Гасим все сегменты	


switch (segcounter)
 {   
  case 0: {
                segment(R1); PORTC|=(1<<5); break;  // Выводим первый разряд
           }
  case 1: {
                segment(R2); PORTC|=(1<<2); break;  // Выводим второй разряд
           }
  case 2: {
               segment(R3); PORTC|=(1<<4); break;  // Выводим третий разряд 
           }
 }

segcounter++;

if(segcounter>2) segcounter=0;

}

// Главная программа
int main (void)            
{

DDRB=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4);
DDRD=(1<<5)|(1<<6)|(1<<7);
DDRC=(1<<2)|(1<<4)|(1<<5);


// Настройка Таймера 0
TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру2
TCCR2 |= (1 << CS22)|(1 << CS20);  // Предделитель на 128



asm volatile ("sei");					// Глобально разрешаю прерывания

while(1)
{
                              



R1=1;
R2=2;
R3=3;


}

}


Но не сработало. Как бы работает но идет сильная засветка неиспользуемых сегментов.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 11:16:48
oleg110592

Код: Выделить всё

case 8: 
 PORTD|=(1<<6)|(1<<7)|(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); 
??? Почему для цифры 8 восемь пинов устанавливаются.
Достаточно "зажечь" сегменты A B C D E F G (7 вроде).

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 12:08:35
Gin87
oleg110592 писал(а):

Код: Выделить всё

case 8: 
 PORTD|=(1<<6)|(1<<7)|(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); 
??? Почему для цифры 8 восемь пинов устанавливаются.
Достаточно "зажечь" сегменты A B C D E F G (7 вроде).
Согласен, тут косяк. Точка лишняя. Пофиксил.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 12:38:39
Gin87
Исключил таймер для фикса бага. Получился такой код:

Код: Выделить всё


while(1)
{
                              

                
			
				segment(R1); 
		        PORTC|=(1<<5); 
                _delay_ms(200);

				PORTC &=~(1<<5);//гасим все разряды
                segment(12);  //потушить все сегменты

				 
				segment(R2); 
				PORTC|=(1<<2); 
                _delay_ms(200);

				PORTC &=~(1<<2);//гасим все разряды
                segment(12); //потушить все сегменты


           
                segment(R3);
				PORTC|=(1<<4); 
                _delay_ms(200);

				PORTC &=~(1<<4);//гасим все разряды
                segment(12); //потушить все сегменты


R1=1;
R2=2;
R3=3;
Сейчас более наглядно как цифры переключаются. Но все равно сразу по 3. Нет момента когда цифра выключена. По три разряда горит. Такое чувство, что внутри контроллера через диод подтекает что ли.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 12:53:54
oleg110592
в протезе все в порядке:
Изображение
Спойлер

Код: Выделить всё

#include <avr/io.h>         // Ножки ввода-вывода
#include <util/delay.h>      // Задержки
#include <avr/interrupt.h>   // Прерывания

volatile unsigned int segcounter = 0;

//создаем глобальные переменные для хранения разрядов выводимого числа
volatile char R1 = 0;
volatile char R2 = 0;
volatile char R3 = 0;

//======динамическая индикация============
void segment (char N)
{
    // A PD6
    // B PD5
    // C PB4
    // D PB3
    // E PB2
    // F PB0
    // G PB1
    // H
    switch (N)
    {
    case 0:
        PORTD |= (1 << 5) | (1 << 6);
        PORTB |= (1 << 0) | (1 << 2) | (1 << 3) | (1 << 4);
        break; // число 0
    case 1:
        PORTD |= (1 << 5);
        PORTB |= (1 << 4);
        break; // число 1
    case 2:
        PORTD |= (1 << 5) | (1 << 6);
        PORTB |= (1 << 1) | (1 << 2) | (1 << 3);
        break; // число 2
    case 3:
        PORTD |= (1 << 5) | (1 << 6);
        PORTB |= (1 << 1) | (1 << 3) | (1 << 4);
        break; // число 3
    case 4:
        PORTD |= (1 << 5);
        PORTB |= (1 << 0) | (1 << 1) | (1 << 4);
        break; // число 4
    case 5:
        PORTD |= (1 << 6);
        PORTB |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4);
        break; // число 5
    case 6:
        PORTD |= (1 << 6);
        PORTB |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);
        break; // число 6
    case 7:
        PORTD |= (1 << 5) | (1 << 6);
        PORTB |= (1 << 4);
        break; // число 7
    case 8:
        PORTD |= (1 << 6) | (1 << 5);
        PORTB |= (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);
        break; // число 8
    case 9:
        PORTD |= (1 << 6) | (1 << 5);
        PORTB |= (1 << 0) | (1 << 1) | (1 << 3) | (1 << 4);
        break; // число 9
    case 10:
        PORTB |= (1 << 1);
        break; // знак минус
    case 11:
        PORTD |= (1 << 6) | (1 << 5);
        PORTB |= (1 << 0) | (1 << 1);
        break; // знак градуса
    }
}

void print_led (int chislo)
{
    R1 = chislo % 10; // 1ый разряд 
    R2 = (chislo % 100) / 10; // 2ой разряд
    R3 = (chislo % 1000) / 100; // 3ий разряд
}

//======динамическая индикация конец======
// Прерывание по переполнению T2, динамическая индикация
ISR (TIMER2_OVF_vect)
{
    PORTC &= ~((1 << 2) | (1 << 4) | (1 << 5)); //гасим все разряды
    PORTB &= ~((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)); // Гасим все сегменты
    PORTD &= ~((1 << 5) | (1 << 6) | (1 << 7)); // Гасим все сегменты   
    switch (segcounter)
    {
    case 0: segment (R1);
        break; // Выводим первый разряд
    case 1: segment (R2);
        break; // Выводим второй разряд
    case 2: segment (R3);
        break; // Выводим третий разряд 
    }
    if (segcounter == 0) PORTC |= (1 << 5);
    if (segcounter == 1) PORTC |= (1 << 2);
    if (segcounter == 2) PORTC |= (1 << 4);
    if (++segcounter > 2) segcounter = 0;
}

// Главная программа
int main (void)
{
    DDRB = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);
    DDRD = (1 << 5) | (1 << 6) | (1 << 7);
    DDRC = (1 << 2) | (1 << 4) | (1 << 5);
    // Настройка Таймера 2
    TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру2
    TCCR2 |= (1 << CS22) | (1 << CS20); // Предделитель на 128
    asm volatile ("sei"); // Глобально разрешаю прерывания
    R1 = 1;
    R2 = 2;
    R3 = 3;
    while (1)
    {
    }
}

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 12:55:28
Gin87
Всем спасибо, за помощь. Нашел проблему. В общем мой самый первый код рабочий. У меня катоды через ULN2003A включены, забыл ее запитать. Все работает.
Вот код, может кому пригодится.

Код: Выделить всё

//#define F_CPU 8000000UL		// Тактовая частота микроконтроллера 8 МГц

// Подключаю стандартные библиотеки
#include <avr/io.h>			// Ножки ввода-вывода
#include <util/delay.h>		// Задержки
#include <avr/interrupt.h>	// Прерывания

volatile unsigned int segcounter = 0;


//создаем глобальные переменные для хранения разрядов выводимого числа
volatile char R1=0;
volatile char R2=0;
volatile char R3=0;

//======динамическая индикация============

void segment (char N)
{

switch (N)
{
case 0:
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<0)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 0
case 1:
 PORTD|=(1<<5);
 PORTB|=(1<<4);   
 break; // число 1
case 2: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<1)|(1<<2)|(1<<3);  
 break; // число 2
case 3: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<1)|(1<<3)|(1<<4);  
 break; // число 3
case 4: 
 PORTD|=(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<4); 
 break; // число 4
case 5: 
 PORTD|=(1<<6);
 PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4);  
 break; // число 5
case 6: 
 PORTD|=(1<<6);
 PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 6
case 7: 
 PORTD|=(1<<5)|(1<<6);
 PORTB|=(1<<4);   
 break; // число 7
case 8: 
 PORTD|=(1<<6)|(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4); 
 break; // число 8
case 9: 
 PORTD|=(1<<6)|(1<<5);
 PORTB|=(1<<0)|(1<<1)|(1<<3)|(1<<4); 
 break; // число 9
case 10: 
 PORTB|=(1<<1); 
 break; // знак минус
case 11: 
 PORTD|=(1<<6)|(1<<5); 
 PORTB|=(1<<0)|(1<<1);  
 break; // знак градуса
case 12: 
 PORTD|=0; 
 PORTB|=0;  
 break; // знак градуса
}
}
 

 
//Эта функция принимает как аргумент число которое необходимо вывести. Эта функция меняет глобальные переменные разрядов чисел в соответствии с аргументом функции
void print_led (int chislo)
{
R1=chislo%10;  // 1ый разряд 
R2=(chislo%100)/10; // 2ой разряд
R3=(chislo%1000)/100; // 3ий разряд
}


//======динамическая индикация конец======
	


// Прерывание по переполнению T2, динамическая индикация
ISR (TIMER2_OVF_vect)
{
 
PORTB &=~((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)); // Гасим все сегменты
PORTD &=~((1<<5)|(1<<6)|(1<<7)); // Гасим все сегменты	
PORTC &=~((1<<2)|(1<<4)|(1<<5));//гасим все разряды


 switch (segcounter)
 {   
  case 0: segment(R1); PORTC|=(1<<5);  break;  // Выводим первый разряд
  case 1: segment(R2); PORTC|=(1<<2);  break;  // Выводим второй разряд
  case 2: segment(R3); PORTC|=(1<<4);  break;  // Выводим третий разряд 
 }


segcounter++;

if(segcounter>2) segcounter=0;

}

// Главная программа
int main (void)            
{

DDRB=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4);
DDRD=(1<<5)|(1<<6)|(1<<7);
DDRC=(1<<2)|(1<<4)|(1<<5);


// Настройка Таймера 2
TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру2
TCCR2 |= (1 << CS22)|(1 << CS20);  // Предделитель на 128



asm volatile ("sei");					// Глобально разрешаю прерывания

while(1)
{


R1=1;
R2=2;
R3=3;


}

}



Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 12:56:15
Gin87
oleg110592, спасибо большое, что проверили. =)

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 14:04:04
ARV
Gin87 писал(а):Вот код, может кому пригодится.
разве что в качестве примера, как не следует писать программы.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 14:25:20
Gin87
ARV писал(а):
Gin87 писал(а):Вот код, может кому пригодится.
разве что в качестве примера, как не следует писать программы.
Уважаемый, ARV, ну пожалуйста пожалуйста пожалуйста пожалуйста пожалуйста , напишите КАК НАДО БЫЛО правильно?

А то балаболить многие могут.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 14:28:05
ARV
я уже столько раз писал - воспользуйтесь поиском по форуму. в конце-концов, загляните на мой сайт.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 14:32:14
Gin87
ARV писал(а):я уже столько раз писал - воспользуйтесь поиском по форуму. в конце-концов, загляните на мой сайт.
Вот этим все и сказано.


P.S. Да и сайт Ваш сплошная копипаста интернета. Своего либо нет, либо совсем мало. Динамической индикации посредством РАЗНЫХ битов разных портов там НЕТ.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 15:42:38
shads
Gin87 писал(а):Динамической индикации посредством РАЗНЫХ битов разных портов там НЕТ.
Ща будет... поищу, как я делал...

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 16:50:47
oleg110592
вариант
Спойлер

Код: Выделить всё

#include <avr/io.h>         // Ножки ввода-вывода
#include <util/delay.h>      // Задержки
#include <avr/interrupt.h>   // Прерывания
#include <avr/pgmspace.h>

#define SegA	(uint8_t)1<<0
#define SegB	(uint8_t)1<<1
#define SegC	(uint8_t)1<<2
#define SegD	(uint8_t)1<<3
#define SegE	(uint8_t)1<<4
#define SegF	(uint8_t)1<<5
#define SegG	(uint8_t)1<<6
#define SegH	(uint8_t)1<<7

#define digit_0	(uint8_t)(SegA | SegB | SegC | SegD | SegE | SegF)
#define digit_1	(uint8_t)(SegB | SegC)
#define digit_2	(uint8_t)(SegA | SegB | SegG | SegE | SegD)
#define digit_3	(uint8_t)(SegA | SegB | SegG | SegC | SegD)
#define digit_4	(uint8_t)(SegF | SegG | SegB | SegC)
#define digit_5	(uint8_t)(SegA | SegF | SegG | SegC | SegD)
#define digit_6	(uint8_t)(SegA | SegF | SegE | SegD | SegC | SegG)
#define digit_7	(uint8_t)(SegA | SegB | SegC)
#define digit_8	(uint8_t)(SegA | SegB | SegC | SegD | SegE | SegF | SegG)
#define digit_9	(uint8_t)(SegA | SegB | SegC | SegD | SegF | SegG)

const uint8_t seg7[10] PROGMEM ={
    digit_0,
    digit_1,
    digit_2,
    digit_3,
    digit_4,
    digit_5,
    digit_6,
    digit_7,
    digit_8,
    digit_9
};

// A PD6
// B PD5
// C PB4
// D PB3
// E PB2
// F PB0
// G PB1
// H PD7
#define SEGA_PORT PORTD
#define SEGA ((uint8_t)(1<<6))
#define SEGB_PORT PORTD
#define SEGB ((uint8_t)(1<<5))
#define SEGC_PORT PORTB
#define SEGC ((uint8_t)(1<<4))
#define SEGD_PORT PORTB
#define SEGD ((uint8_t)(1<<3))
#define SEGE_PORT PORTB
#define SEGE ((uint8_t)(1<<2))
#define SEGF_PORT PORTB
#define SEGF ((uint8_t)(1<<0))
#define SEGG_PORT PORTB
#define SEGG ((uint8_t)(1<<1))
#define SEGH_PORT PORTD
#define SEGH ((uint8_t)(1<<7))

#define CAT1_PORT PORTC
#define CAT1 ((uint8_t)(1<<5))
#define CAT2_PORT PORTC
#define CAT2 ((uint8_t)(1<<2))
#define CAT3_PORT PORTC
#define CAT3 ((uint8_t)(1<<4))

volatile unsigned int segcounter = 0;

//создаем глобальные переменные для хранения разрядов выводимого числа
volatile char R1 = 0;
volatile char R2 = 0;
volatile char R3 = 0;
volatile char tempR = 0;

void print_led (int chislo)
{
    R1 = seg7[chislo % 10]; // 1ый разряд 
    R2 = seg7[(chislo % 100) / 10]; // 2ой разряд
    R3 = seg7[(chislo % 1000) / 100]; // 3ий разряд
}

// Прерывание по переполнению T2, динамическая индикация
ISR (TIMER2_OVF_vect)
{
    CAT1_PORT &= ~CAT1; // cathodes off
    CAT2_PORT &= ~CAT2;
    CAT3_PORT &= ~CAT3;

    SEGA_PORT &= ~SEGA; // segment off
    SEGB_PORT &= ~SEGB;
    SEGC_PORT &= ~SEGC;
    SEGD_PORT &= ~SEGD;
    SEGE_PORT &= ~SEGE;
    SEGF_PORT &= ~SEGF;
    SEGG_PORT &= ~SEGG;
    SEGH_PORT &= ~SEGH;

    switch (segcounter)
    {
    case 0: tempR = R1;
        break; // Выводим первый разряд
    case 1: tempR = R2;
        break; // Выводим второй разряд
    case 2: tempR = R3;
        break; // Выводим третий разряд 
    }
    
    if(tempR & SegA) SEGA_PORT |= SEGA;
    if(tempR & SegB) SEGB_PORT |= SEGB;
    if(tempR & SegC) SEGC_PORT |= SEGC;
    if(tempR & SegD) SEGD_PORT |= SEGD;
    if(tempR & SegE) SEGE_PORT |= SEGE;
    if(tempR & SegF) SEGF_PORT |= SEGF;
    if(tempR & SegG) SEGG_PORT |= SEGG;
    if(tempR & SegH) SEGH_PORT |= SEGH;
    
    if (segcounter == 0) CAT1_PORT |= CAT1;
    if (segcounter == 1) CAT2_PORT |= CAT2;
    if (segcounter == 2) CAT3_PORT |= CAT3;
    if (++segcounter > 2) segcounter = 0;
}

// Главная программа

int main (void)
{
    DDRB = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);
    DDRD = (1 << 5) | (1 << 6) | (1 << 7);
    DDRC = (1 << 2) | (1 << 4) | (1 << 5);
    // Настройка Таймера 2
    TIMSK |= (1 << TOIE2); // Разрешение прерывания по таймеру2
    TCCR2 |= (1 << CS22) | (1 << CS20); // Предделитель на 128
    asm volatile ("sei"); // Глобально разрешаю прерывания
    R1 = digit_1;
    R2 = digit_2;
    R3 = digit_3;
    while (1)
    {
    }
}

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 18:35:55
shads
В принципе у меня почти так же как и у oleg110592...
В архиве примерчик использования в проте...

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 19:29:49
ARV
Gin87 писал(а):Да и сайт Ваш сплошная копипаста интернета. Своего либо нет, либо совсем мало. Динамической индикации посредством РАЗНЫХ битов разных портов там НЕТ.
вы отдаете себе отчет, что вы такое сейчас сказанули? на моем сайте все проекты (кроме буквально пары) исключительно МОИ. это в интернете полно плагиата с моего сайта - все мои таймеры скоммуниздены практически на каждый радиолюбительский сайт. проекты, которые в былые времена я размещал на радиокоте - все скопированы на другие сайты, и большинство без указания авторства.

Re: Динамическая индикация на разных портах.

Добавлено: Пт май 20, 2016 22:09:43
Jack_A
СпойлерВот объясните - почему некотрые новички еще 2*2 как след написать не могут, а как затешутся в форум - сразу начинают поучать и раздавать шпиндюлей? Одно хорошо - их форумный век обычно недолог .