Проблема с семисегментным индикатором

Обсуждаем контроллеры компании Atmel.
Ответить
Родился
Сообщения: 15
Зарегистрирован: Чт апр 23, 2020 12:42:03

Сообщение RishatPF »

Здравствуйте. Если не трудно,подскажите пожалуйста, почему при одинаковых подключениях на индикаторах из
Рис1
Изображение
и Рис2
Изображение
разный результат как на Рис3
Изображение,
уже голову сломал.

Вот сам код:

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

 #include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


#define  CHISLO PORTD
#define  RAZRIAD PORTB



unsigned int razr1 = 0, razr2 = 0, razr3 = 0, razr4 = 0, razr5 = 0, razr6 = 0;
unsigned char reg = 1;
unsigned int z, a=0, i=0, k=0, j=0;
unsigned int comma=0x80;


unsigned int chisla [11] = {
	
	// числа от 0 до 9
	0x3f, 0x6, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x80
};


void vse_chislo (unsigned int razbivka_chisla)
{
   // индикация первого дисплея 4 индикатора
	razr1 = razbivka_chisla/1000; // тысячи
	razr2 = razbivka_chisla%1000/100; // сотни
	razr3 = razbivka_chisla%100/10; // десятки
	razr4 = razbivka_chisla%10; // единицы
        
}

void vse_chislo1 (unsigned int razbivka_chisla1)
{
     // индикация второго дисплея 2 индикатора
	razr5= razbivka_chisla1%100/10;// десятки
	razr6= razbivka_chisla1%10;// единицы
}

ISR (TIMER0_OVF_vect)
{
   //переключение разрядов для обоих дисплеев
	if (reg == 1) {RAZRIAD = 0b00000001; CHISLO = chisla[razr1];} //включаем 1-й разряд, остальные выключаем
	if (reg == 2) {RAZRIAD = 0b00000010; CHISLO = chisla[razr2];} //включаем 2-й разряд, остальные выключаем
	if (reg == 3) {RAZRIAD = 0b00000100; CHISLO = chisla[razr3];} //включаем 3-й разряд, остальные выключаем
	if (reg == 4) {RAZRIAD = 0b00001000; CHISLO = chisla[razr4] | comma;} //включаем 4-й разряд, остальные выключаем
	if (reg == 5) {RAZRIAD = 0b00010000; CHISLO = chisla[razr5];} //включаем 5-й разряд, остальные выключаем
	if (reg == 6) {RAZRIAD = 0b00100000; CHISLO = chisla[razr6];} //включаем 6-й разряд, остальные выключаем
	reg++; // добавляем к переменной reg единицу
	if (reg > 6) reg = 1; // отслеживаем переменную reg, чтобы она не превысила значение 4
		
}



int main(void)
{
  
   // Настройка портов ввода-вывода
        DDRD = 0xFF;
        DDRB = 0xFF;
        DDRC &= ~((1<<4) | (1<<5));
	PORTC |= (1<<2) | (1<<3)| (1<<4)| (1<<5);
	
	
	RAZRIAD = 0b00000001;
	CHISLO = 0xff;
	
	// Настройка 0-го таймер счетчика на прерывание по переполнению
	
	TCCR0 |= (1<<1); TCCR0 &= ~((1<<0) | (1<<2)); // f/8
	TIMSK |= (1<<0);
	TCNT0 = 0;
	sei ();
	
	
	
    while (1) 
    {
       
       vse_chislo1(i); //вывод на первый дисплей
       	vse_chislo(j); //вывод на второй дисплей
		
            //*---------------------------------Дисплей 1-------------------------------------------------------*/  
   /*    switch(i){
	  case 1: z=1; break;
	     case 2: z=5; break;
		case 3: z=10; break;
		   case 4: z=20; break;
		      case 5: z=50; break;
			 default : z=0;
       }
       */
     
       if (bit_is_clear(PINC, 2)){
	  
	 if(i<99){
	    
	     i=i+1;
	     _delay_ms(2500);
	  }else { i=99;}
	  }
		
		
		   if (bit_is_clear(PINC, 3)){
	  
	 if(i>1){
	    
	     i=i-1;
	     _delay_ms(2500);
	  }else { i=0;}
	  }
	  
	  
	/*-------------------------------Дисплей 2---------------------------------------------------------*/  
	  
	/*   switch(j){
	  case 1: k=1500; break;
	     case 2: k=500; break;
		case 3: k=300; break;
		   case 4: k=200; break;
		      case 5: k=100; break;
			 default : k=0;
			 }*/
			    
	     if (bit_is_clear(PINC, 4)){
	  
	 if(j<9999){
	    
	     j=j+1;
	     _delay_ms(500);
	  }else { j=9999;}
	  }
		
		
		   if (bit_is_clear(PINC, 5)){
	  
	 if(j>1){
	    
	     j=j-1;
	     _delay_ms(500);
	  }else { j=0;}
	  }

		
    }
}

Вложения
2020-05-17_18-20-17.png
Рис3
(13.84 КБ) 889 скачиваний
2020-05-17_18-18-20.png
Рис2
(4.45 КБ) 880 скачиваний
2020-05-17_18-17-19.png
Рис1
(3.59 КБ) 910 скачиваний
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

глюк протеуса... кликни правой клавишей на неисправный экран и в настройках поправь время чувствительности (точное название и значение не помню)
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Родился
Сообщения: 15
Зарегистрирован: Чт апр 23, 2020 12:42:03

Сообщение RishatPF »

[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3842548#p3842548"]глюк протеуса... кликни правой клавишей на неисправный экран и в настройках поправь время чувствительности (точное название и значение не помню)[/uquote]

Менял от 1ms до 7ms эффект тот же :(
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Сообщение Ярослав555 »

я Вам секрет открою - туда можно вписать 0.01 mS
Реклама
Эиком - электронные компоненты и радиодетали
Модератор
Аватара пользователя
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля

Сообщение Аlex »

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

   //переключение разрядов для обоих дисплеев
   if (reg == 1) {RAZRIAD = 0b00000001; CHISLO = chisla[razr1];} //включаем 1-й разряд, остальные выключаем
   if (reg == 2) {RAZRIAD = 0b00000010; CHISLO = chisla[razr2];} //включаем 2-й разряд, остальные выключаем
   if (reg == 3) {RAZRIAD = 0b00000100; CHISLO = chisla[razr3];} //включаем 3-й разряд, остальные выключаем
   if (reg == 4) {RAZRIAD = 0b00001000; CHISLO = chisla[razr4] | comma;} //включаем 4-й разряд, остальные выключаем
   if (reg == 5) {RAZRIAD = 0b00010000; CHISLO = chisla[razr5];} //включаем 5-й разряд, остальные выключаем
   if (reg == 6) {RAZRIAD = 0b00100000; CHISLO = chisla[razr6];} //включаем 6-й разряд, остальные выключаем
   reg++; // добавляем к переменной reg единицу
   if (reg > 6) reg = 1; // отслеживаем переменную reg, чтобы она не превысила значение 4
Я вам больше скажу. С таким кодом у вас будут проблемы и в железе.

PS: Вообще, у вас Протеус в руках. Он умеет код отлаживать. Пройдитесь по шагам в своём коде и посмотрите что творится на выводах процессора. И проблема всплывёт сама собой.
Хотя, тут и отладка не нужна - результат очевиден. Достаточно глазами пройтись "пошагово".
Контактная информация:
Реклама
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Сообщение Ярослав555 »

СпойлерИзображение
Изображение
Изображение
Изображение
Вложения
graphic.png
(45.93 КБ) 351 скачивание
indicator.png
(43.47 КБ) 343 скачивания
prot.png
(33.87 КБ) 353 скачивания
sch.png
(103.98 КБ) 364 скачивания
Реклама
Родился
Сообщения: 15
Зарегистрирован: Чт апр 23, 2020 12:42:03

Сообщение RishatPF »

[uquote="Ярослав555",url="/forum/viewtopic.php?p=3842574#p3842574"]я Вам секрет открою - туда можно вписать 0.01 mS[/uquote]
Перепробовал на всех трёх дисплеях, не помогло :(

Добавлено after 57 seconds:
[uquote="Ярослав555",url="/forum/viewtopic.php?p=3842577#p3842577"]
СпойлерИзображение
Изображение
Изображение
Изображение
[/uquote]
Все параметры такие же. Но что то не помогает.

Добавлено after 3 minutes 4 seconds:
[uquote="Аlex",url="/forum/viewtopic.php?p=3842575#p3842575"]

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

   //переключение разрядов для обоих дисплеев
   if (reg == 1) {RAZRIAD = 0b00000001; CHISLO = chisla[razr1];} //включаем 1-й разряд, остальные выключаем
   if (reg == 2) {RAZRIAD = 0b00000010; CHISLO = chisla[razr2];} //включаем 2-й разряд, остальные выключаем
   if (reg == 3) {RAZRIAD = 0b00000100; CHISLO = chisla[razr3];} //включаем 3-й разряд, остальные выключаем
   if (reg == 4) {RAZRIAD = 0b00001000; CHISLO = chisla[razr4] | comma;} //включаем 4-й разряд, остальные выключаем
   if (reg == 5) {RAZRIAD = 0b00010000; CHISLO = chisla[razr5];} //включаем 5-й разряд, остальные выключаем
   if (reg == 6) {RAZRIAD = 0b00100000; CHISLO = chisla[razr6];} //включаем 6-й разряд, остальные выключаем
   reg++; // добавляем к переменной reg единицу
   if (reg > 6) reg = 1; // отслеживаем переменную reg, чтобы она не превысила значение 4
Я вам больше скажу. С таким кодом у вас будут проблемы и в железе.

PS: Вообще, у вас Протеус в руках. Он умеет код отлаживать. Пройдитесь по шагам в своём коде и посмотрите что творится на выводах процессора. И проблема всплывёт сама собой.
Хотя, тут и отладка не нужна - результат очевиден. Достаточно глазами пройтись "пошагово".[/uquote]

Если не трудно, пожалуйста, ткните носом, а то что то не пойму о чём Вы. И кто му же почему с первым дисплеем всё нормально а второй и третий глючит?

Добавлено after 7 minutes 55 seconds:

Для наглядности добавил видео
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Сообщение Ярослав555 »

если не трудно - дайте проект протеуса и хекс прошивки.
Родился
Сообщения: 15
Зарегистрирован: Чт апр 23, 2020 12:42:03

Сообщение RishatPF »

[uquote="Ярослав555",url="/forum/viewtopic.php?p=3842601#p3842601"]если не трудно - дайте проект протеуса и хекс прошивки.[/uquote]

Прикрепил архив.

зы: перезалил.
Вложения
export.rar
(31.25 КБ) 158 скачиваний
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Сообщение Ярослав555 »

Все работает. Дело в прошивке. Я вообще удивляюсь, как протеус хоть как-то работал на этой прошивке.
Сегменты у вас как для СС индикатора, групповые выводы как для СА индикатора. Или на что-то ставьте лог инверторы, или прошивку правьте.
Самсусамыч

Сообщение Самсусамыч »

К «reg» не единицу нужно добавлять, а производить сдвиг влево…
reg++; // добавляем к переменной reg единицу
то есть в начале в «reg» записывается 1, а затем её сдвигаем влево до конечного значения…
Поставщик валерьянки для Кота
Аватара пользователя
Сообщения: 2081
Зарегистрирован: Пт май 31, 2013 17:14:38
Откуда: Украина, Винница

Сообщение Ярослав555 »

СпойлерИзображение
Вложения
prot.png
(245.38 КБ) 344 скачивания
Родился
Сообщения: 15
Зарегистрирован: Чт апр 23, 2020 12:42:03

Сообщение RishatPF »

[uquote="Самсусамыч",url="/forum/viewtopic.php?p=3842690#p3842690"]К «reg» не единицу нужно добавлять, а производить сдвиг влево…
reg++; // добавляем к переменной reg единицу
то есть в начале в «reg» записывается 1, а затем её сдвигаем влево до конечного значения…[/uquote]

не совсем вас понял. через reg я делаю переключение, а сдвиг у меня здесь RAZRIAD = 0b00000001;

Добавлено after 1 minute 30 seconds:
[uquote="Ярослав555",url="/forum/viewtopic.php?p=3842687#p3842687"]Все работает. Дело в прошивке. Я вообще удивляюсь, как протеус хоть как-то работал на этой прошивке.
Сегменты у вас как для СС индикатора, групповые выводы как для СА индикатора. Или на что-то ставьте лог инверторы, или прошивку правьте.[/uquote]
сам в шоке, по другому у меня или индикаторы не включались или только 8 было. Завтра буду разбираться.

Добавлено after 1 minute 53 seconds:
[uquote="Ярослав555",url="/forum/viewtopic.php?p=3842694#p3842694"]
СпойлерИзображение
[/uquote]
Спасибо, заработало. и выводы регистров правильно встали :)
Завтра попробую програмно решить проблему.

Добавлено after 8 hours 22 minutes 44 seconds:
[uquote="Ярослав555",url="/forum/viewtopic.php?p=3842687#p3842687"]Все работает. Дело в прошивке. Я вообще удивляюсь, как протеус хоть как-то работал на этой прошивке.
Сегменты у вас как для СС индикатора, групповые выводы как для СА индикатора. Или на что-то ставьте лог инверторы, или прошивку правьте.[/uquote]
Вы были правы, индикатор ОК а выходы были настроены на ОА. Исправил и о чудо, всё заработало :) Большое спасибо.

Добавлено after 2 minutes 27 seconds:
[uquote="Самсусамыч",url="/forum/viewtopic.php?p=3842690#p3842690"]К «reg» не единицу нужно добавлять, а производить сдвиг влево…
reg++; // добавляем к переменной reg единицу
то есть в начале в «reg» записывается 1, а затем её сдвигаем влево до конечного значения…[/uquote]
Вы наверное это имели в виду?
Спойлер

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

if (reg == 1) { PORTB|=(1<<PORTB5);PORTB&=~(1<<PORTB0); CHISLO = chisla[razr1];} //включаем 1-й разряд, остальные выключаем
	if (reg == 2) { PORTB|=(1<<PORTB0);PORTB&=~(1<<PORTB1); CHISLO = chisla[razr2];} //включаем 2-й разряд, остальные выключаем
	if (reg == 3) { PORTB|=(1<<PORTB1);PORTB&=~(1<<PORTB2); CHISLO = chisla[razr3];} //включаем 3-й разряд, остальные выключаем
	if (reg == 4) { PORTB|=(1<<PORTB2);PORTB&=~(1<<PORTB3); CHISLO = chisla[razr4] |comma;} //включаем 4-й разряд, остальные выключаем
	if (reg == 5) { PORTB|=(1<<PORTB3);PORTB&=~(1<<PORTB4); CHISLO = chisla[razr5];} //включаем 5-й разряд, остальные выключаем
	if (reg == 6) { PORTB|=(1<<PORTB4);PORTB&=~(1<<PORTB5); CHISLO = chisla[razr6];} //включаем 6-й разряд, остальные выключаем
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Сообщение NStorm »

Вы наверное это имели в виду?
Не это явно имели в виду. Прочитайте как работает сдвиг. У вас такая тонна избыточного кода из-за малого знания языка.
Я бы как-то так переписал, вместо сдвига reg, чтобы CHISLO выбирать нормально. При этом razrX переделать в массив:

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

PORTB = 1 << (reg - 1);
CHISLO = chisla[razr[reg - 1]];
if (reg == 4)
  CHISLO |= comma;
reg++;
if (reg > 6)
  reg = 1;
Последний раз редактировалось NStorm Пн май 18, 2020 14:00:23, всего редактировалось 1 раз.
Прорезались зубы
Аватара пользователя
Сообщения: 237
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Сообщение AlanDrakes »

ИМХО, исправляется элементарно:

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


ISR (TIMER0_OVF_vect)
{
RAZRIAD = 0; // Гашение индикаторов перед переключением.
   //переключение разрядов для обоих дисплеев
   if (reg == 1) {RAZRIAD = 0b00000001; CHISLO = chisla[razr1];} //включаем 1-й разряд, остальные выключаем
   if (reg == 2) {RAZRIAD = 0b00000010; CHISLO = chisla[razr2];} //включаем 2-й разряд, остальные выключаем
   if (reg == 3) {RAZRIAD = 0b00000100; CHISLO = chisla[razr3];} //включаем 3-й разряд, остальные выключаем
   if (reg == 4) {RAZRIAD = 0b00001000; CHISLO = chisla[razr4] | comma;} //включаем 4-й разряд, остальные выключаем
   if (reg == 5) {RAZRIAD = 0b00010000; CHISLO = chisla[razr5];} //включаем 5-й разряд, остальные выключаем
   if (reg == 6) {RAZRIAD = 0b00100000; CHISLO = chisla[razr6];} //включаем 6-й разряд, остальные выключаем
   reg++; // добавляем к переменной reg единицу
   if (reg > 6) reg = 1; // отслеживаем переменную reg, чтобы она не превысила значение 4
      
}
Ответить

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