7-ми сегментный индикатор под mega16

Обсуждаем контроллеры компании Atmel.
Ответить
-=eagle=-
Родился
Сообщения: 7
Зарегистрирован: Сб апр 18, 2015 00:48:07

7-ми сегментный индикатор под mega16

Сообщение -=eagle=- »

Приветствую!
Прошу помощи с выводом на индикатор. Имеется индикатор с общим катодом и 16-я мега. Возникла такая проблема: Если в протеусе катоды подключать через инвертирующий элемент - все работает, а через транзисторы - нет. Уже всю голову сломал, что в программе надо подправить, но никакие действия не приводят к нужному результату. Буду премного благодарен за помощь!

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

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


unsigned char number[] = 
{
  0x3f, //0
  0x06, //1
  0x5b, //2
  0x4f, //3   
  0x66, //4
  0x6d, //5 
  0x7d, //6
  0x07, //7   
  0x7f, //8
  0x6f  //9    
};


//числа для вывода на индикатор
volatile int indication_number = 0;

int main( void )
{
  //порт, к которому подкл. сегменты
  PORTD = 0xFF;
  DDRD = 0xFF;
  
  //порт, к которому подкл. катод
  PORTA = 0x00;
  DDRA |= (1<<3)|(1<<2)|(1<<1)|(1<<0); 
  
  //инициализация таймера Т0 
  TIMSK = (1<<TOIE0);
  TCCR0 = (1<<CS02)|(0<<CS01)|(1<<CS00);
  TCNT0 =  0xd2;
  
    
  sei();

  indication_number=1834;
 
 while(127)
{
      
	  indication_number += 20;
         _delay_ms(1000);     
  }  
  return 0;
}

//прерывания таймера Т0 - вывод на индикатор
ISR(TIMER0_OVF_vect)
{
  static unsigned char count = 0;
  TCNT0 = 0xd2;
  
   //гасим разряды
   PORTA &= ~((1<<3)|(1<<2)|(1<<1)|(1<<0));
   
   
   //зажигаем следующий разряд
   if (count == 0) {
	   PORTD = (number[indication_number % 10000 / 1000]);
	   PORTA |= (1<<3);
   }
   if (count == 1) {
	   PORTD = (number[indication_number % 1000 / 100]);
	   PORTA |= (1<<2);
   }
   if (count == 2) {
	  PORTD = (number[indication_number % 100 / 10]);
      PORTA |= (1<<1);
   }
   if (count == 3) {
      PORTD = (number[indication_number % 10]);
      PORTA |= (1<<0);
   }
    
    count++;
    if (count == 4) count = 0;
}
Реклама
Аватара пользователя
smacorp
Друг Кота
Сообщения: 3480
Зарегистрирован: Вт окт 22, 2013 04:37:23
Откуда: Казань

Re: 7-ми сегментный индикатор под mega16

Сообщение smacorp »

-=eagle=- писал(а):через инвертирующий элемент - все работает, а через транзисторы - нет. Уже всю голову сломал, что в программе надо подправить
Откуда уверенность, что править нужно именно в программе? Уверены, что, например, транзисторы правильно подключаете?
Платы для HLDI - установки лазерной засветки фоторезиста.
Фоторезист Ordyl Alpha 350
Жидкое олово для лужения плат (видео) - самое лучшее и только у меня.
Паяльные маски XV501T-4 и KSM-S6189 (5 цветов).
Заказ печатных плат - pcbsmac@gmail.com
Реклама
Аватара пользователя
Halex
Грызет канифоль
Сообщения: 281
Зарегистрирован: Пт ноя 15, 2013 20:58:23

Re: 7-ми сегментный индикатор под mega16

Сообщение Halex »

smacorp писал(а):Откуда уверенность, что править нужно именно в программе?
Да в голове надо править, - в голове!!! Сто-пИтьсот раз объяснял - многоразрядные семисегментники из библиотеки LEDMPX.DLL в Протеусе чисто цифровые, аналоговых свойств не имеют никаких! Нет, чайники упорно лепят на них транзисторные ключи, да для пущей важности ещё и токоограничивающие резисторы "впа(Р)ивают". В Протеусе нет цифровых моделей транзисторов - только аналоговые. Инвертор - цифровой элемент, потому и работает. Песонально для -=eagle=- поясняющая картинка. Подставьте мысленно вместо амперметра транзисторный ключ - будет работать, или нет???
Изображение
А вообще для таких вопросов есть соответствующая ветка и здесь на Коте, может модераторы перенесут туда?
Последний раз редактировалось Halex Вс апр 19, 2015 06:38:25, всего редактировалось 1 раз.
Аватара пользователя
dr.doc
Это не хвост, это антенна
Сообщения: 1368
Зарегистрирован: Вс мар 28, 2010 12:52:22
Откуда: Беларусь

Re: 7-ми сегментный индикатор под mega16

Сообщение dr.doc »

Вот этого не знал... А обходил простой подтяжкой общих выводов индикаторов к питанию в запирающем включении.
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
smacorp
Друг Кота
Сообщения: 3480
Зарегистрирован: Вт окт 22, 2013 04:37:23
Откуда: Казань

Re: 7-ми сегментный индикатор под mega16

Сообщение smacorp »

Halex писал(а):Песонально для smacorp поясняющая картинка. Подставьте мысленно вместо амперметра транзисторный ключ - будет работать, или нет???
Вы ничего не перепутали? Во-первых, топик создал не я. Во-вторых, у меня в Протеусе транзисторы в режиме ключа, где нужно, работают без проблем.
Платы для HLDI - установки лазерной засветки фоторезиста.
Фоторезист Ordyl Alpha 350
Жидкое олово для лужения плат (видео) - самое лучшее и только у меня.
Паяльные маски XV501T-4 и KSM-S6189 (5 цветов).
Заказ печатных плат - pcbsmac@gmail.com
Реклама
Аватара пользователя
Halex
Грызет канифоль
Сообщения: 281
Зарегистрирован: Пт ноя 15, 2013 20:58:23

Re: 7-ми сегментный индикатор под mega16

Сообщение Halex »

smacorp писал(а):Вы ничего не перепутали?
Да, не тот ник вставил, приношу извинения, уже исправил.
Реклама
-=eagle=-
Родился
Сообщения: 7
Зарегистрирован: Сб апр 18, 2015 00:48:07

Re: 7-ми сегментный индикатор под mega16

Сообщение -=eagle=- »

Halex писал(а):
smacorp писал(а):Откуда уверенность, что править нужно именно в программе?
Да в голове надо править, - в голове!!! Сто-пИтьсот раз объяснял - многоразрядные семисегментники из библиотеки LEDMPX.DLL в Протеусе чисто цифровые, аналоговых свойств не имеют никаких! Нет, чайники упорно лепят на них транзисторные ключи, да для пущей важности ещё и токоограничивающие резисторы "впа(Р)ивают". В Протеусе нет цифровых моделей транзисторов - только аналоговые. Инвертор - цифровой элемент, потому и работает. Песонально для -=eagle=- поясняющая картинка. Подставьте мысленно вместо амперметра транзисторный ключ - будет работать, или нет???
Изображение
А вообще для таких вопросов есть соответствующая ветка и здесь на Коте, может модераторы перенесут туда?
Так за этим и пришел сюда, чтобы в голове поправить :)

Собрал тестовую схему на транзисторах - все равно не работает, все сегменты зажигаются на ура, а вот управлять не получается. Транзисторы использовал такие: Транзистор bc847b SOT23 45V 0.1A NPN 100MHZ, на базу повесил резистор 220 Ом, выводы сегментов также висят на 220 Ом.
-=eagle=-
Родился
Сообщения: 7
Зарегистрирован: Сб апр 18, 2015 00:48:07

Re: 7-ми сегментный индикатор под mega16

Сообщение -=eagle=- »

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

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

#define  F_CPU 8000000UL // Частота кварца

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

volatile unsigned int test = 1234; // Переменная для вывода на индикатор

ISR(TIMER1_COMPA_vect)  // Обработчик прерывания по совпадению таймера 1
{
	test++; // Увеличить выводимое число
	if(test > 9999) test = 0; // Если вышел за пределы четырех разрядов, обнулить
	TCNT1H=0x00; // Сброс регистра
	TCNT1L=0x00; // счета
}

void dig_out(int num); // Объявление функции вывода на индикатор

int main(void)
{
	DDRA = 0x0F;  // Настройка портов
	DDRC = 0xFF;  // для работы с индикатором Порт С для разрядов, Порт D для цифр
	
	TCCR1A=0x00; // Настройка таймера
	TCCR1B=0x04;
	TCNT1H=0x00;
	TCNT1L=0x00;
	OCR1AH=0x70;
	OCR1AL=0x80;
	
	TIMSK=0x10;
	
	sei(); // Разрешение прерываний
	
	while(1)
	{
		dig_out(test);	//Постоянно вызываем функцию вывода текущего числа
	}
}

void dig_out(int num) // Функция для вывода на индикатор 4-х разрядов
{
	unsigned char i = 0; // Переменная счетчика
	unsigned char raz = 1; // Номер разряда
	unsigned char dig_num[] = {
		0x3f, //0
		0x06, //1
		0x5b, //2
		0x4f, //3
		0x66, //4
		0x6d, //5
		0x7d, //6
		0x07, //7
		0x7f, //8
		0x6f}; // Коды цифр для индикатора с общим анодом
	unsigned char dig[] = {0, 0, 0, 0}; // Массив для значения разряда
	
	if(num < 10) // Для заполнения нулями левых разрядов
	{
		dig[0] =0;
		dig[1] =0;
		dig[2] =0;
	}
	
	if(num < 100) // Для заполнения нулями левых разрядов
	{
		dig[0] =0;
		dig[1] =0;
	}
	
	if(num < 1000) // Для заполнения нулями левых разрядов
	{
		dig[0] =0;
	}
	
	while(num > 999)  // Получение количества тысяч
	{
		dig[0]++;
		num -= 1000;
	}
	
	while(num > 99)  // Получение количества сотен
	{
		dig[1]++;
		num -= 100;
	}
	
	while(num > 9) // Получение числа десятков
	{
		dig[2]++;
		num -= 10;
	}
	
	dig[3] = num; // Получения количества единиц
	
	while(raz <= 0x10) // Крутимся пока не заполним все 4 разряда
	{
		PORTA = raz; // Выбираем разряд
		PORTC = dig_num[dig[i]]; // Выводим цифру
		raz = raz<<1; // Сдвигаемся на следующий разряд
		i++; // Увеличиваем индекс следующей цифры
		_delay_ms(1); // Задержка 1 мс
	}
}
Ответить

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