Цитата(Sirko @ Feb 5 2009, 21:35)

Может подскажите, как написать Си код, что бы без оптимизации нормально компилился.
Это еще что за глупости? Оптимизация - обязательная часть процесса компиляции, без нее получается код в 4...5 раз больше и, соответственно, медленнее. Вы тоже наслушались страшилок об ошибках оптимизации? Отключение оптимизации IMHO предназначено исключительно для того, чтобы в случае, если вам покажется что в оптимизации ошибка, вы могли ее отключить и убедиться, что на самом деле ошибка в вашем коде.
У меня для работы с EEPROM есть два файла - eerw.h и eerw.c, я их просто подключаю к проекту и пользуюсь их функциями. Для записи там используется кольцевой буфер - если запись уже идет, то данные помещаются в этот буфер, а по прерыванию по завершении предыдущего цикла записи выбираются из буфера и ставятся на запись.
В основной программе нужно только вызвать EEInit() в начале, там где программируются порты и пр.
CODE
//
// eerw.h
//
#define EE_SIZE 16 // размер кольцевого буфера для записи в EEPROM
typedef struct tagEEdata
{
uint8_t Adr;
uint8_t Data;
} CEEdata;
void EEinit();
uint8_t ReadEE(uint8_t adr);
uint16_t ReadEE2(uint8_t adr);
uint32_t ReadEE4(uint8_t adr);
void WriteEE(uint8_t data, uint8_t adr);
void WriteEE2(uint16_t data, uint8_t adr);
void WriteEE4(uint32_t data, uint8_t adr);
void WriteNextByte();
CODE
//
// eerw.c - функции для чтения/записи в EEPROM
//
#include <avr/io.h>
#include <avr/interrupt.h>
#include "eerw.h"
CEEdata EEdata[EE_SIZE]; // буфер данных для записи в EEPROM
CEEdata *pInPtr, *pOutPtr; // указатели для записи в EEPROM
/*
* работа с EEPROM
*/
void EEinit()
{
pInPtr = pOutPtr = EEdata;
}
uint8_t ReadEE(uint8_t adr)
{
while(EECR & _BV(EEWE))
{}
EEAR = adr;
EECR |= _BV(EERE);
return EEDR;
}
uint16_t ReadEE2(uint8_t adr)
{
uint16_t res1 = ReadEE(adr), res2 = ReadEE(adr+1);
return res1 | (res2<<8);
}
uint32_t ReadEE4(uint8_t adr)
{
uint32_t res1 = ReadEE2(adr), res2 = ReadEE2(adr+2);
return res1 | (res2<<16);
}
void WriteEE(uint8_t data, uint8_t adr)
{
pInPtr->Adr = adr;
pInPtr->Data = data;
if(++pInPtr == &EEdata[EE_SIZE])
pInPtr = EEdata;
cli();
if((EECR & _BV(EERIE)) == 0)
{
EECR |= _BV(EERIE);
WriteNextByte();
}
sei();
}
void WriteEE2(uint16_t data, uint8_t adr)
{
WriteEE(data, adr);
WriteEE((data&0xff00)>>8, adr+1);
}
void WriteEE4(uint32_t data, uint8_t adr)
{
WriteEE2(data, adr);
WriteEE2((data&0xffff0000)>>16, adr+2);
}
void WriteNextByte()
{
EEAR = pOutPtr->Adr;
EEDR = pOutPtr->Data;
if(++pOutPtr == &EEdata[EE_SIZE])
pOutPtr = EEdata;
cli();
EECR |= _BV(EEMWE);
EECR |= _BV(EEWE);
sei();
}
/*
* Обработчик прерывания от EEPROM
*/
ISR(EE_RDY_vect)
{
if(pOutPtr == pInPtr)
EECR &= ~_BV(EERIE);
else
WriteNextByte();
}
Причина редактирования: Уменьшение видимого размера цитируемых исходников.