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

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

Добавлено: Вс май 17, 2020 16:28:55
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;}
	  }

		
    }
}


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

Добавлено: Вс май 17, 2020 16:47:36
Ivanoff-iv
глюк протеуса... кликни правой клавишей на неисправный экран и в настройках поправь время чувствительности (точное название и значение не помню)

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

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

Менял от 1ms до 7ms эффект тот же :(

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

Добавлено: Вс май 17, 2020 18:21:02
Ярослав555
я Вам секрет открою - туда можно вписать 0.01 mS

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

Добавлено: Вс май 17, 2020 18:21:30
А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: Вообще, у вас Протеус в руках. Он умеет код отлаживать. Пройдитесь по шагам в своём коде и посмотрите что творится на выводах процессора. И проблема всплывёт сама собой.
Хотя, тут и отладка не нужна - результат очевиден. Достаточно глазами пройтись "пошагово".

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

Добавлено: Вс май 17, 2020 18:29:28
Ярослав555
СпойлерИзображение
Изображение
Изображение
Изображение

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

Добавлено: Вс май 17, 2020 19:13:56
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:

Для наглядности добавил видео

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

Добавлено: Вс май 17, 2020 19:21:07
Ярослав555
если не трудно - дайте проект протеуса и хекс прошивки.

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

Добавлено: Вс май 17, 2020 19:45:59
RishatPF
[uquote="Ярослав555",url="/forum/viewtopic.php?p=3842601#p3842601"]если не трудно - дайте проект протеуса и хекс прошивки.[/uquote]

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

зы: перезалил.

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

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

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

Добавлено: Вс май 17, 2020 22:01:08
Самсусамыч
К «reg» не единицу нужно добавлять, а производить сдвиг влево…
reg++; // добавляем к переменной reg единицу
то есть в начале в «reg» записывается 1, а затем её сдвигаем влево до конечного значения…

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

Добавлено: Вс май 17, 2020 22:03:47
Ярослав555
СпойлерИзображение

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

Добавлено: Пн май 18, 2020 07:39:11
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-й разряд, остальные выключаем

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

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

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

PORTB = 1 << (reg - 1);
CHISLO = chisla[razr[reg - 1]];
if (reg == 4)
  CHISLO |= comma;
reg++;
if (reg > 6)
  reg = 1;

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

Добавлено: Пн май 18, 2020 12:14:59
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
      
}