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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Непонятные действия оптимизации.
defunct
сообщение Dec 22 2008, 17:44
Сообщение #16


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Oleg_IT @ Dec 22 2008, 18:35) *
Увы не одинаково и не стабильно. Без оптимизации всё нормально, с –Os и до –O1 чудеса.

Опишите плз. эти самые "чудеса".
Что не так?
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Dec 22 2008, 18:50
Сообщение #17


Знающий
****

Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709



Цитата(defunct @ Dec 22 2008, 20:44) *
Опишите плз. эти самые "чудеса".
Что не так?

С той простенькой программой при оптимизации меандра на выходе нет, а без оптимизации есть. В более расширенной версии оптимизатор «выкидывает» всё что в мейне под if (Start == 1) …

Код
ISR (TIMER0_COMP_vect)
{
    TCNT0 = 0x00;
    if (Flag == 1)
    {
        PORTA ^= 0x01;
        if ((PINA & 0x02) == 0)
            CountIn_1++;
        CountCycleImp++;
        if (CountCycleImp == ConstCntCycleImp)
        {
            PORTA          &=~ 0x01;
            Flag            = 0;
            CountCycleImp   = 0;
            Start           = 1;
            return;
        }
    }
    else
    {
        CountCycleImp++;
        if (CountCycleImp == ConstCntCycleWithoutImp)
        {
            Flag            = 1;
            CountCycleImp   = 0;
        }
    }
}

//////////////////////    MAIN   ///////////////////
int main(void)
{
    TCCR0   = (1 << CS00);
    TCNT0   = 0x00;
    OCR0    = 0x50;
    TIMSK   |= (1 << OCIE0);

    DDRA   = 0xFD;
    PORTA  = 0xFF;

    sei();

    while (1)
    {
        if (Start == 1)
        {
            Start = 0;
            if (CountIn_1 < CountIn_1_Min)
                PORT_W |= 0x04;

            if (CountIn_1 > CountIn_1_Max)
                PORT_W &=~ 0x04;

            CountIn_1 = 0;
        }
    }
    return 0;
}
Go to the top of the page
 
+Quote Post
Александр Куличо...
сообщение Dec 22 2008, 19:09
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017



Викидывает, потому что при запуске программы Start равно 0 и, следовательно, проверка условия бессмысленна. Компилятор не знает о том, что переменная может поменятся в прерывании. Ему это нужно указать с помощью квалификатора volatile:

volatile char Flags;
Go to the top of the page
 
+Quote Post
smac
сообщение Dec 22 2008, 19:14
Сообщение #19


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

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



Цитата(Oleg_IT @ Dec 22 2008, 21:50) *
С той простенькой программой при оптимизации меандра на выходе нет, а без оптимизации есть. В более расширенной версии оптимизатор «выкидывает» всё что в мейне под if (Start == 1) …

Я конечно полный дилетант в С, но я бы объявил переменные и квалификатор volatile у переменной Start поставил
З. Ы. Надеюсь что нигде не ошибся в терминах
З. З. Ы. Упс, опередили

Сообщение отредактировал smac - Dec 22 2008, 19:15
Go to the top of the page
 
+Quote Post
defunct
сообщение Dec 23 2008, 00:48
Сообщение #20


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Oleg_IT @ Dec 22 2008, 20:50) *
С той простенькой программой при оптимизации меандра на выходе нет, а без оптимизации есть.

А что есть вместо меандра? Точнее плз ;>
У меня с той простенькой программой при оптимизации -Os меандр есть, по крайней мере я вижу что порт переключается...

Насчет Вашей новой программы, с учетом советов предыдущих ораторов, можно написать как-то так:
Код
#include <avr/io.h>
#include <avr/interrupt.h>


typedef unsigned char  U8;
typedef unsigned short U16;
typedef unsigned long  U32;

typedef volatile unsigned char  V8;
typedef volatile unsigned short V16;
typedef volatile unsigned long  V32;


#define ConstCntCycleImp 5
#define ConstCntCycleWithoutImp 3

#define CountIn_1_Min    5
#define CountIn_1_Max    10


#define PORT_W   PORTA


typedef struct tagDEVICE_CONTEXT
{
    U8  Flag;
    V8  Start;
    U8  CountIn_1;
    U8  CountCycleImp;
} TDEVICE_CONTEXT, *PDEVICE_CONTEXT;




TDEVICE_CONTEXT devContext = { 0 };


ISR (TIMER0_COMP_vect)
{
    TCNT0 = 0x00;
    if (devContext.Flag == 1)
    {
        PORTA ^= 0x01;
        if ((PINA & 0x02) == 0)
            devContext.CountIn_1++;
        devContext.CountCycleImp++;
        if (devContext.CountCycleImp == ConstCntCycleImp)
        {
            PORTA          &=~ 0x01;
            devContext.Flag            = 0;
            devContext.CountCycleImp   = 0;
            devContext.Start           = 1;
            return;
        }
    }
    else
    {
        devContext.CountCycleImp++;
        if (devContext.CountCycleImp == ConstCntCycleWithoutImp)
        {
            devContext.Flag            = 1;
            devContext.CountCycleImp   = 0;
        }
    }
}

//////////////////////    MAIN   ///////////////////
int main(void)
{
    TCCR0   = (1 << CS00);
    TCNT0   = 0x00;
    OCR0    = 0x50;
    TIMSK   |= (1 << OCIE0);

    DDRA   = 0xFD;
    PORTA  = 0xFF;

    sei();

    while (1)
    {
        if (devContext.Start == 1)
        {
            devContext.Start = 0;
            if (devContext.CountIn_1 < CountIn_1_Min)
                PORT_W |= 0x04;

            if (devContext.CountIn_1 > CountIn_1_Max)
                PORT_W &=~ 0x04;

            devContext.CountIn_1 = 0;
        }
    }
    return 0;
}

Я не знаю значений Ваших констант, поэтому поставьте какие должны быть. Работает абсолютно одинаково, с оптимизацией и без нее. Что я поменял:
1. Сгруппировал все переменные в одну структуру (удобнее писать программу, т.к. не нужно помнить все переменные, можно помнить только имя одной структуры остальное сделает Code Completion, и удобнее отлаживать - в watch достаточно написать только имя структуры и видно сразу все переменные).
2. Объявил типы в удобной форме (вместо длинючих "volatile unsigned char", ведь много удобнее и понятнее написать V8).
3. Объявил поле Start как volatile, чтобы компилятор не выбрасывал обращения к этой переменной на свое усмотрение.
Go to the top of the page
 
+Quote Post
Oleg_IT
сообщение Dec 23 2008, 04:11
Сообщение #21


Знающий
****

Группа: Свой
Сообщений: 922
Регистрация: 3-06-05
Из: Москва
Пользователь №: 5 709



Цитата(defunct @ Dec 23 2008, 03:48) *
А что есть вместо меандра? Точнее плз ;>
У меня с той простенькой программой при оптимизации -Os меандр есть, по крайней мере я вижу что порт переключается...

Спасибо за подсказку модификации кода.

В той простенькой программе с оптимизацией на выходе вообще ни чего нет.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Dec 23 2008, 19:57
Сообщение #22


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



А вы нам приведите ассемблерный листинг того варианта программы (функцию main и обработчик прерывания), в котором ничего на выходе нет.
Сразу будет видно, где чего не хватает smile.gif
Go to the top of the page
 
+Quote Post

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

 


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


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