ARV писал(а): во-вторых, что ж это у вас за динамическая индикация такая?! с делениями в прерываниях?! это же, мягко говоря, очень долго! Скажите так небудет долго? или нужно ещо дорабатывать? Функция setcsr() вызывается в основном цыкле когда установлен флаг что время прочитано и флаг сбрасывается. Время читается каждую секунду по прерыванию INT0 от RTC.
Code:
char hour, min, sec; // текущее время
char scr[6]; // экран
........................
void setscr (char a, char b, char c)
{
scr[0]=a/10; scr[1]=a%10; scr[2]=b/10; scr[3]=b%10; scr[4]=c/10; scr[5]=c%10;
flscr=0; // сброс флага, что время прочиталось
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
if ((alarm==1)&&(blink==1)) saund=~saund; // звуковой сигнал
else saund=0;
anod_1=0; anod_2=0; anod_3=0; anod_4=0; anod_5=0; anod_6=0; // выключить аноды
tochka=0; // погасить точку
}
// Timer 2 output compare interrupt service routine
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
switch (fleg)
{
case 0: setcifra (scr[fleg]);
if ((fl!=1)&&(alarm!=1)) anod_1=1; // если ненужно мигать, то горит
else if (blink==0) anod_1=1; // мигает
break;
case 1: setcifra (scr[fleg]);
if ((fl!=1)&&(alarm!=1)) anod_2=1;
else if (blink==0) anod_2=1;
break;
case 2: setcifra (scr[fleg]);
if ((fl!=2)&&(alarm!=1)) anod_3=1;
else if (blink==0) anod_3=1;
break;
case 3: setcifra (scr[fleg]);
if ((fl!=2)&&(alarm!=1)) anod_4=1;
else if (blink==0) anod_4=1;
break;
case 4: setcifra (scr[fleg]);
if ((fl!=3)&&(alarm!=1)) anod_5=1;
else if (blink==0) anod_5=1;
break;
case 5: setcifra (scr[fleg]);
if ((fl!=3)&&(alarm!=1)) anod_6=1;
else if (blink==0) anod_6=1;
break;
case 6: if (blink==1) tochka=1; else tochka=0; break;
};
fleg++;
if (fleg>6) fleg=0;
}
Содержимое поста отредактировано: Apparatchik, в: 13.02.2011 13:29
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6157
Apparatchik(Пользователь)
Специалист
Постов: 123
В ответ на: Плавная смена цифр 13.02.2011 15:14
Репутация: 0  
Пауза в теле основного цыкла 10 мс это нормально?
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6159
ARV(Администратор)
Администратор
Постов: 2386
В ответ на: Плавная смена цифр 13.02.2011 18:27
Репутация: 176  
если в теле основного цикла больше делать нечего, то там может быть любая пауза. а вот с кодом у меня возникли сложности... как-то отвык я от разбора чужого кода... сдается мне, что в обработчике TIM2_COMP напрашивается какая-то оптимизация... что-то с анодами там не то - не хватает массива, что ли...
но я все-таки продолжаю рекомендовать делать чуть-чуть иначе: откажитесь от обмена с RTC внутри обработчика прерывания, ведь обмен по i2c - штука медлденная, явно потребует вспомогательных функций и т.п. просто устанавливайте флаг в прерывании, а вот в главном цикле ожидайте этого флага, а потом читайте время, обрабатывайте его и т.п. думаю, код получится гораздо компактнее и понятнее.
Не стыдно не знать, стыдно не учиться
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6161
Apparatchik(Пользователь)
Специалист
Постов: 123
В ответ на: Плавная смена цифр 13.02.2011 19:25
Репутация: 0  
ARV писал(а): если в теле основного цикла больше делать нечего, то там может быть любая паузатоесть паузу можно вообще неставить? Там идёт опрос кнопок и другие типичные для часов вычисления.что-то с анодами там не то - не хватает массива, что ли...Сделал так чтоб легко было менять разводку на плате #define anod_1 PORTD.6 Часы у меня на газорозрядных индикаторах, лампы разные пробую и т.д. Когда эксперементы закончатся и программа отладится сделаю проще (массив наверное).но я все-таки продолжаю рекомендовать делать чуть-чуть иначе: откажитесь от обмена с RTC внутри обработчика прерывания, ведь обмен по i2c - штука медлденная, явно потребует вспомогательных функций и т.п. просто устанавливайте флаг в прерывании, а вот в главном цикле ожидайте этого флага, а потом читайте время, обрабатывайте его и т.п. думаю, код получится гораздо компактнее и понятнее.Сделаю, огромное спасибо Вам за подобного рода подсказки, мало кто так помагает, а учится негде.я советую для начала сделать просто возможность задания яркости отдельного разряда врчную, т.е. чтобы изменив какую-то переменную (или массив) вы бы получили свои часы, у которых один разряд светится ярче/темнее остальных. когда вы добьетесь этого - вот тогда можно будет запросто менять яркость в нужные моменты автоатически.Есть глобальный массив char bright[6] каждый элемент отвечает за яркость своего разряда, теперь нужно заводить ещо один таймер и в нём менять яркость? И ещо одна проблема: яркость часов в целом меняется в зависимости от положения солнца (четыре ступени ночь утро день вечер), так вот как правильно "увязать" "глобальное" изменение яркости и эфект смены цыфр (цыфра плавно тухнет потом плавно загорается другая)?
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6166
ARV(Администратор)
Администратор
Постов: 2386
В ответ на: Плавная смена цифр 13.02.2011 22:42
Репутация: 176  
советы я для того и даю, чтобы вы и другие начинающие могли научиться чему-то, для того и сайт, для того и форум. собственно. благодарить меня не за что.
теперь о яркости. то есть вы добились того, что можете статичеки задать любую яркость любого разряда, так? и теперь впридачу к том у, что яркость каждого разряда будет меняться при смене цифр, вы еще хотите добавить ОБЩУЮ регулировку яркости, так? я верно понял? если так, то я вижу только один вариант: завести глобальную переменную COMMON_BRIGHT (общая яркость) и в момент установки скважности ШИМ (для любого разряда) УМНОЖАТЬ эту переменную на текущую яркость разряда, а потом СТАРШИЙ разряд 16-битного результата заносить в качестве итоговой яркости. то есть у вас будет двойная модуляция яркости.
Не стыдно не знать, стыдно не учиться
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6168
Apparatchik(Пользователь)
Специалист
Постов: 123
В ответ на: Плавная смена цифр 13.02.2011 23:04
Репутация: 0  
ARV писал(а): то есть вы добились того, что можете статичеки задать любую яркость любого разряда, так? и теперь впридачу к том у, что яркость каждого разряда будет меняться при смене цифр, вы еще хотите добавить ОБЩУЮ регулировку яркости, так? я верно понял?Вы верно поняли, я добился того, что могу задать яркость каждого разряда (просто присвоив значение). А перед тем, как захотелось "эфекта" работала регулировка общей яркости, и теперь хочу "подружить" их.завести глобальную переменную COMMON_BRIGHT (общая яркость) и в момент установки скважности ШИМ (для любого разряда) УМНОЖАТЬ эту переменную на текущую яркость разряда, а потом СТАРШИЙ разряд 16-битного результата заносить в качестве итоговой яркости. то есть у вас будет двойная модуляция яркости.Попробую вникнуть и разобратся в написаном, и наверно завтра будут вопросы.
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6170
ARV(Администратор)
Администратор
Постов: 2386
В ответ на: Плавная смена цифр 14.02.2011 08:41
Репутация: 176  
ну вот вам общая идея, как делать:
Code:
volatile unsigned int common_br;
//там, где настраиваете ШИМ i-го разряда, делаете так:
OCR1A = (bright[i] * common_br) >> 8;
Не стыдно не знать, стыдно не учиться
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6187
Apparatchik(Пользователь)
Специалист
Постов: 123
В ответ на: Плавная смена цифр 16.02.2011 20:35
Репутация: 0  
Сделал пока только плавную смену цыфр. Работает, но как-то нестабильно часто збои бывают, при каждом запуске часов поразному. То всё нормально, то первый разряд чуть мигает в такт смене цыфр в секундах, то вдруг яркость всех знакомест кроме последнего падает. Хватит ли 8МГц тактовой частоты МК для этой цели? Наверно у меня прерывания долго выполняются? Быстрее использовать цыкл for или лучше шесть раз переписать тело цыкла? Куда ещо следует обратить внимание?
Бывает что яркость других знакомест останавливается не на максимуме а в средине и так они тускло горят пока там цыфра несменится. массив яркостей такой char psc[15]={1,40,80,120,160,200,240,255,240,200,160,120,80,40,1}; элементы присваиваются OCR2 через каждые 50мс как дойдёт до последнего ждёт флага. Тоесть как Вы и рекомендовали меньше секунды.
Содержимое поста отредактировано: Apparatchik, в: 16.02.2011 21:20
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6188
ARV(Администратор)
Администратор
Постов: 2386
В ответ на: Плавная смена цифр 16.02.2011 23:18
Репутация: 176  
ну что я могу вам сказать... явно у вас есть ошибки. долго или не долго выполняется код - это я сказать не могу, это надо в отладчике смотреть и замерять. по идее 8 Мгц достаточно для такой задачи...
массив у вас какой-то загадочный... сначала в рост, а потом в спад... может, и неоптимальностей много в других местах?
Не стыдно не знать, стыдно не учиться
Для добавления сообщений Вы должны зарегистрироваться или авторизоваться.
#6192
Apparatchik(Пользователь)
Специалист
Постов: 123
В ответ на: Плавная смена цифр 17.02.2011 23:33
Репутация: 0  
Знаю что ковырятся в чужом коде это .... , но может найдёте минутку. Убрал всё лишнее и постарался всё закоментить. Что я делаю нетак?
Code:
char fleg; // какой разряд выводить
signed char iocr=15; // счётчик ступеней яркости
bit blink; // флаг для мигания точки
bit flscr; // флаг для чтения времени с RTC
char fr[6]; // какой разряд изменился
char tscr[6]; // временный экран
char scr[6]; // экран
char bright[7]={1,1,1,1,1,1,1}; // яркость для каждого разряда включая точки
char psc[15]={1,40,80,120,160,200,240,255,240,200,160,120,80,40,1}; // ступени яркости
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void) // срабатывает каждые пол секунды
{
blink=~blink;
if (blink==0) // выполнять чтото каждую секунду
{
flscr=1; // установка флага - нужно читать время с RTC
}
}
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void) // срабатывает каждые 50мс
{
char i, j;
iocr++;
if (iocr<15) // 14 ступеней яркости
{
for (i=0; i<6; i++)
{
if (fr[i]==1) bright[i]=psc[iocr]; // меняем яркость в нужных разрядах
if (iocr==7) for (j=0; j<6; j++) scr[j]=tscr[j]; // когда яркость ноль выводим следуйщую цыфру
}
}
}
// Timer 2 output compare interrupt service routine
interrupt [TIM2_COMP] void timer2_comp_isr(void)
{
switch (fleg)
{
case 0: setcifra (scr[fleg]);
anod_1=1;
break;
case 1: setcifra (scr[fleg]);
anod_2=1;
break;
case 2: setcifra (scr[fleg]);
anod_3=1;
break;
case 3: setcifra (scr[fleg]);
anod_4=1;
break;
case 4: setcifra (scr[fleg]);
anod_5=1;
break;
case 5: setcifra (scr[fleg]);
anod_6=1;
break;
case 6: if (blink==1) tochka=1; else tochka=0; break;
};
fleg++;
if (fleg>6) fleg=0;
OCR2=bright[fleg];
}
// Timer 2 overflow interrupt service routine
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
anod_1=0; anod_2=0; anod_3=0; anod_4=0; anod_5=0; anod_6=0; // выключиь аноды
tochka=0; // погасить точку
}
void setscr (char a, char b, char c)
{
char i;
tscr[0]=a/10; tscr[1]=a%10; tscr[2]=b/10; tscr[3]=b%10; tscr[4]=c/10; tscr[5]=c%10;
for (i=0; i<6; i++)
{
if (tscr[i]!=scr[i]) fr[i]=1; else fr[i]=0; // узнаём в каком разряде поменялась цыфра
}
iocr=-1; // установка счётчика ступений яркости в начало
flscr=0; // сброс флага, чтения времени
}
void main(void)
{
while (1)
{
// если установлен флаг чтения времени, то читаем,
// вычисляем какой разряд изменился, запускаем плавную смену и збрасываем флаг чтения времени
if (flscr==1) {rtc_get_time (&hour, &min, &sec); setscr (hour, min, sec);}
}
}