|
|
  |
Часы, немного переделал и стали отставать |
|
|
|
Dec 7 2008, 19:40
|
Частый гость
 
Группа: Свой
Сообщений: 92
Регистрация: 8-03-05
Пользователь №: 3 160

|
Раньше в прерывании было Код ISR(SIG_OVERFLOW2) { clock_++; if (clock_==128) { clock_=0; hour[h_sek]++; } } Функция часов Код if (hour[h_sek]==60) { hour[h_sek] =0; hour[h_min]++; …. Сделал Код ISR(SIG_OVERFLOW2) { clock_++; if (clock_==128) { clock_=0; isr_1sek_=1; } } Код void clock(void){ cli(); if ( isr_1sek_ )//прошла секунда { isr_1sek_=0; sei(); if (++hour[h_sek]==60) { hour[h_sek] =0; hour[h_min]++; if (hour[h_min]==60) …. sei(); Часы начали отставать. Не могу понять почему? Ведь событие происходит раз в секунду, пропустить его ни как нельзя, даже если программа зависнет на пол секунды, чего нет на самом деле. Вот, чешу репу, чего я не так сделал?
|
|
|
|
|
Dec 7 2008, 20:23
|
Частый гость
 
Группа: Свой
Сообщений: 92
Регистрация: 8-03-05
Пользователь №: 3 160

|
Цитата(DpInRock @ Dec 8 2008, 00:08)  Насколько?
Что является эталоном? Случаем не виндовые часы? Примерно на 5 сек. в сутки. Тоже сначала показалось что что-то с комповскими часами не то, поэтому перед проверкой делал синхронизацию с временем интернета. Раньше без коррекции в функции часов: 23:42 09.12.2007 0:20 14.12.2007 отстование 2 сек Прикрепил исходник, но в нем наверное глухо разобраться (17kB)
|
|
|
|
|
Dec 7 2008, 20:57
|
Гуру
     
Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882

|
_Diman_, я бы на вашем месте инкремент переменной делал после проверки условия на выход ее за границу допустимых значений, а не проверку условия после инкремента. Код if (hour[h_sec]<59) hour[h_sec]+=1; else { hour[h_sec]=0; if (hour[h_min]<59) hour[h_min]+=1; esle { hour[h_min]=0; Кроме этого переменная isr_1sek_ должна быть типа volatile. Ну и вдобавок, если у вас структура времени, то может стоить оформить ее как структуру, а не простой массив значений. P.S. исходник не смотрел  P.P.S. смущает строчка Код if (++hour[h_sek]==60) . Я не настолько большой знаток стандартов Си, чтобы понять, что по стандарту раньше делается после индексирования и извлечения значения, инкремент значения или сравнение?
|
|
|
|
|
Dec 7 2008, 21:29
|
Частый гость
 
Группа: Свой
Сообщений: 92
Регистрация: 8-03-05
Пользователь №: 3 160

|
Я думаю тут не из-за этого, но можно и так. Код if (++hour[h_sek]>=60) Инкремент после был бы: Код if (hour[h_sek]++==60) На счет volatile, я смотрю листинг. Привык к WinAVR-20060421. Там обычно не прокатывает вот такое Код ISR(){ clock_--; }
clock_=60; while(clock_) В функции часов, есть одно место "не очень" коррекция хода в час, Код if (++hour[h_min]==60) { //cli(); if ( setup.corr_flag&BIT(fl_corr_znak_pl) )//корекция часов clock_+=setup.correction;//для убыстрения else clock_= 0x00-setup.correction; //sei(); Но это раньше работало, здесь я тоже особых проблем не вижу. Ладно, не буду голову забивать, буду разбираться в симуляторе.
|
|
|
|
|
Dec 11 2008, 05:28
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(DpInRock @ Dec 11 2008, 07:03)  В прерывании, сначала решайте вопросы индикатора (и звука), а потом все остальные. Тогда время индикации будет постоянным. Обычно делают наоборот: фонвая программа занимается динамической индикацией и обработкой кнопок, так как для нее не критично изменение частоты на 10...20%, а все остальное делается в прерываниях. Цитата(DpInRock @ Dec 11 2008, 07:03)  Особенно это заметно, если звук по прерыванию генериться. Не проще ли генерить его таймером?
|
|
|
|
|
Dec 11 2008, 22:44
|
Частый гость
 
Группа: Свой
Сообщений: 92
Регистрация: 8-03-05
Пользователь №: 3 160

|
Да как то уже все сделано, возвращаться неохота и нет времени. Яркость тоже сидит в прерывании, всего их два, яркость и часы. Звук примитивный пищит только, 1 таймером. Вот писание часов http://startcd.narod.ru/clock/clock.html если интересно только эти на ид10, а так они у меня с 2004 года уже трудятся. Поменял коррекцию, не помогло. Код ISR(SIG_OVERFLOW0){ if (++lcd_time_switch==light_isr) PORTLCD=lcd_buffer[znakomesto]; } //************************************** ISR(SIG_OVERFLOW2) { clock_++; if (clock_==128) { clock_=correct; isr_1sek_=1; } }
//************************************** void clock(void){ if ( isr_1sek_ )//прошла секунда { correct=0; if (++hour[h_sek]==60) { if (++hour[h_min]==60) { if ( setup.corr_flag&BIT(fl_corr_znak_pl) )//корекция часов correct=setup.correction;//для убыстрения else correct= 0x00-setup.correction; hour[h_min] =0; hour[h_hour]++; Вообщем пока забросил. Во блин, сейчас опять решил проверить уход, до синхронизации с интернетом за два дня секунд 13, после синхронизации 1 секунда. Получается у меня, что то с компом. Извините, что ненароком мозги пудрил
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|