Перейти к содержанию

Не корректно отображаются цифры на Светодиодном индикаторе


Cegrei Ulanov

Рекомендуемые сообщения

Добрый день, пишу программу термометр на ATmega16, в качестве готового примера взял код с интернета который был написан на ATmega8. Код в протеусе заработал, но после переноса на железо, почему-то Светодиодный индикатор a и b не хотят загораться, когда в протеусе всё хорошо.

На первой картинки, изображены 0008.

Код программы для упрощения, который только отвечает за вывод цифр на Светодиодный индикатор.

/*** Практическое применение термодатчиков DS18B20. Простой термометр ***/
//#define F_CPU 10000000
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

//------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp---minus-blank
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80, 0x40, 0x00};

volatile unsigned char zamer = 0,segcounter = 0;
volatile int display1 = 0, display2 = 0, display3 = 0, display4 = 0;

/*** Прерывание по переполнению T2, динамическая индикация ***/
ISR (TIMER2_OVF_vect)
{
	PORTD = 0xFF;
	PORTB = (1 << segcounter);
	
	switch (segcounter)
	{ //Выводин на экран информацию
		case 0:
		PORTD = ~(SEGMENTE[display1]);
		break;
		case 1:
		PORTD = ~(SEGMENTE[display2]);
		break;
		case 2:
		PORTD = ~((SEGMENTE[display3])|0x80); // добавляем точку
		break;
		case 3:
		PORTD = ~(SEGMENTE[display4]);
		break;
	}
	if ((segcounter++) > 2) segcounter = 0;
}

volatile char temp_flag = 1, Temp_H, Temp_L, OK_Flag;
int main(void)
{
	DDRD = 0xFF;
	DDRB |= (1 << PB0)|(1 << PB1)|(1 << PB2)|(1 << PB3);
	PORTD = 0x00;
	PORTB = 0x00;

	TCCR1B |= (1 << WGM12)|(1 << CS12); // Таймер 1 - отсчёт 1 сек для измерения температуры
	OCR1A  = 2250; // Для отсчёта 1 сек
	TIMSK |= (1 << OCIE1A); // разрешение прерывания по сравнению А таймера 1

	TIMSK |= (1 << TOIE2); // разрешение прерывания по таймеру2
	TCCR2 |= (1 << CS21);  // предделитель на 8
	
	// 	_delay_ms(50);
	
	// 	unsigned int tempint,tempint1,tempint2,tempint3; // переменные для целого значения температуры
	// 	unsigned int temppoint,temppoint1; // переменные для дробного значения температуры

	sei(); // Глобально разрешаем прерывания
	while(1)
	{
		display1 = 0; //tempint1;
		display2 = 0;//tempint2;
		display3 = 0;//tempint3;
		display4 = 8;//temppoint1;
		
	}
	
}

А на втором фото, сам результат. Светодиодный индикатор я подключал по схеме которую предоставил производитель, а также провода всё целы, я их даже менял местами и индикаторы a и b рабочие, только вод микроконтроллер не может их запустить или нет там вообще сигнала. Компилировал я, через программу Atmel Studio 7.0, а записывал на микроконтроллер через программу AVR Studio 4.

Screenshot_99.jpg

Screenshot_100.jpg

Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

Если в протеусе все хорошо, ищите ошибку в монтаже. Только это не "индикаторы", а сегменты - запутаете людей и запутаетесь сами. Еще раз проверьте сегменты (на питание и землю через резистор, или тестером). Проверьте саму макетку. Где-то неконтакт или эти сегменты замыкают.

Настоящему коту и в декабре март!

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

А если перевернуть индикатор? По мне, так вижу 9(8).777 С распайкой сегментов, точно всё нормально?
 

Errare humanum est. Коли людЯм позволено, что же о нас то говорить!
 

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

может для начала заменить магические числа

39 минут назад, Cegrei Ulanov сказал:

//------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp---minus-blank

char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80, 0x40, 0x00};

заменить на более вменяемую запись

#define SEG_A  (1<<0) // назначение сегментов индикатора
#define SEG_B  (1<<1) // соответствующим битам порта LED
#define SEG_C  (1<<2) //      A
#define SEG_D  (1<<3) //   F     B
#define SEG_E  (1<<4) //      G
#define SEG_F  (1<<5) //   E     C
#define SEG_G  (1<<6) //      D     H
#define SEG_H  (1<<7) //

const unsigned char SEGMENTE [15] = {
   (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F), //           ; zero 
   (SEG_B + SEG_C)                                , //           ; one 
   (SEG_A + SEG_B + SEG_D + SEG_E + SEG_G ),        //           ; two 
   (SEG_A + SEG_B + SEG_C + SEG_D + SEG_G),         //           ; three 
   (SEG_B + SEG_C + SEG_F + SEG_G),                 //           ; four 
   (SEG_A + SEG_C + SEG_D + SEG_F + SEG_G),         //           ; five 
   (SEG_A + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G), //           ; six 
   (SEG_A + SEG_B + SEG_C),                         //           ; seven 
   (SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G),//    ; eight 
   (SEG_A + SEG_B + SEG_C + SEG_D + SEG_F + SEG_G), //           ; nine 
  ~(SEG_A + SEG_B + SEG_C + SEG_D + SEG_E + SEG_F + SEG_G),//    ; пусто
   (SEG_A + SEG_F + SEG_E),                         //           ; R
   (SEG_A + SEG_D + SEG_E + SEG_F + SEG_G),                 //     ; E 
   ( SEG_B + SEG_C + SEG_D + SEG_E + SEG_F),    //           ; U
   (SEG_A + SEG_B + SEG_C + SEG_E + SEG_F + SEG_G) //           ; A
   };
*/

дабы не выносить себе и другим мозг

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, IMXO сказал:

дабы не выносить себе и другим мозг

Я только начинающий, и для меня было легче воспринять мой код, ваш код, сложный. Я воспользовался вашим кодом, всё равно не решило проблему. Скорее это в коде ошибка, а где(( Я заменил  Семисегментный индикатор на новый, ошибка прежняя, a и b не загорается. На ножки PD0 которая отвечает за "a" немного тусклее горит светодиод остальных, а на ножки  PD1 которая отвечает за b горит светодиод ярко. Получается сигнал есть.

5 часов назад, KomSoft сказал:

Точка вроде на месте, и по коду на первый взгляд норм. Там пока в цикле тупо записывается 000.8

Я сделал 000.8 статическими специально, чтобы было потом легче настроить  Семисегментный индикатор

6 часов назад, o_l_e_g сказал:

А если перевернуть индикатор? По мне, так вижу 9(8).777 С распайкой сегментов, точно всё нормально?
 

Там всё отлично, на самом деле там должны были быть три нуля и восьмерка 

6 часов назад, KomSoft сказал:

Если в протеусе все хорошо, ищите ошибку в монтаже. Только это не "индикаторы", а сегменты - запутаете людей и запутаетесь сами. Еще раз проверьте сегменты (на питание и землю через резистор, или тестером). Проверьте саму макетку. Где-то неконтакт или эти сегменты замыкают.

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

Изменено пользователем Cegrei Ulanov
Ссылка на комментарий
Поделиться на другие сайты

//Код целеком.
/*** Практическое применение термодатчиков DS18B20. Простой термометр ***/
#include <avr/io.h>        
#include <util/delay.h>
#include <avr/interrupt.h>

#define F_CPU 8000000UL // устанавливаем рабочую частоту контроллера

//------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9----dp---minus-blank                      
char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F, 0x80, 0x40, 0x00};

volatile unsigned char segcounter = 0;
volatile int display1 = 0, display2 = 0, display3 = 0, display4 = 0;

/*** Прерывание по переполнению T2, динамическая индикация ***/
ISR (TIMER2_OVF_vect)
{	
PORTD = 0xFF;
PORTB = (1 << segcounter);
	
switch (segcounter)
{	
case 0:
PORTD = ~(SEGMENTE[display1]);
break;
case 1:
PORTD = ~(SEGMENTE[display2]);
break;	
case 2:
PORTD = ~((SEGMENTE[display3])|0x80); // добавляем точку 
break;		
case 3:
PORTD = ~(SEGMENTE[display4]);
break;		
}
if ((segcounter++) > 2) segcounter = 0;	
}

unsigned char Temp_H = 0,Temp_L = 0,OK_Flag = 0,temp_flag;

/*** Инициализация DS18B20 ***/
unsigned char DS18B20_init(void)
{
PORTC &= ~(1 << PC0); // устанавливаем низкий уровень
DDRC |= (1 << PC0);
_delay_us(490);
DDRC &= ~(1 << PC0);
_delay_us(68);
OK_Flag = (PINC & (1 << PC0)); // ловим импульс присутствия датчика
// если OK_Flag = 0 датчик подключен, OK_Flag = 1 датчик не подключен
_delay_us(422);
return OK_Flag;
}

/*** Функция чтения байта из DS18B20 ***/
unsigned char read_18b20(void)
{
unsigned char i;   
unsigned char dat = 0;
for(i = 0;i < 8;i++) 
{		
DDRC |= (1 << PC0);
_delay_us(2);        
DDRC &= ~(1 << PC0);
_delay_us(4);        
dat = dat >> 1;	    
if(PINC & (1 << PC0))
{			
dat |= 0x80; 
}
_delay_us(62);
}	
return dat;
}

/*** функция записи байта в DS18B20 ***/
void write_18b20(unsigned char dat)
{
unsigned char i;	
for(i = 0;i < 8;i++)
{
DDRC |= (1 << PC0);
_delay_us(2);      		
if(dat & 0x01)
{
DDRC &= ~(1 << PC0);	
}
else
{
DDRC |= (1 << PC0);
}
dat = dat >> 1; 
_delay_us(62); 
DDRC &= ~(1 << PC0);
_delay_us(2); 
}	
}

/*** Главная функция ***/
int main(void)            
{
DDRD = 0xFF;
DDRB |= (1 << PB0)|(1 << PB1)|(1 << PB2)|(1 << PB3);
PORTD = 0x00;
PORTB = 0x00;

TIMSK |= (1 << TOIE2); // разрешение прерывания по таймеру2
TCCR2 |= (1 << CS21);  // предделитель на 8 
    
_delay_ms(50);
	
unsigned int tempint = 0,tempint1,tempint2,tempint3; // переменные для целого значения температуры
unsigned int temppoint = 0,temppoint1; // переменные для дробного значения температуры

sei(); //глобально разрешаем прерывания
	
while(1)
{				    	
if(OK_Flag == 1) // если датчик не ответил
{
// ставим прочерки во всех разрядах
display1 = 11; display2 = 11;
display3 = 11; display4 = 11;
}

DS18B20_init();        // инициализация DS18B20
write_18b20(0xCC);     // проверка кода датчика
write_18b20(0x44);     // запуск температурного преобразования
_delay_ms(1000);
DS18B20_init();        // инициализация DS18B20
write_18b20(0xCC);     // проверка кода датчика
write_18b20(0xBE);     // считываем содержимое ОЗУ
Temp_L = read_18b20(); // читаем первые 2 байта блокнота
Temp_H = read_18b20(); 
temp_flag = 1;         // флаг знака температуры равен 1(плюс)

if(Temp_H &(1 << 3))   // проверяем бит знака температуры на равенство единице 
{			
signed int tmp;
temp_flag = 0;      // флаг знака равен 0(минус)
tmp = (Temp_H << 8) | Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp >> 8; 
}		

tempint = ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
tempint1 = tempint % 1000 / 100;  
tempint2 = tempint % 100 / 10;  
tempint3 = tempint % 10;        
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625;       // точность температуры 
temppoint1 = temppoint / 1000;        
		
if(temp_flag == 0) // если флаг знака температуры равен 0, в первом разряде ставим минус
tempint1 = 11;

if(tempint1 < 1) // если первая цифра значения температуры меньше 1, то гасим 1 разряд индикатора
tempint1 = 12;

if(tempint1 == 12 && tempint2 < 1) // если первая цифра погашена и вторая цифра значения температуры меньше 1, то гасим 2 разряд индикатора
tempint2 = 12;

if(tempint2 < 1 && temp_flag == 0) // если вторая цифра значения температуры меньше 1 и знак равен "минус", то гасим 2 разряд индикатора
tempint2 = 12;

// выводим значения на дисплей
display1 = tempint1;
display2 = tempint2; 
display3 = tempint3;
display4 = temppoint1;
}
}

 

Ссылка на комментарий
Поделиться на другие сайты

Это все хорошо, а макетка? М.б. неконтакт в разьеме. Если есть ослик, посмотрите на выводе мк, если нету - прозвоните ногу мк-ногу индикатора. Там по пути 4 разьемчика и проводок - 5 потенциальных обрывов.

'На ножки PD0 которая отвечает за "a" немного тусклее горит светодиод остальных, а на ножки  PD1 которая отвечает за b горит светодиод ярко. Получается сигнал есть." - Получается есть, но должны светиться с одинаковой яркостью. На что-то соседнее не коротит?

Настоящему коту и в декабре март!

Ссылка на комментарий
Поделиться на другие сайты

5 часов назад, IMXO сказал:

заменить на более вменяемую запись

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

Ссылка на комментарий
Поделиться на другие сайты

Всем спасибо за помощь и советы. Проблема решилась, и как и многие говорили, код был рабочий, проблема была в железе, а именно ножки DDRD 14 и 15 сломались((

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...