Подскажите какую частоту оптимально можно использовать для такого вида динамической индикации что бы небыло заметного мерехтения индикаторов и незагружать микроконтроллер лишними обработками. Какую частоту вы используете ?
CodeVision AVR в вопросах и ответах
Я правильно понял за 1 прерывание зажигаю только один сегмент , при следующем прерывании его тушу и зажигаю следующий сегмент.
Подскажите какую частоту оптимально можно использовать для такого вида динамической индикации что бы небыло заметного мерехтения индикаторов и незагружать микроконтроллер лишними обработками. Какую частоту вы используете ?
Подскажите какую частоту оптимально можно использовать для такого вида динамической индикации что бы небыло заметного мерехтения индикаторов и незагружать микроконтроллер лишними обработками. Какую частоту вы используете ?
- Реклама
вы поняли верно.
а на счет частоты - все просто: глаз не замечает мерцания примерно с 25 гц. если у вас 3 индикатора по 8 сегментов, то минимальная частота будет 25*8*3=600 гц. можно и больше, если ресурсы позволяют (обычно они позволяют). я выбираю ближайшую бОльшую частоту, которая получается с простыми настройками таймера - например, тупое переполнение.
а на счет частоты - все просто: глаз не замечает мерцания примерно с 25 гц. если у вас 3 индикатора по 8 сегментов, то минимальная частота будет 25*8*3=600 гц. можно и больше, если ресурсы позволяют (обычно они позволяют). я выбираю ближайшую бОльшую частоту, которая получается с простыми настройками таймера - например, тупое переполнение.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Мне интересен ваш код по приему RC5, насколько мне известно, RC5-6-7-8 это бифазный код, там надо оценивать не только паузы, но и предыдущее состояние линии. Как вы совместили все во одном коде? Я бы для каждого стандарта писал свой код 
Боевой ватник.
у меня получилось нечаянно 
я сделал RC5 по алгоритму, описанному во многих источниках. да, анализ предыдущего состояния и т.п. но при проверке оказалось, что из 5-и пультов, которые у меня дома есть, только от магнитолы PHILIPS передает в стандарте RC5, а остальные - нет. поначалу мне казалось, что мой алгоритм при приеме не-RC кодов работает неверно, но потом я увидел закономерность и подправил алгоритм: если принимать не 14 бит (как положено для RC5), а 32, то по этому алгоритму прекрасно принимаются коды от ВСЕХ моих пультов (техника Samsung, LG, BBK и Toshiba). В начале каждого кода четко прослеживаются биты семейства, затем toggle-бит (если он есть), затем код команды и т.п. Единственный нюанс: коды эти не совпадают с документированными, то есть если в документации написано, что "Volume+" должна иметь код 0x10720432 (например), то мой алгоритм показывает 0xAe004323 (опять же например). Это совсем не помешает для любительских поделок - не так ли?
я сделал RC5 по алгоритму, описанному во многих источниках. да, анализ предыдущего состояния и т.п. но при проверке оказалось, что из 5-и пультов, которые у меня дома есть, только от магнитолы PHILIPS передает в стандарте RC5, а остальные - нет. поначалу мне казалось, что мой алгоритм при приеме не-RC кодов работает неверно, но потом я увидел закономерность и подправил алгоритм: если принимать не 14 бит (как положено для RC5), а 32, то по этому алгоритму прекрасно принимаются коды от ВСЕХ моих пультов (техника Samsung, LG, BBK и Toshiba). В начале каждого кода четко прослеживаются биты семейства, затем toggle-бит (если он есть), затем код команды и т.п. Единственный нюанс: коды эти не совпадают с документированными, то есть если в документации написано, что "Volume+" должна иметь код 0x10720432 (например), то мой алгоритм показывает 0xAe004323 (опять же например). Это совсем не помешает для любительских поделок - не так ли?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
Я, признаться, был уверен, что слова "посегментный вывод" лишь очепятка, а теперь у меня вопрос - а зачем так выводить? В какой ситуации это понадобилось? Ведь такое управление приведет к значительному снижению воспринимаемой глазом светимости...sheva_s писал(а):Я правильно понял за 1 прерывание зажигаю только один сегмент , при следующем прерывании его тушу и зажигаю следующий сегмент. ... ?
- Реклама
Yellow Tiger, вы будете смеяться
но при 3-х разрядах при этом имеется существенная экономия... резисторов 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Дело не в экономии денег, а в экономии места на плате, конструкцию хочу сделать маленькой и избавиться от ненужных резисторов и транзисторов которые нужно ставить на управление разрядами, да и разобраться с этим видом индикации хочется. Плюс снизить энергопотребление устройства.
Без транзисторов сложновато. Не забывайте что по крайней мере в мегах идет ограничение по току вывода 20 мА, но не более 80мА на порт. Есть садисты, подключающие сегменты напрямую к выводам. Но в надежности работы такого решения возникают сомнения.
Боевой ватник.
Покритекуйте код посегментной динамической индикации может что то нужно переделать. По порту В идет управление сегментами индикатора по порту Д управление разрядами индикатора. Частоту обновления дисплея пришлось ставить 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 сегментов значит переходим на вывод новой цифры
};
Последний раз редактировалось sheva_s Ср май 20, 2009 23:37:07, всего редактировалось 3 раза.
Вы протеусом пользуетесь? Можно смоделировать в нем, только частоту контроллеру задать всего несколько килогерц и понаблюдать в сильном замедлении что происходит. Так легче баги вылавливать если не умеете пользоватсяся дебаггерами.
Боевой ватник.
Протеусам пользуюсь, программа проверена и отлажена в железе (на макете) просто спрашивал может можно что-то оптимизировать или улучьшить. Выставлял маленькую частоту 18 Гц. на прерывание таймера то все работает как надо, индикация работает посегментно.
А вот что такое дебагер и как ним пользоваться можете подсказать хоть вратце.
А вот что такое дебагер и как ним пользоваться можете подсказать хоть вратце.
Я сам профан, и не пользуюсь им в силу своей малой просвещенности в области МК. Дебажу выводя разные метки и значения переменных на средства отображения в протеусе или железе. На моем уровне поделок этого более чем достаточно.
(на эту тему есть анекдот: Надпись на стене казармы - "Как ни крути, а баба лучше" )
Настоящий дебаггер позволяет по ходу исполнения кода программы просматривать как меняется содержимое ригистров, и многое другое, если не ошибаюсь. Тоесть позволяет копаться на самом низком уровне, пошагово, или потактово поглядывая что творится с регистрами при исполнении той или иной строчки сишного кода. Если что неверно сказал, поправьте. А вообще, подробно про дебаггеры, JTAG ,и прочее лучше спросите у Желтого Тигры и у ARV, они точно вам расскажут очень толково.
(на эту тему есть анекдот: Надпись на стене казармы - "Как ни крути, а баба лучше" )
Настоящий дебаггер позволяет по ходу исполнения кода программы просматривать как меняется содержимое ригистров, и многое другое, если не ошибаюсь. Тоесть позволяет копаться на самом низком уровне, пошагово, или потактово поглядывая что творится с регистрами при исполнении той или иной строчки сишного кода. Если что неверно сказал, поправьте. А вообще, подробно про дебаггеры, JTAG ,и прочее лучше спросите у Желтого Тигры и у ARV, они точно вам расскажут очень толково.
Боевой ватник.
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
Я бы вместо трех цифр ("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;- Сообщения: 12
- Зарегистрирован: Ср май 13, 2009 20:34:56
Добрый день! Помогите разобраться с внешним прерывание...
как его описать?
и можно ли вот это прерывание переделать под 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;
как его описать?
и можно ли вот это прерывание переделать под 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;
Спасибо за советы, последнее я упустил просто у меня макетка собрана, а там стоят транзисторы на управление разрядами вот из - за этого и получилось так в программе.Yellow Tiger писал(а): И последнее - у тебя и активные сегменты...
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
Я что-то подобное и предполагал.sheva_s писал(а):просто у меня макетка собрана, а там стоят транзисторы на управление
В CV Avr есть мастер кода - отметить там нужные прерывания, и он сам рыбу нарисует.Tahasp писал(а):Помогите разобраться с внешним прерыванием... как его описать? и можно ли ... переделать под CV AVR???
- Сообщения: 12
- Зарегистрирован: Ср май 13, 2009 20:34:56
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 подобным способом описать эти команды, ну или какие могут быть еще решения...?????????????
Спасибо, с этим я уже и без этого разобрался...
возник другой вопрос, но с начала в чем суть, я пытаюсь переделать программу из 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 подобным способом описать эти команды, ну или какие могут быть еще решения...?????????????
Абсодютно в таком же виде и описать, через #define. Только в синтаксисе CVAVRа нужно писать #asm("sei"), а не asm("sei"), как здесь - и все.
Оптимизм х (Опыт + Знания) = const


