реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Вызов функции из interrupt [TIM2_OVF], неправильно обрабатывает данные
Savrik
сообщение Feb 3 2010, 00:56
Сообщение #1


наблюдаю..
***

Группа: Свой
Сообщений: 291
Регистрация: 11-12-06
Из: Украина
Пользователь №: 23 369



Есть обработчик прерывания(1 мс)
Код
interrupt [TIM2_OVF] void timer2_ovf_isr(void)
{
    // Reinitialize Timer 2 value
    TCNT2=0x83;  //сразу переинициализируем таймер
    // Place your code here
    timer++;
    if ((timer%2000) == 0)lcdUpdateStatus = 1;
    if (timer == 10000)
        {  
            timer = 0;
        }
}

и есть функция
Код
void systemCheck()
{
    uchar i;
    if (systemBusy)return;
    systemBusy = 1;
    ADMUX = ADC_U_MINUS;
    for (i = 0; i < 20; i++)
    {
        ADCSRA.6 = 1;    
        while(ADCSRA.6 != 0);    
    }    
    currSysStatus.Uminus = adc_data;  //currSysStatus глобальная структура
    ADMUX = ADC_U_PLUS;
    for (i = 0; i < 20; i++)
    {
        ADCSRA.6 = 1;    
        while(ADCSRA.6 != 0);    
    }    
    currSysStatus.Uplus = adc_data;
    selectInput(MULTIPLEX_L_TEMP);//выбираем соот. вход мультиплексора
    ADMUX = ADC_MULTIPLEX;
    for (i = 0; i < 20; i++)
    {
        ADCSRA.6 = 1;    
        while(ADCSRA.6 != 0);    
    }    
    currSysStatus.temp_L = adc_data;
    selectInput(MULTIPLEX_R_TEMP);    //выбираем соот. вход мультиплексора
    for (i = 0; i < 20; i++)
    {
        ADCSRA.6 = 1;    
        while(ADCSRA.6 != 0);    
    }    
    currSysStatus.temp_R = adc_data;
    systemBusy = 0;  
}

Если вызывать функцию из основного тела программы(напр., цикла в main() каждые 2000 мс), то все так, как надо
Цитата
Umin 1023 Uplus 0, ACErr 0 Lalar 0 Ralar 0 Ltemp 275 Rtemp 254

но если я вызываю из обработчика прерывания каждые 2000, то валится какой-то бред..
Цитата
Umin 259 Uplus 0, ACErr 0 Lalar 0 Ralar 0 Ltemp 259 Rtemp 259
Функция критична, так как в ней фактически реализован контроль за питанием усилителя.. вызывать из основного тела нереально ввиду того, что есть многоуровневое меню.. Что я не так делаю, и какие есть варианты.. мне нужно быть уверенным, что функция ТОЧНО вызовется через каждые 50 мс..
Go to the top of the page
 
+Quote Post
smac
сообщение Feb 3 2010, 04:56
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 2-06-08
Из: Москва
Пользователь №: 38 003



Цитата(Savrik @ Feb 3 2010, 03:56) *
Что я не так делаю, и какие есть варианты.. мне нужно быть уверенным, что функция ТОЧНО вызовется через каждые 50 мс..

Вызывать функции из обработчиков прерываний совсем не комильфо, но если очень хочется, тогда нужно обратить внимание на стек ну и ассемблерный листинг неплохо бы посмотреть.
Go to the top of the page
 
+Quote Post
jasper
сообщение Feb 3 2010, 05:12
Сообщение #3


Народный чинитель
***

Группа: Участник
Сообщений: 415
Регистрация: 15-07-05
Пользователь №: 6 811



Возможно, следует объявить глобальные переменные, как volatile.
Go to the top of the page
 
+Quote Post
ut1wpr
сообщение Feb 3 2010, 05:42
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 98
Регистрация: 20-06-05
Пользователь №: 6 150



Цитата(jasper @ Feb 3 2010, 08:12) *
Возможно, следует объявить глобальные переменные, как volatile.

Для начала попробуй выключить всю оптимизацию. Абсолютно всю. Затем посмотри, может стека мало.
Уж очень большую функцию вызываешь. Правильно сказано, не кошерно это.
Программирование чаще всего - не реализация алгоритма, а его поиск. Может, в консерватории что-то подправить? smile.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 3 2010, 06:05
Сообщение #5


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ut1wpr @ Feb 3 2010, 09:42) *
Может, в консерватории что-то подправить? smile.gif

Там, похоже, надо голову сменить. Кстати, одно исключение имеется когда ситуация
Цитата
Функция критична ... вызывать из основного тела нереально ввиду того, что есть многоуровневое меню

возможна в реальной жизни - для Low Power Design, там где нельзя мучить МК переключением контекстов.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 3 2010, 08:00
Сообщение #6


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(jasper @ Feb 3 2010, 07:12) *
Возможно, следует объявить глобальные переменные, как volatile.
Ага. Все. Не глядя. Вот объясните - какими мыслями вы руководствуетесь, давая такие советы?


Цитата(ut1wpr @ Feb 3 2010, 07:42) *
Для начала попробуй выключить всю оптимизацию. Абсолютно всю.
Тоже совет из серии "закрой окно, по колесу постучи".


Цитата(Savrik @ Feb 3 2010, 02:56) *
и есть функция
все операции с SystemBusy можно смело выкинуть - у вас нет разрешения вложенных прерываний, значит этот код не будет прерван. Покажите объявление currSysStatus. Добавьте в его еще конец одно поле и выводите его вместе с остальными данными. Если увидите там не 0 - у вас нехватка стека, надо переделывать программу, сокращая количество глобальных переменных. Какой смысл делать 20 преобразований АЦП, не используя их результат? Добавьте дерганье ногой в начале и конце этой функции, убедитесь, что прерывание таймера вызывает ее именно раз в 2 сек.

Цитата(Savrik @ Feb 3 2010, 02:56) *
какие есть варианты.. мне нужно быть уверенным, что функция ТОЧНО вызовется через каждые 50 мс..
Кристалл не указан - у новых мег есть возможность запускать АЦП от событий таймера. Точне вы не получите. А тем более программно.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Savrik
сообщение Feb 3 2010, 15:26
Сообщение #7


наблюдаю..
***

Группа: Свой
Сообщений: 291
Регистрация: 11-12-06
Из: Украина
Пользователь №: 23 369



Цитата(smac @ Feb 3 2010, 06:56) *
Вызывать функции из обработчиков прерываний совсем не комильфо, но если очень хочется, тогда нужно обратить внимание на стек

Стек в порядке.. из других, намного тяжелее функций, вызов идет нормально. К тому же, (правда, не знаю, насколько это оптимально и как правильно работает в компиляторе CAVR) стек увеличен до 300 байт.

Цитата(Сергей Борщ @ Feb 3 2010, 10:00) *
все операции с SystemBusy можно смело выкинуть - у вас нет разрешения вложенных прерываний, значит этот код не будет прерван. Покажите объявление currSysStatus. Добавьте в его еще конец одно поле и выводите его вместе с остальными данными. Если увидите там не 0 - у вас нехватка стека, надо переделывать программу, сокращая количество глобальных переменных. Какой смысл делать 20 преобразований АЦП, не используя их результат? Добавьте дерганье ногой в начале и конце этой функции, убедитесь, что прерывание таймера вызывает ее именно раз в 2 сек.
Кристалл не указан - у новых мег есть возможность запускать АЦП от событий таймера. Точне вы не получите. А тем более программно.

20 преобразований это на будущее) Прерывание точно вызывает раз в 2 секунды. Извините, забыл - ATMega16L. Добавил поле, и оно 0.. вот и сама структура
Код
typedef struct sysSettings {
    uchar        brightness;
    uchar        contrast;
    uint         fan1;
    uint         fan2;
    uint         temp_L;
    uint         temp_R;
    uint         Uplus;
    uint         Uminus;
    uchar          LAlarm;
    uchar          RAlarm;
    uchar          ACError;
    uchar        Mute;
    uchar test;
} c_SystemSettings;

используется по всей программе, нигде проблем со стеком не замечено. Могу грешить только на adc_data, так как во всех переменных, изменяемых systemCheck() они одинаковые..


P.S. тьфу.. я же из прерывания запускаю преобразование АЦП. Смогу ли я получить прерывание по завершению преобразования, если сейчас нахожусь в другом, более низкоуровневом прерывании?


P.P.S. так как нету прерывания по завершению АЦП, решил следующим образом:
Код
...
currSysStatus.temp_R = ADCW;  //вместо currSysStatus.temp_R = adc_data;
...

Прошу прощения за собственную глупостьsmile.gif И спасибо всем за советы, направили мозги в нужное направление)

Сообщение отредактировал Savrik - Feb 3 2010, 15:34
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 15:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016