C_unions_bits.txt 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. union _word
  2. {
  3. uint16_t word;
  4. uint8_t byte[2];
  5. } wrd;
  6. wrd.byte[0] = data;
  7. wrd.byte[1] = reg;
  8. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  9. http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=67601
  10. typedef union {
  11. volatile unsigned char flinps;
  12. struct {
  13. unsigned char b0 : 1;
  14. unsigned char b1 : 1;
  15. unsigned char menubtileft : 1;
  16. unsigned char menubtimiddle : 1;
  17. unsigned char menubtiright : 1;
  18. unsigned char b5 : 1;
  19. unsigned char b6 : 1;
  20. unsigned char b7 : 1;
  21. };
  22. } flinps_union_t;
  23. typedef union {
  24. volatile unsigned char buttons;
  25. struct {
  26. unsigned char b0 : 1;
  27. unsigned char b1 : 1;
  28. unsigned char menubtbleft : 1;
  29. unsigned char menubtbmiddle : 1;
  30. unsigned char menubtbright : 1;
  31. unsigned char b5 : 1;
  32. unsigned char b6 : 1;
  33. unsigned char b7 : 1;
  34. };
  35. } buttons_union_t;
  36. typdef struct {
  37. flinps_union_t flinps;
  38. buttons_union_t buttons;
  39. unsigned char buttprsd;
  40. unsigned char fdsmsm;
  41. unsigned char tmpinps;
  42. } mydata_struct_t;
  43. mydata_struct_t mydata;
  44. int main(void) {
  45. mydata.flinps.menubtileft = 1;
  46. mydata.buttons.menubtbright = 0;
  47. mydata.buttprsd = 11;
  48. mydata.fdsmsm = 22;
  49. mydata.tmpinps = 33;
  50. }
  51. -------------------------------------------------------------------------------
  52. Как брать отдельные байты от слова?
  53. http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=20709&start=0
  54. A UNION is the most elegant solution and designed to perform just this task.
  55. Code:
  56. union u_type //Setup a Union
  57. {
  58. unsigned int IntVar;
  59. unsigned char Bytes[2];
  60. }
  61. temp; //Assign a var name to the Union
  62. void main(void)
  63. {
  64. temp.IntVar=65535; //Assign a value to the Int var of the Union
  65. HighByte=temp.Bytes[1]; //Get the High Byte (255)
  66. LowByte=temp.Bytes[0]; //Get the Low Byte (255)
  67. }
  68. ----------
  69. into a series of char (8-bit) pointers. Example:
  70. Code:
  71. unsigned char low_byte;
  72. unsigned char high_byte;
  73. unsigned int the_value;
  74. ...
  75. the_value = 1234;
  76. low_byte = * ((unsigned char *)&the_value);
  77. high_byte = * ((unsigned char *)((&the_value)+1));
  78. or a char-sized pointer could be used the same way. [I'd probably use the pointer method for repetitive uses within an app and/or many-byte variables.]
  79. Code:
  80. unsigned char low_byte;
  81. unsigned char high_byte;
  82. unsigned int the_value;
  83. unsigned char *the_ptr;
  84. ...
  85. the_value = 1234;
  86. the_ptr = * ((unsigned char *)&the_value);
  87. low_byte = *the_ptr;
  88. the_ptr++;
  89. high_byte = *the_ptr;
  90. ----------
  91. the bset way:
  92. it only compile in ONe line asm code !
  93. Code:
  94. #define LowB(x) (*((unsigned char*) &(##x)+1))
  95. #define HighB(x) (*((unsigned char*) &(##x)+0))
  96. for ex for low byte use LowB(x)
  97. только тут наверное младший байт без смещение (лежит первым), а старший
  98. байт -- +1. И тогда это совпадёт с предыдущим примером.
  99. ----------
  100. typedef union {
  101. uint16_t u16; // element specifier for accessing whole u16
  102. int16_t i16; // element specifier for accessing whole i16
  103. struct {
  104. #ifdef LITTLE_ENDIAN // Byte-order is little endian
  105. uint8_t u8L; // element specifier for accessing low u8
  106. uint8_t u8H; // element specifier for accessing high u8
  107. #else // Byte-order is big endian
  108. uint8_t u8H; // element specifier for accessing low u8
  109. uint8_t u8L; // element specifier for accessing high u8
  110. #endif
  111. } s16; // element spec. for acc. struct with low or high u8
  112. } nt16_t;
  113. nt16_t a;
  114. a.u16 = 0x0123;
  115. a.s16.u8H == 0x01;
  116. typedef union {
  117. uint32_t u32; // element specifier for accessing whole u32
  118. int32_t i32; // element specifier for accessing whole i32
  119. struct {
  120. #ifdef LITTLE_ENDIAN // Byte-order is little endian
  121. uint16_t u16L; // element specifier for accessing low u16
  122. uint16_t u16H; // element specifier for accessing high u16
  123. #else // Byte-order is big endian
  124. uint16_t u16H; // element specifier for accessing low u16
  125. uint16_t u16L; // element specifier for accessing high u16
  126. #endif
  127. } s32; // element spec. for acc. struct with low or high u16
  128. } nt32_t;