Страница 43 из 421

Добавлено: Вт май 19, 2009 11:16:47
sheva_s
Я правильно понял за 1 прерывание зажигаю только один сегмент , при следующем прерывании его тушу и зажигаю следующий сегмент.
Подскажите какую частоту оптимально можно использовать для такого вида динамической индикации что бы небыло заметного мерехтения индикаторов и незагружать микроконтроллер лишними обработками. Какую частоту вы используете ?

Добавлено: Вт май 19, 2009 11:23:12
ARV
вы поняли верно.
а на счет частоты - все просто: глаз не замечает мерцания примерно с 25 гц. если у вас 3 индикатора по 8 сегментов, то минимальная частота будет 25*8*3=600 гц. можно и больше, если ресурсы позволяют (обычно они позволяют). я выбираю ближайшую бОльшую частоту, которая получается с простыми настройками таймера - например, тупое переполнение.

Добавлено: Вт май 19, 2009 17:43:00
Cat
Мне интересен ваш код по приему RC5, насколько мне известно, RC5-6-7-8 это бифазный код, там надо оценивать не только паузы, но и предыдущее состояние линии. Как вы совместили все во одном коде? Я бы для каждого стандарта писал свой код :oops:

Добавлено: Вт май 19, 2009 17:58:04
ARV
у меня получилось нечаянно :)

я сделал RC5 по алгоритму, описанному во многих источниках. да, анализ предыдущего состояния и т.п. но при проверке оказалось, что из 5-и пультов, которые у меня дома есть, только от магнитолы PHILIPS передает в стандарте RC5, а остальные - нет. поначалу мне казалось, что мой алгоритм при приеме не-RC кодов работает неверно, но потом я увидел закономерность и подправил алгоритм: если принимать не 14 бит (как положено для RC5), а 32, то по этому алгоритму прекрасно принимаются коды от ВСЕХ моих пультов (техника Samsung, LG, BBK и Toshiba). В начале каждого кода четко прослеживаются биты семейства, затем toggle-бит (если он есть), затем код команды и т.п. Единственный нюанс: коды эти не совпадают с документированными, то есть если в документации написано, что "Volume+" должна иметь код 0x10720432 (например), то мой алгоритм показывает 0xAe004323 (опять же например). Это совсем не помешает для любительских поделок - не так ли?

Добавлено: Вт май 19, 2009 18:48:51
Yellow Tiger
sheva_s писал(а):Я правильно понял за 1 прерывание зажигаю только один сегмент , при следующем прерывании его тушу и зажигаю следующий сегмент. ... ?
Я, признаться, был уверен, что слова "посегментный вывод" лишь очепятка, а теперь у меня вопрос - а зачем так выводить? В какой ситуации это понадобилось? Ведь такое управление приведет к значительному снижению воспринимаемой глазом светимости... :?

Добавлено: Вт май 19, 2009 18:56:40
ARV
Yellow Tiger, вы будете смеяться :))) но при 3-х разрядах при этом имеется существенная экономия... резисторов :)))

Добавлено: Вт май 19, 2009 22:00:24
sheva_s
Дело не в экономии денег, а в экономии места на плате, конструкцию хочу сделать маленькой и избавиться от ненужных резисторов и транзисторов которые нужно ставить на управление разрядами, да и разобраться с этим видом индикации хочется. Плюс снизить энергопотребление устройства.

Добавлено: Вт май 19, 2009 22:13:23
Cat
Без транзисторов сложновато. Не забывайте что по крайней мере в мегах идет ограничение по току вывода 20 мА, но не более 80мА на порт. Есть садисты, подключающие сегменты напрямую к выводам. Но в надежности работы такого решения возникают сомнения.

Добавлено: Ср май 20, 2009 16:19:48
sheva_s
Покритекуйте код посегментной динамической индикации может что то нужно переделать. По порту В идет управление сегментами индикатора по порту Д управление разрядами индикатора. Частоту обновления дисплея пришлось ставить 3,2 кГц, при 2400 видно немного мерехтение хотя нужно попробывать увеличить ток через сегмент может станет лучше.

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

int  k;   // служебная пер. для включения нужного разряда на индикаторе.
int a=0b00000001;    // масска для вывода на экран семента
int B,C,D;                       //  храняться числа для вывода на экран    
int V;                              // переменная вывода которая непосредственно выводиться  в данный разряд

int digit[15]={          0b00111111,               // 0
                           0b00000110,               // 1
                           0b01011011,               // 2
                           0b01001111,               // 3
                           0b01100110,               // 4
                           0b01101101,               // 5
                           0b01111101,               // 6
                           0b00000111,               // 7
                           0b01111111,               // 8
                           0b01101111,               // 9
                           0b10000000,               // ,
                           0b00000000,               // пусто  
                           0b00111110,               // U
                           0b01000000,               // -      
                           0b01110111                // A
                                            };    // масив цифр

// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Reinitialize Timer 0 value

 TCCR0 = 0x00; //stop
 TCNT0 = 0xED; //set count  3200
 TCCR0 = 0x03; //start timer

// Place your code here
 PORTB=0;   
  
 if (k==3) k=0; 
 if (k==0)    {PORTD=0b00100000; V=B;}; //управление разрядом
 if (k==1)    {PORTD=0b01000000; V=C;};
 if (k==2)    {PORTD=0b10000000; V=D;};  
 
 PORTB=digit[V]&a;  // зажигаем сегмент по маске 
 a=a<<1;                  // смешаем маску
 if (a==0b00000000) {a=0b00000001;  k++;}; // проверяем зажгли 8 сегментов  значит переходим на вывод новой цифры
                     
    }; 

Добавлено: Ср май 20, 2009 16:59:34
Cat
Вы протеусом пользуетесь? Можно смоделировать в нем, только частоту контроллеру задать всего несколько килогерц и понаблюдать в сильном замедлении что происходит. Так легче баги вылавливать если не умеете пользоватсяся дебаггерами.

Добавлено: Ср май 20, 2009 20:31:14
sheva_s
Протеусам пользуюсь, программа проверена и отлажена в железе (на макете) просто спрашивал может можно что-то оптимизировать или улучьшить. Выставлял маленькую частоту 18 Гц. на прерывание таймера то все работает как надо, индикация работает посегментно.
А вот что такое дебагер и как ним пользоваться можете подсказать хоть вратце.

Добавлено: Ср май 20, 2009 20:58:18
Cat
Я сам профан, и не пользуюсь им в силу своей малой просвещенности в области МК. Дебажу выводя разные метки и значения переменных на средства отображения в протеусе или железе. На моем уровне поделок этого более чем достаточно.

(на эту тему есть анекдот: Надпись на стене казармы - "Как ни крути, а баба лучше" ) :)))

Настоящий дебаггер позволяет по ходу исполнения кода программы просматривать как меняется содержимое ригистров, и многое другое, если не ошибаюсь. Тоесть позволяет копаться на самом низком уровне, пошагово, или потактово поглядывая что творится с регистрами при исполнении той или иной строчки сишного кода. Если что неверно сказал, поправьте. А вообще, подробно про дебаггеры, JTAG ,и прочее лучше спросите у Желтого Тигры и у ARV, они точно вам расскажут очень толково.

Добавлено: Ср май 20, 2009 22:52:41
Yellow Tiger
sheva_s писал(а):Покритекуйте код ...
Может я в полночь не соображаю уже ничего, но что-то я не нашел в коде объявлений переменных, используемых во фрагменте кода. Как понимать всякие V,B,C,D,a - ???
Лучше все-таки выкладывать весь код, иначе могут быть накладки...

Добавлено: Ср май 20, 2009 23:35:38
sheva_s
Исправил выложенный ранее код.

Добавлено: Сб май 23, 2009 20:11:09
Yellow Tiger
Я бы вместо трех цифр ("int B,C,D;") держал массив "unsigned char display[3]" и обращался к цифре не копированием её в переменную V, а просто по индексу; и константы для активации знакоместа тоже загнать в массив размером с ширину дисплея, например: "unsigned char RunningGnd[3];". Переменную V вообще можно убрать.
Тогда вот этот участок кода:

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

if (k==0)    {PORTD=0b00100000; V=B;}; //управление разрядом
if (k==1)    {PORTD=0b01000000; V=C;};
if (k==2)    {PORTD=0b10000000; V=D;};
выглядел бы так:

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

PORTD=RunningGnd[k];  //управление разрядом
а выдача сегмента в порт так:

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

PORTB=digit[display[k]]&a;
И последнее - у тебя и активные сегменты, и активные знакоместа выдаются в порт единичками; а раз ты экономишь место на плате и энергопотребление, значит ключевые транзисторы не предполагаются, так? Тогда нужно выдавать не единички, а нули либо в сегменты, либо в знакоместа.

Добавлено: Вс май 24, 2009 11:42:57
Tahasp
Добрый день! Помогите разобраться с внешним прерывание...
как его описать?
и можно ли вот это прерывание переделать под CV AVR???

// прерывание таймер0, 20килогерц
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
GICR = 0xC0;//разрешили прерывания INT0, INT1;
TCNT0 = 0xA4;// обновили счетчик

PORTD=(PORTD & 0b00001111) | steps;

if (sleep_ctr) sleep_ctr--;
}



#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
// прерывание INT0
GICR&=0b10111111;
PORTD&=0b11001111;
}

#pragma interrupt_handler int1_isr:3
void int1_isr(void)
{
// прерывание INT1
GICR&=0b01111111;
PORTD&=0b00111111;

Добавлено: Вс май 24, 2009 16:50:21
sheva_s
Yellow Tiger писал(а): И последнее - у тебя и активные сегменты...
Спасибо за советы, последнее я упустил просто у меня макетка собрана, а там стоят транзисторы на управление разрядами вот из - за этого и получилось так в программе.

Добавлено: Вс май 24, 2009 17:13:11
Yellow Tiger
sheva_s писал(а):просто у меня макетка собрана, а там стоят транзисторы на управление
Я что-то подобное и предполагал. :)
Tahasp писал(а):Помогите разобраться с внешним прерыванием... как его описать? и можно ли ... переделать под CV AVR???
В CV Avr есть мастер кода - отметить там нужные прерывания, и он сам рыбу нарисует.

Добавлено: Вс май 24, 2009 18:28:20
Tahasp
Yellow Tiger
Спасибо, с этим я уже и без этого разобрался...



возник другой вопрос, но с начала в чем суть, я пытаюсь переделать программу из ICCV7 в CV AVR...
так вот, вопрос в том что CV AVR не обрабатывает вот эту часть кода:
//////////////////////////////////////////////////////////////////////////////////////////////
void init_devices(void)
{
//stop errant interrupts until set up

CLI(); //disable all interrupts

port_init();
timer0_init();


MCUCR = 0x00;//INT0 INT1 - по низкому!!!(чтобы не пропустить прерывание) уровню
GICR = 0xC0;
TIMSK = 0x01; //timer interrupt sources
//TIMSK = 0xC0; //timer interrupt sources

SEI(); //re-enable interrupts
//all peripherals are now initialized
}
/////////////////////////////////////////////////////////////////////////////////////

из-за ассемблировских команд CLI и SEI, в ICCV7 работа этих команд рассписана в отдельном макросе:

///////////////////////////////////////////////////////////////////////////

#define _asm asm /* old style */

#define WDR() asm("wdr")
#define SEI() asm("sei")
#define CLI() asm("cli")
#define NOP() asm("nop")
#define _WDR() asm("wdr")
#define _SEI() asm("sei")
#define _CLI() asm("cli")
#define _NOP() asm("nop")
///////////////////////////////////////////////////////////////////////////////////////

а нельзя ли в CV AVR подобным способом описать эти команды, ну или какие могут быть еще решения...?????????????

Добавлено: Вс май 24, 2009 23:04:36
Aheir
Абсодютно в таком же виде и описать, через #define. Только в синтаксисе CVAVRа нужно писать #asm("sei"), а не asm("sei"), как здесь - и все.