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

Динамическая Индикация


a_sergeevich

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

Про динамическую индикацию в принципе всё ясно, есть такой код:

#define _pic16f877	// зададим тип процессора
#include <pic.h>	// подключим файл описаний

__CONFIG(LVPDIS & UNPROTECT & PWRTDIS & WDTDIS & XT);

// таблица знакогенератора
const unsigned char CODE_TABLE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};	

unsigned char buffer[9]={1,2,3,4,5,6,7,8,9};	// буфер индикатора
unsigned char PTR;	// указатель буфера

void	main(void)
{

// настроим порты на выход
TRISB = 0b11110000;	// для дешифратора знакомест (4 младших разряда)
TRISD = 0b00000000;	// для символа

PORTD = 0;		// очистим индикатор
PTR = 0;		// начало буфера
PORTB = 0b00001111;	// установим последний разряд индикатора

OPTION = 0b10000010;	// запишем байт настройки в регистр OPTION
INTCON = 0;		// Выключить все прерывания и сбросить T0IF
TMR0 = 0;		// Сброс TMR0

T0IE = 1;		// Разрешить прерывания от TMR0
GIE = 1;		// Разрешить все прерывания


// зациклим программу
cycle:;
goto cycle;


}

// обработка прерываний
void interrupt all(void)
{

PORTD = 0;	// очистим индикатор
PORTB++;	// установим следующее знакоместо для отображения
PORTD = CODE_TABLE[buffer[PTR]];	// выведем на индикатор
PTR++;		// установим указатель на следующий символ

if(PTR == 10) { PTR = 0; PORTB = 0b00001111; } //проверим, не кончился ли массив для вывода на индикатор

T0IF = 0;	// сбросим флаг прерывания
}

Проблема в следующем,как мне вывести на 9-ти разрядный (АЛС318) не 9-ть цифр,допустим 16-ть?

Я пытался сделать это так:

unsigned char buffer[16]={1,2,3,4,5,6,7,8,9,8,7,6,5,4,3,2}; расширяю буфер

В обработчике прерывания делаю так:

if(PTR==10) {PORTB = 0b00001111;}

if(PTR==16) {PTR=0;PORTB = 0b00001111;}

И у меня одни значения накладываются на другие и получается полная ерунда.

Понимаю, что надо как-то организовать небольшую паузу между показами первой части и второй,но не могу догнать как.

Прошу помощи.

Пока буду до вечера ещё думать, может, что и придёт в голову.

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

Компилятор используемый мной для этого примера HITECH-PICC.

Дешифратор 74145

МК PIC16F877A

Будьте проще и люди к вам потянутся.

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

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

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

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

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

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

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

Есть девять индикаторов. Есть допустим 16 чисел в массиве(1,2,3,4,5,6,7,8,9,0,9,8,7,6,5,4)

Сначала выводятся первые девять цифр,затем остальные семь и далее все заново.

Например, ситуация надо вывести число 1234567890987654 на индикатор АЛС318, сначала мы его разобъём на отдельные числа, а потом надо его вывести вот тут-то и пригодиться такой вывод по частям.

Вот у меня и проблема возникла с этим проблема, т.к вывести первые 9-ть чисел не проблема, а вот как доходит до остальных 7-ми тут затык и начинается.Сейчас почитал тут в инете статейку про дин.индикацию, кое-какие мысли появились, но пробовать сегодня уже не буду,завтра вечерком наверное займусь.

Но все же от помощи не откажусь :)

Будьте проще и люди к вам потянутся.

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

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

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

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

По частям - значит с паузой?

Так причем тут динамическая индикация? Динамикой можно выводить что угодно, хоть с паузой, хоть без. Просто это будет два независимых процесса. Один создает последовательное с паузой заполнение регистра вывода(буфера), а второй и будет собственно дин. индикацией - т.е. непрерывным выводом буфера на АЛС.

戦う前に相手のベルトの色に注目

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

my504

Спасибо за ответ, теперь я понял свою ошибку, впринципе на радиокоте тоже самое посоветовали.

Будьте проще и люди к вам потянутся.

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

И так пережевав все советы, вот, что у меня получилось, сразу оговорюсь, на задержку в цикле не обращайте внимание, такая нужна для протеуса, что бы не мелькало :), да и индикатор 8-ми разрядный т.к 9-ти в протеусе нету.

#define _pic16f877
#define  buf_size 20
#include <pic.h>

__CONFIG (LVPDIS & UNPROTECT & PWRTDIS & WDTDIS & XT);

const unsigned char CODE_TABLE[10] = 
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f
};

unsigned char buffer[buf_size];
unsigned char buffer2[buf_size]={1,2,3,4,5,6,7,8,9,4,5,3,6,2,1,0,3,4,5,7
};
unsigned char PTR;
unsigned int i = 0, j=0, z;
int s=0;

void main (void) 
{


TRISB = 0b11110000;
TRISD = 0b00000000;
PORTD = 0;
PTR = 0;
PORTB = 0b00001111;
OPTION = 0b10000010;
INTCON = 0;
TMR0 = 0;
T0IE = 1;
GIE = 1;

while (1)
{
	for(i=0;i<=9;i++)
	{
		buffer[i] = buffer2[j];

		j++;

		if (j==buf_size+1) { s= -1; break;
		}
	}

	s=s+1;
	j=s;







	for(z=0; z<=30000; z++);
}
}


void interrupt all (void)
{
	PORTD = 0;
	PORTB++;
	PORTD = CODE_TABLE[buffer[PTR]];
	PTR++;

	if(PTR==9) {PTR = 0; PORTB = 0b00001111;
	}
	T0IF = 0;
}

Всё работает, единственное не хочет отображать последнюю цифру, никак не пойму почему.

Будьте проще и люди к вам потянутся.

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

  • 1 год спустя...

научите мнея динамическои индикации, ну никак не поиму , что сделать надо?

	# include <pic.h>
# include "delay.h"
__CONFIG ( XT & WDTDIS & PWRTEN & BOREN & LVPDIS & DUNPROT & WRTEN & DEBUGDIS & UNPROTECT ) ;
# define 		_XTAL_FREQ 4000000  // Определить частоту МК
# define 		bitset(var, bitno) ((var) |= 1UL << (bitno))
# define 		bitclr(var, bitno) ((var) &= ~(1UL << (bitno)))
// ОПРЕДЕЛИТЬ ПИНЫ
# define 	KNOP	RA0
# define 	DQ		RA2
// ПРОТОТИПЫ
	unsigned char DS1821_reset( void ) ;	
// ПЕРЕМЕННЫЕ
bit nado_s ; 
unsigned char count, sec, bufer;
static volatile near unsigned int    TMR1        @ 0x00E;		                                          // E
unsigned char led7seg[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F ,0x78}; 
unsigned char buffer[4]={1,2,3,4};    // буфер индикатора
unsigned char PTR;      // указатель буфера


void main ( void )
{
unsigned char i ,digit;
OPTION = 1 ;		// Подтяжка вкл
TRISA = 1 ;		// Вход
TRISB = 1 ;		// 7 сег дисплай

ADCON1 = 0b00000111 ; // ПортА цифровои
CMCON =  0b00000111 ; // Компаратор выкл
//Инициализация прерываний от TMR1 пред 1:1,
//Internal clock (FOSC/4), генератор офф

TMR1 = 65535 - 10000;   // Таймер на 10000 циклов
TMR1ON = 1 ;                    // Вкл. TMR1
TMR1IE = 1 ;                    // Разрешить  прерывание от TMR1
PEIE = 1 ;      // Разрешить все прерывания от периферийных устройств
GIE =  0	;	// Запрет прерывания на время измерения температуры

i = DS1821_reset();
if ( i = 0 )	// Если ошибка на шине, показать " Е1"
{
	GIE =1 ;  // Прерывания
	sec = 100; nado_s = 1; // в течение 10 сек
	bufer = 



}
}

//Сброс DS1821///////////////////////////
unsigned char DS1821_reset ()
{
unsigned char D_Presence ;
DQ = 0 ; DelayUs(500) ; // Импульс сброса
TRISA = 0b00000010;	  // RA2 на вход
DelayUs(60);			  // задержка для восстановленния высокого уровня
	 D_Presence = DQ;  // C порта в переменную
	if (D_Presence)  	
		{ DelayUs(500); return 0;} // Если ошибка
	else { DelayUs(500); return 1;} // Все нормально
}
// INTERRUPT//////////////////////////////
void interrupt isr (void)
{
static unsigned char ind_num=0;	// Номер индикатора


if(TMR1IF)	// Проверяем флаг
{
	TMR1IF=0;	// Сбрасываем флаг
	TMR1 = 65537 - 10000 ; 

	if (nado_s)
	{ --sec;
	  	 if (sec = 0)
	 		{ nado_s = 0 ;}
	}


	ind_num++;	// Следующий индикатор
	if(ind_num>3)	ind_num=0;	// Если зашкалило, выбираем первый

	PORTD &=0b11110000;	// Гасим индикаторы
	NOP();NOP();NOP();NOP();NOP();	// Небольшая задержка
	PORTC = led7seg[bufer];
	PORTD |=(1<<ind_num);			// Зажигаем текущий индикатор


}
}

хочу вначале отобразить, если не обнаружен датчик, то E1 на индикаторе. Индикатор подключен к PORTB , a катоды к D , 4 разряда.

Не цитируите полностью предыдущее сообщение!!!

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

Вы попробуйте сначала хоть что-нибудь отобразить, число например, а потом уже и до DS доберётесь. Есть проблемки у начинающих с прикручиванием DS-ок и дин. индикации, но до этого потом дойдёте.

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

Оставил только свои комментарии

// INTERRUPT//////////////////////////////
void interrupt isr (void)
{
static unsigned char ind_num=0;


   	if(TMR1IF)  /*Мы уже в прерывании зачем проверка*/
   	{
           	TMR1IF=0;      
           	TMR1 = 65537 - 10000 ; 

           	if (nado_s)     				//не понял
           	{ --sec; 					//хода Вашей 
  				if (sec = 0)   		//мысли
               	{ nado_s = 0 ;}           //зачем?
           	}


           	ind_num++;	
           	if(ind_num>3)   ind_num=0; 	

           	PORTD &=0b11110000;    
           	NOP();NOP();NOP();NOP();NOP();  
           	PORTC = led7seg[bufer]; //PORTC = led7seg[bufer[ind_num]];/вот так лучше будет
           	PORTD |=(1<<ind_num);	


   	}
}

Изменено пользователем rtfcnf

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

ну это так то впринципе понятно, а что на этом участке делать?

	i = DS1821_reset();
if ( i = 0 )	// Если ошибка на шине, показать " Е1"
{
	GIE =1 ;  // Прерывания
	sec = 100; nado_s = 1; // в течение 10 сек
	bufer = 



}

Не цитируите полностью предыдущее сообщение!!!

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

Насколько я понимаю это Ваш знакогенератор (или не Ваш?)

unsigned char led7seg[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F ,0x78}; 

он хранит символы для вывода на 7-сегметный индикатор

Добавите одиннадцатый символ "пробел" - записать его в массив как 0X00 и добавите двенадцатый символ "E" - схему не вижу, как записать его не скажу поэтому.

unsigned char led7seg[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F ,0x78, 0x00, 0xXX}; 

В коде для вывода "E1" надо написать так:

        i = DS1821_reset();
       if ( i = 0 )    // Если ошибка на шине, показать " Е1"
       {
               GIE =1 ;  // Прерывания
               sec = 100; nado_s = 1; // в течение 10 сек

               bufer[0] = 10;
               bufer[1] = 11;
               bufer[2] = 1;
               bufer[3] = 10;
       }

Это сообщение поставляется "как есть", без каких либо гарантий. Автор сообщения не несёт какой либо ответственности

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

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

  • 4 месяца спустя...

#define _pic16f877      // зададим тип процессора
#include <pic.h>        // подключим файл описаний

__CONFIG(LVPDIS & UNPROTECT & PWRTDIS & WDTDIS & XT);

// таблица знакогенератора
const unsigned char CODE_TABLE[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};       

unsigned char buffer[9]={1,2,3,4,5,6,7,8,9};    // буфер индикатора
unsigned char PTR;      // указатель буфера

void    main(void)
{

       // настроим порты на выход
       TRISB = 0b11110000;     // для дешифратора знакомест (4 младших разряда)
       TRISD = 0b00000000;     // для символа

       PORTD = 0;              // очистим индикатор
       PTR = 0;                // начало буфера
       PORTB = 0b00001111;     // установим последний разряд индикатора

       OPTION = 0b10000010;    // запишем байт настройки в регистр OPTION
       INTCON = 0;             // Выключить все прерывания и сбросить T0IF
       TMR0 = 0;               // Сброс TMR0

       T0IE = 1;               // Разрешить прерывания от TMR0
       GIE = 1;                // Разрешить все прерывания


       // зациклим программу
cycle:;
       goto cycle;


}

// обработка прерываний
void interrupt all(void)
{

       PORTD = 0;      // очистим индикатор
       PORTB++;        // установим следующее знакоместо для отображения
       PORTD = CODE_TABLE[buffer[PTR]];        // выведем на индикатор
       PTR++;          // установим указатель на следующий символ

       if(PTR == 10) { PTR = 0; PORTB = 0b00001111; } //проверим, не кончился ли массив для вывода на индикатор

       T0IF = 0;       // сбросим флаг прерывания
}

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

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

Оставил только свои комментарии

....
   	if(TMR1IF)  /*Мы уже в прерывании зачем проверка*/

правильней так:

if (T0IE&&T0IF)
  {
.....
  } 

если обрабатывается несколько прерываний то проверка T0IF сокращает пребывание в обработчике

проверка T0IE нужна в случае если в основной проге запретили прерывание по таймеру

прога свалится в обработчик и все равно обработает T0IF что нарушит работу проги

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

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

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

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

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

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

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

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

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

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

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