Главная категория > Программаторы
AVR Studio4 и оптимизация
Two_byte:
Народ, помогите разобраться, накалякал снифер для определения УОЗ квадроцикла
Спойлер//#include <mega8.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
volatile unsigned char i = 0; data_e; temp = 0;
unsigned long buffer;
volatile unsigned int counter_rpm; count; rpm; rpm1;
unsigned int addr; angle; angle_val[150];
ISR(INT0_vect)
{
TCCR1B=0x02;
}
ISR(INT1_vect)
{
TCCR1B=0x00;
//if (temp == 0) count = 0;
count=TCNT1;
TCNT1=0;
i=1;
}
ISR(TIMER1_OVF_vect)
{
counter_rpm++;
}
ISR(ANA_COMP_vect)
{
rpm = TCNT1;
rpm1 = counter_rpm;
}
void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
{
/* Wait for completion of previous write */
while(EECR & (1<<EEWE))
;
/* Set up address and data registers */
EEAR = uiAddress;
//temp = ucData>>8; // сдвиг вправо на 8 бит
EEDR = ucData;
/* Write logical one to EEMWE */
EECR |= (1<<EEMWE);
/* Start eeprom write by setting EEWE */
EECR |= (1<<EEWE);
}
int main(void)
{
cli();
TCCR1A=0x00;
TCCR1B=0x00;
MCUCR |= _BV(ISC11) | _BV(ISC01);
MCUCR &= ~(_BV(ISC10)) & ~(_BV(ISC00));
GICR |= _BV(INT0) | _BV(INT1);
DDRD &= ~(_BV(PD6)) & ~(_BV(PD7)) & ~(_BV(PD2)) & ~(_BV(PD3));
PORTD = 0xff;
ACSR |= _BV(ACIE) | _BV(ACIS1) | _BV(ACBG);
ACSR &= ~(_BV(ACD)) & ~(_BV(ACIC)) & ~(_BV(ACIS0));
SFIOR &= ~(_BV(ACME));
data_e = 0xff;
for (addr=0; addr<512; addr++)
{
EEPROM_write(addr,data_e);
}
counter_rpm=0;
sei();
while(1)
{
temp = 0;
if (i != 0) - это условие проверяется только после вычисления следующей строки, и цикл while передает управление на строку addr = 141176/buffer
{
buffer = ((unsigned long)counter_rpm * 65536 + (unsigned long)count);
addr = 141176/buffer; // через 50 RPM по два байта на угол
angle = ((buffer - ((unsigned long)rpm1*65536 + (unsigned long)rpm))*423)/buffer; // угол * 10 !!!
// data_e = angle/256;
angle_val[addr] = angle;
// EEPROM_write(addr,data_e);
// data_e = angle;
// addr++;
// EEPROM_write(addr,data_e);
counter_rpm=0;
i=0;
}
buffer=0; - если убрать эту строку, то цикл while вообще делает только один проход, и стопорится в самом конце программы ( rjmp $ )
}
}
Дык эта падла, при оптимизации в цикле while(1) {} неправильно переход и проверку условия переменной i делает.
Без оптимизации все компилирует правильно, но время обработки прерывания становится неприлично большим.
Прям хоть на АСМ-е пиши!
tridentxp:
что значит не правильно i проверяет ? ну ты ваще замудтил... нагрузил 8 битную бедолагу 32-у битными типами (зы,у кого подпись про невпихуемое ?).. кста, я бы *65536 заменил бы на <16. арму юзай.
Two_byte:
переменную i проверяет не в том месте цикла где надо, а на строку ниже.
drfaust:
А где i инициализируется?
Модификатор volatile говорит компилеру не делать никаких предположений относительно значения i. В дебаг-режиме все переменные обычно обнуляются, если не указано иное, как только включается оптимизация volatile unsigned char i = 0; из-за volatile присвоение i=0; не выполняется. Нужно инициализировать volatile переменные (в том числе и temp) в начале main()
Так что, стоит сначала i и temp явно сразу после cli проинициализировать - должно помочь. Вообще-то попробуй использовать модификатор const вместо volatile, (правда придётся при изменении этой переменной помучатся с преобразованием типа) - согласно стандарту С глобальные переменные(и выражения с их использованием) с модификатором const не оптимизируются -> не должно быть оптимизации перехода if(i != 0)...
СТОП!!! Я ошибся, надо использовать static, а при изменении переменной использовать преобразование типа к обычному int.Хотя по ANSI C оптимизации не подлежат и глобальные переменные - стоит всё-таки поиграться с отсутствием volatile
volatile конкретно по PICам и прочим встройкам - по идее компилер не должен оптимизировать if(!=0)
tridentxp:
--- Цитата: drfaust от 23/07/2014 21:31:58 ---... volatile unsigned char i = 0; из-за volatile присвоение i=0; не выполняется....
--- Конец цитаты ---
интересный оборот... а где об этом говорится ?
Навигация
Перейти к полной версии