c - 32 bit number handling with ATTiny and Atmel Studio -
i wondering how attiny, attiny24 stores 32 bit unsigned ints in memory. i'm trying take 32 bit value , write 32 bit location in eeprom. have attempted use simple mask, every time try, lower 2 bytes (lsb) correctly , upper 2 bytes zeros. example, when try write: 0x12345678 output is: 0x00005678. there setting in atmel studio need set, or need use method other masking.
ultimately want able read 32 bit counter value , write specific location in eeprom. working on modifying existing circuit , not have luxury debug serial output.
code snippets:
in main:
unsigned long test_val = 305419896; //0x12345678 eeprom_long_write(0x25,test_val);
functions:
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 completion of previous write eecr =(0<<eepm1) | (0>>eepm0); // set programming mode eearl = ucaddress; // setup address , data registers eedr = ucdata; // load data register eecr |= (1<<eempe); // write logical 1 eempe eecr |= (1<<eepe); // start eeprom write setting eepe }
you fell pit of integer promotion , coercion. ((1<<8)-1)
processed int
, not long
(better: uint32_t
). on avr, int
has minimum size allowed standard: 16 bits.
as is anyway complicated, can use following:
uint8_t shift = 32u; // enough enough { shift -= 8u; eeprom_write(eeadr++, (uint8_t)(ee_data >> shift)); } while ( shift ) ;
this safes 1 additional shift , explicit masking , registers.
note use of stdint.h
types (you have include header, of course). should correct declarations accordingly. cast uint8_t
implies masking.
Comments
Post a Comment