Обработка 32-битных чисел с ATTiny и Atmel Studio

Мне интересно, как ATTiny, в частности ATTiny24, хранит 32-битные беззнаковые целые в памяти. Я пытаюсь взять 32-разрядное значение и записать его в 32-разрядное место в EEPROM. Я пытался использовать простую маску, но каждый раз, когда я пытаюсь, я правильно получаю два младших байта (lsb), а верхние два байта - все нули. Например, когда я пытаюсь написать: 0x12345678, вывод: 0x00005678. Есть ли в Atmel Studio параметр, который мне нужно установить, или мне нужно использовать другой метод, кроме маскировки.

В конечном итоге я хочу иметь возможность прочитать значение 32-битного счетчика и записать его в определенное место в EEPROM. Я работаю над модификацией существующей схемы и поэтому не могу позволить себе роскошь отлаживать с помощью последовательного выхода.

Фрагменты кода:

В основном:

unsigned long test_val = 305419896;  //0x12345678
EEprom_Long_Write(0x25,test_val);

Функции:

EEprom_Long_Write:

void EEprom_Long_Write(unsigned char eeadr, unsigned long EE_Data)
{
    unsigned char temp=0;
    unsigned char count= eeadr + 3;
    unsigned long mask=0;
    unsigned char position=24;  
    while (eeadr <= count)
    {
        mask = ((1<<8)-1) << position;
        temp = (EE_Data & mask) >> position;
        EEPROM_write(eeadr, temp);
        position = position-8;
        eeadr++;
    }
}

EEPROM_write:

void EEPROM_write(unsigned char ucAddress, unsigned char ucData)
{   
    while(EECR & (1<<EEPE));        //Wait for completion of previous write
    EECR =(0<<EEPM1) | (0>>EEPM0);  // Set Programming mode
    EEARL = ucAddress;              // Setup address and data registers
    EEDR = ucData;                  // Load Data Register
    EECR |= (1<<EEMPE);             // Write logical one to EEMPE
    EECR |= (1<<EEPE);              // Start eeprom write be setting EEPE

}

2 ответа

Решение

Вы попали в яму целочисленного продвижения и принуждения. ((1<<8)-1) обрабатывается как intне long (лучше: uint32_t). На AVR, int имеет минимальный размер, разрешенный стандартом: 16 бит.

В любом случае, это слишком сложно, вы можете использовать следующее:

uint8_t shift = 32U;   // enough is enough
do {
    shift -= 8U;
    EEPROM_write(eeadr++, (uint8_t)(EE_Data >> shift));
} while ( shift ) ;

Это экономит вам одну дополнительную смену и явную маскировку и некоторые регистры.

Обратите внимание на мое использование stdint.h типы (вы должны включить заголовок, конечно). Вы должны исправить все декларации соответственно. Актерский состав uint8_t подразумевает маскировку

Изменить это:

mask = ((1<<8)-1) << position;
temp = (EE_Data & mask) >> position;

к этому:

temp = (EE_Data >> position) & 0xFF;
Другие вопросы по тегам