CodeVision AVR в вопросах и ответах
- sheva_s
- Грызет канифоль
- Сообщения: 256
- Зарегистрирован: Пт апр 27, 2007 14:32:48
- Откуда: Украина Кривой Рог
- Контактная информация:
Я правильно понял за 1 прерывание зажигаю только один сегмент , при следующем прерывании его тушу и зажигаю следующий сегмент.
Подскажите какую частоту оптимально можно использовать для такого вида динамической индикации что бы небыло заметного мерехтения индикаторов и незагружать микроконтроллер лишними обработками. Какую частоту вы используете ?
Подскажите какую частоту оптимально можно использовать для такого вида динамической индикации что бы небыло заметного мерехтения индикаторов и незагружать микроконтроллер лишними обработками. Какую частоту вы используете ?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
вы поняли верно.
а на счет частоты - все просто: глаз не замечает мерцания примерно с 25 гц. если у вас 3 индикатора по 8 сегментов, то минимальная частота будет 25*8*3=600 гц. можно и больше, если ресурсы позволяют (обычно они позволяют). я выбираю ближайшую бОльшую частоту, которая получается с простыми настройками таймера - например, тупое переполнение.
а на счет частоты - все просто: глаз не замечает мерцания примерно с 25 гц. если у вас 3 индикатора по 8 сегментов, то минимальная частота будет 25*8*3=600 гц. можно и больше, если ресурсы позволяют (обычно они позволяют). я выбираю ближайшую бОльшую частоту, которая получается с простыми настройками таймера - например, тупое переполнение.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
у меня получилось нечаянно
я сделал 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 (опять же например). Это совсем не помешает для любительских поделок - не так ли?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Yellow Tiger
- Сверлит текстолит когтями
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
Я, признаться, был уверен, что слова "посегментный вывод" лишь очепятка, а теперь у меня вопрос - а зачем так выводить? В какой ситуации это понадобилось? Ведь такое управление приведет к значительному снижению воспринимаемой глазом светимости...sheva_s писал(а):Я правильно понял за 1 прерывание зажигаю только один сегмент , при следующем прерывании его тушу и зажигаю следующий сегмент. ... ?
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Yellow Tiger, вы будете смеяться
но при 3-х разрядах при этом имеется существенная экономия... резисторов 
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- sheva_s
- Грызет канифоль
- Сообщения: 256
- Зарегистрирован: Пт апр 27, 2007 14:32:48
- Откуда: Украина Кривой Рог
- Контактная информация:
Покритекуйте код посегментной динамической индикации может что то нужно переделать. По порту В идет управление сегментами индикатора по порту Д управление разрядами индикатора. Частоту обновления дисплея пришлось ставить 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 раза.
- sheva_s
- Грызет канифоль
- Сообщения: 256
- Зарегистрирован: Пт апр 27, 2007 14:32:48
- Откуда: Украина Кривой Рог
- Контактная информация:
Протеусам пользуюсь, программа проверена и отлажена в железе (на макете) просто спрашивал может можно что-то оптимизировать или улучьшить. Выставлял маленькую частоту 18 Гц. на прерывание таймера то все работает как надо, индикация работает посегментно.
А вот что такое дебагер и как ним пользоваться можете подсказать хоть вратце.
А вот что такое дебагер и как ним пользоваться можете подсказать хоть вратце.
- Cat
- Электрический кот
- Сообщения: 1087
- Зарегистрирован: Вт май 05, 2009 10:43:42
- Откуда: Россия
- Контактная информация:
Я сам профан, и не пользуюсь им в силу своей малой просвещенности в области МК. Дебажу выводя разные метки и значения переменных на средства отображения в протеусе или железе. На моем уровне поделок этого более чем достаточно.
(на эту тему есть анекдот: Надпись на стене казармы - "Как ни крути, а баба лучше" )
Настоящий дебаггер позволяет по ходу исполнения кода программы просматривать как меняется содержимое ригистров, и многое другое, если не ошибаюсь. Тоесть позволяет копаться на самом низком уровне, пошагово, или потактово поглядывая что творится с регистрами при исполнении той или иной строчки сишного кода. Если что неверно сказал, поправьте. А вообще, подробно про дебаггеры, JTAG ,и прочее лучше спросите у Желтого Тигры и у ARV, они точно вам расскажут очень толково.
(на эту тему есть анекдот: Надпись на стене казармы - "Как ни крути, а баба лучше" )
Настоящий дебаггер позволяет по ходу исполнения кода программы просматривать как меняется содержимое ригистров, и многое другое, если не ошибаюсь. Тоесть позволяет копаться на самом низком уровне, пошагово, или потактово поглядывая что творится с регистрами при исполнении той или иной строчки сишного кода. Если что неверно сказал, поправьте. А вообще, подробно про дебаггеры, JTAG ,и прочее лучше спросите у Желтого Тигры и у ARV, они точно вам расскажут очень толково.
Боевой ватник.
- Yellow Tiger
- Сверлит текстолит когтями
- Сообщения: 1148
- Зарегистрирован: Вт июл 08, 2008 12:24:17
- Yellow Tiger
- Сверлит текстолит когтями
- Сообщения: 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;И последнее - у тебя и активные сегменты, и активные знакоместа выдаются в порт единичками; а раз ты экономишь место на плате и энергопотребление, значит ключевые транзисторы не предполагаются, так? Тогда нужно выдавать не единички, а нули либо в сегменты, либо в знакоместа.
Добрый день! Помогите разобраться с внешним прерывание...
как его описать?
и можно ли вот это прерывание переделать под 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[i];
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[i];
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???
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 подобным способом описать эти команды, ну или какие могут быть еще решения...?????????????