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

Обсуждаем контроллеры компании Atmel.
Ответить
Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение 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;


}

}



Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

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

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

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение Gin87 »

1) Совет не помог. Все равно все три цифры горят одновременно.

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

Сообщение 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;  // Выводим третий разряд 
           }
 }
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение 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;


}

}


Но не сработало. Как бы работает но идет сильная засветка неиспользуемых сегментов.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение 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 вроде).
Реклама
Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение 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 вроде).
Согласен, тут косяк. Точка лишняя. Пофиксил.
Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение 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. Нет момента когда цифра выключена. По три разряда горит. Такое чувство, что внутри контроллера через диод подтекает что ли.
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение 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)
    {
    }
}
Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение 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;


}

}


Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение Gin87 »

oleg110592, спасибо большое, что проверили. =)
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

Gin87 писал(а):Вот код, может кому пригодится.
разве что в качестве примера, как не следует писать программы.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение Gin87 »

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

А то балаболить многие могут.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Открыл глаза
Сообщения: 74
Зарегистрирован: Вс янв 24, 2010 21:29:07

Сообщение Gin87 »

ARV писал(а):я уже столько раз писал - воспользуйтесь поиском по форуму. в конце-концов, загляните на мой сайт.
Вот этим все и сказано.


P.S. Да и сайт Ваш сплошная копипаста интернета. Своего либо нет, либо совсем мало. Динамической индикации посредством РАЗНЫХ битов разных портов там НЕТ.
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

Gin87 писал(а):Динамической индикации посредством РАЗНЫХ битов разных портов там НЕТ.
Ща будет... поищу, как я делал...
Друг Кота
Аватара пользователя
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

Сообщение 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)
    {
    }
}
Опытный кот
Аватара пользователя
Сообщения: 882
Зарегистрирован: Ср фев 22, 2012 01:25:21

Сообщение shads »

В принципе у меня почти так же как и у oleg110592...
В архиве примерчик использования в проте...
Вложения
7SEG_LED_on_diff_lines.7z
(31.41 КБ) 297 скачиваний
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

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

Мой уютный бложик... заходите!
Контактная информация:
Друг Кота
Аватара пользователя
Сообщения: 6337
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение Jack_A »

СпойлерВот объясните - почему некотрые новички еще 2*2 как след написать не могут, а как затешутся в форум - сразу начинают поучать и раздавать шпиндюлей? Одно хорошо - их форумный век обычно недолог .
Изображение
Ответить

Вернуться в «AVR»