[{"data":1,"prerenderedAt":565},["ShallowReactive",2],{"guide-binary-in-embedded-systems":3},{"id":4,"title":5,"body":6,"date":556,"description":557,"extension":558,"meta":559,"navigation":560,"path":561,"readingTime":389,"seo":562,"stem":563,"__hash__":564},"guides\u002Fguides\u002Fbinary-in-embedded-systems.md","Binary Data in Embedded Systems",{"type":7,"value":8,"toc":542},"minimark",[9,13,18,21,26,29,59,66,70,73,99,103,106,121,125,128,153,157,164,218,221,252,255,264,268,271,316,319,339,350,354,357,393,396,400,403,472,475,505,509,525,529,538],[10,11,12],"p",{},"Embedded systems operate at the boundary between software and hardware, where every bit matters. Microcontrollers communicate with sensors, actuators, and communication peripherals through registers — memory-mapped addresses where individual bits control hardware behavior. Understanding binary representation is not optional in this domain; it is the language the hardware speaks.",[14,15,17],"h2",{"id":16},"register-manipulation-with-bitwise-operations","Register Manipulation with Bitwise Operations",[10,19,20],{},"Hardware registers pack multiple fields into a single byte or word. Setting, clearing, or toggling individual bits without disturbing others requires bitwise operations.",[22,23,25],"h3",{"id":24},"setting-a-bit-or","Setting a Bit (OR)",[10,27,28],{},"To enable a peripheral, you set a specific bit to 1:",[30,31,36],"pre",{"className":32,"code":33,"language":34,"meta":35,"style":35},"language-c shiki shiki-themes github-light github-dark","\u002F\u002F Set bit 3 of register CTRL (enable interrupt)\nCTRL |= (1 \u003C\u003C 3);\n\u002F\u002F Binary: if CTRL was 01010010, result is 01011010\n","c","",[37,38,39,47,53],"code",{"__ignoreMap":35},[40,41,44],"span",{"class":42,"line":43},"line",1,[40,45,46],{},"\u002F\u002F Set bit 3 of register CTRL (enable interrupt)\n",[40,48,50],{"class":42,"line":49},2,[40,51,52],{},"CTRL |= (1 \u003C\u003C 3);\n",[40,54,56],{"class":42,"line":55},3,[40,57,58],{},"\u002F\u002F Binary: if CTRL was 01010010, result is 01011010\n",[10,60,61,62,65],{},"The OR operation leaves all other bits unchanged because ",[37,63,64],{},"x | 0 = x",".",[22,67,69],{"id":68},"clearing-a-bit-and-with-not","Clearing a Bit (AND with NOT)",[10,71,72],{},"To disable a feature, you clear a bit to 0:",[30,74,76],{"className":32,"code":75,"language":34,"meta":35,"style":35},"\u002F\u002F Clear bit 5 of register MODE (disable watchdog)\nMODE &= ~(1 \u003C\u003C 5);\n\u002F\u002F ~(1 \u003C\u003C 5) = 11011111\n\u002F\u002F AND with 11011111 forces bit 5 to 0, preserves everything else\n",[37,77,78,83,88,93],{"__ignoreMap":35},[40,79,80],{"class":42,"line":43},[40,81,82],{},"\u002F\u002F Clear bit 5 of register MODE (disable watchdog)\n",[40,84,85],{"class":42,"line":49},[40,86,87],{},"MODE &= ~(1 \u003C\u003C 5);\n",[40,89,90],{"class":42,"line":55},[40,91,92],{},"\u002F\u002F ~(1 \u003C\u003C 5) = 11011111\n",[40,94,96],{"class":42,"line":95},4,[40,97,98],{},"\u002F\u002F AND with 11011111 forces bit 5 to 0, preserves everything else\n",[22,100,102],{"id":101},"toggling-a-bit-xor","Toggling a Bit (XOR)",[10,104,105],{},"To flip a bit — useful for blinking an LED — use XOR:",[30,107,109],{"className":32,"code":108,"language":34,"meta":35,"style":35},"\u002F\u002F Toggle bit 2 of PORTB (blink LED on pin 2)\nPORTB ^= (1 \u003C\u003C 2);\n",[37,110,111,116],{"__ignoreMap":35},[40,112,113],{"class":42,"line":43},[40,114,115],{},"\u002F\u002F Toggle bit 2 of PORTB (blink LED on pin 2)\n",[40,117,118],{"class":42,"line":49},[40,119,120],{},"PORTB ^= (1 \u003C\u003C 2);\n",[22,122,124],{"id":123},"reading-a-bit-and","Reading a Bit (AND)",[10,126,127],{},"To check whether a flag is set:",[30,129,131],{"className":32,"code":130,"language":34,"meta":35,"style":35},"\u002F\u002F Check if bit 4 of STATUS is set (data ready)\nif (STATUS & (1 \u003C\u003C 4)) {\n    read_sensor_data();\n}\n",[37,132,133,138,143,148],{"__ignoreMap":35},[40,134,135],{"class":42,"line":43},[40,136,137],{},"\u002F\u002F Check if bit 4 of STATUS is set (data ready)\n",[40,139,140],{"class":42,"line":49},[40,141,142],{},"if (STATUS & (1 \u003C\u003C 4)) {\n",[40,144,145],{"class":42,"line":55},[40,146,147],{},"    read_sensor_data();\n",[40,149,150],{"class":42,"line":95},[40,151,152],{},"}\n",[14,154,156],{"id":155},"multi-bit-fields","Multi-Bit Fields",[10,158,159,160,163],{},"Many registers group adjacent bits into fields. For example, an ADC control register might use bits ",[40,161,162],{},"2:0"," to select a channel:",[165,166,167,182],"table",{},[168,169,170],"thead",{},[171,172,173,179],"tr",{},[174,175,176,177],"th",{},"Bits ",[40,178,162],{},[174,180,181],{},"Channel",[183,184,185,194,202,210],"tbody",{},[171,186,187,191],{},[188,189,190],"td",{},"000",[188,192,193],{},"Channel 0",[171,195,196,199],{},[188,197,198],{},"001",[188,200,201],{},"Channel 1",[171,203,204,207],{},[188,205,206],{},"010",[188,208,209],{},"Channel 2",[171,211,212,215],{},[188,213,214],{},"011",[188,216,217],{},"Channel 3",[10,219,220],{},"To write a 3-bit value into this field without affecting other bits:",[30,222,224],{"className":32,"code":223,"language":34,"meta":35,"style":35},"\u002F\u002F Set channel to 5 (binary 101) in bits [2:0]\nADC_CTRL = (ADC_CTRL & ~0x07) | 0x05;\n\u002F\u002F 0x07 = 00000111 — mask for bits [2:0]\n\u002F\u002F ~0x07 = 11111000 — clears bits [2:0], preserves rest\n\u002F\u002F | 0x05 = sets bits [2:0] to 101\n",[37,225,226,231,236,241,246],{"__ignoreMap":35},[40,227,228],{"class":42,"line":43},[40,229,230],{},"\u002F\u002F Set channel to 5 (binary 101) in bits [2:0]\n",[40,232,233],{"class":42,"line":49},[40,234,235],{},"ADC_CTRL = (ADC_CTRL & ~0x07) | 0x05;\n",[40,237,238],{"class":42,"line":55},[40,239,240],{},"\u002F\u002F 0x07 = 00000111 — mask for bits [2:0]\n",[40,242,243],{"class":42,"line":95},[40,244,245],{},"\u002F\u002F ~0x07 = 11111000 — clears bits [2:0], preserves rest\n",[40,247,249],{"class":42,"line":248},5,[40,250,251],{},"\u002F\u002F | 0x05 = sets bits [2:0] to 101\n",[10,253,254],{},"To extract the channel value:",[30,256,258],{"className":32,"code":257,"language":34,"meta":35,"style":35},"uint8_t channel = ADC_CTRL & 0x07;\n",[37,259,260],{"__ignoreMap":35},[40,261,262],{"class":42,"line":43},[40,263,257],{},[14,265,267],{"id":266},"endianness-in-communication-protocols","Endianness in Communication Protocols",[10,269,270],{},"Embedded systems frequently exchange binary data over serial buses (SPI, I2C, UART) and network interfaces (CAN, Ethernet). Byte order — endianness — determines how multi-byte values are laid out in memory and on the wire.",[165,272,273,286],{},[168,274,275],{},[171,276,277,280,283],{},[174,278,279],{},"Order",[174,281,282],{},"Layout of 0x1234",[174,284,285],{},"Used By",[183,287,288,302],{},[171,289,290,293,299],{},[188,291,292],{},"Big-endian",[188,294,295,298],{},[37,296,297],{},"12 34"," (MSB first)",[188,300,301],{},"Network protocols, CAN, Modbus",[171,303,304,307,313],{},[188,305,306],{},"Little-endian",[188,308,309,312],{},[37,310,311],{},"34 12"," (LSB first)",[188,314,315],{},"x86, ARM (default), most RTOS",[10,317,318],{},"When an ARM microcontroller sends a 16-bit value over a CAN bus (big-endian protocol), you must swap bytes:",[30,320,322],{"className":32,"code":321,"language":34,"meta":35,"style":35},"uint16_t value = 0x1234;\nuint16_t network_order = ((value & 0xFF) \u003C\u003C 8) | ((value >> 8) & 0xFF);\n\u002F\u002F Result: 0x3412 → transmitted as bytes 0x12, 0x34\n",[37,323,324,329,334],{"__ignoreMap":35},[40,325,326],{"class":42,"line":43},[40,327,328],{},"uint16_t value = 0x1234;\n",[40,330,331],{"class":42,"line":49},[40,332,333],{},"uint16_t network_order = ((value & 0xFF) \u003C\u003C 8) | ((value >> 8) & 0xFF);\n",[40,335,336],{"class":42,"line":55},[40,337,338],{},"\u002F\u002F Result: 0x3412 → transmitted as bytes 0x12, 0x34\n",[10,340,341,342,345,346,349],{},"Many compiler toolchains provide ",[37,343,344],{},"htons()"," \u002F ",[37,347,348],{},"ntohs()"," helpers for this purpose.",[14,351,353],{"id":352},"bitfields-in-c-convenient-but-risky","Bitfields in C: Convenient but Risky",[10,355,356],{},"C allows you to define bitfields in structs:",[30,358,360],{"className":32,"code":359,"language":34,"meta":35,"style":35},"typedef struct {\n    uint8_t channel  : 3;\n    uint8_t enabled  : 1;\n    uint8_t mode     : 2;\n    uint8_t reserved : 2;\n} ADC_Config;\n",[37,361,362,367,372,377,382,387],{"__ignoreMap":35},[40,363,364],{"class":42,"line":43},[40,365,366],{},"typedef struct {\n",[40,368,369],{"class":42,"line":49},[40,370,371],{},"    uint8_t channel  : 3;\n",[40,373,374],{"class":42,"line":55},[40,375,376],{},"    uint8_t enabled  : 1;\n",[40,378,379],{"class":42,"line":95},[40,380,381],{},"    uint8_t mode     : 2;\n",[40,383,384],{"class":42,"line":248},[40,385,386],{},"    uint8_t reserved : 2;\n",[40,388,390],{"class":42,"line":389},6,[40,391,392],{},"} ADC_Config;\n",[10,394,395],{},"Bitfields improve readability but have portability issues: the C standard does not specify the allocation order of bits within a byte, so the layout can differ between compilers. For hardware register access, explicit bitwise operations are safer and more predictable across toolchains.",[14,397,399],{"id":398},"practical-example-configuring-a-uart","Practical Example: Configuring a UART",[10,401,402],{},"A typical UART configuration register might look like this:",[165,404,405,418],{},[168,406,407],{},[171,408,409,412,415],{},[174,410,411],{},"Bits",[174,413,414],{},"Field",[174,416,417],{},"Values",[183,419,420,433,446,459],{},[171,421,422,427,430],{},[188,423,424],{},[40,425,426],{},"1:0",[188,428,429],{},"Parity",[188,431,432],{},"00=none, 01=even, 10=odd",[171,434,435,440,443],{},[188,436,437],{},[40,438,439],{},"3:2",[188,441,442],{},"Stop bits",[188,444,445],{},"00=1 bit, 01=1.5 bits, 10=2 bits",[171,447,448,453,456],{},[188,449,450],{},[40,451,452],{},"6:4",[188,454,455],{},"Data bits",[188,457,458],{},"000=5bit, 001=6bit, 010=7bit, 011=8bit",[171,460,461,466,469],{},[188,462,463],{},[40,464,465],{},"7",[188,467,468],{},"Enable",[188,470,471],{},"0=off, 1=on",[10,473,474],{},"Configuring 8-N-1 (8 data bits, no parity, 1 stop bit, enabled):",[30,476,478],{"className":32,"code":477,"language":34,"meta":35,"style":35},"UART_CFG = (1 \u003C\u003C 7)   \u002F\u002F enable\n         | (3 \u003C\u003C 4)   \u002F\u002F 8 data bits\n         | (0 \u003C\u003C 2)   \u002F\u002F 1 stop bit\n         | 0;         \u002F\u002F no parity\n\u002F\u002F Binary: 10110000 = 0xB0\n",[37,479,480,485,490,495,500],{"__ignoreMap":35},[40,481,482],{"class":42,"line":43},[40,483,484],{},"UART_CFG = (1 \u003C\u003C 7)   \u002F\u002F enable\n",[40,486,487],{"class":42,"line":49},[40,488,489],{},"         | (3 \u003C\u003C 4)   \u002F\u002F 8 data bits\n",[40,491,492],{"class":42,"line":55},[40,493,494],{},"         | (0 \u003C\u003C 2)   \u002F\u002F 1 stop bit\n",[40,496,497],{"class":42,"line":95},[40,498,499],{},"         | 0;         \u002F\u002F no parity\n",[40,501,502],{"class":42,"line":248},[40,503,504],{},"\u002F\u002F Binary: 10110000 = 0xB0\n",[14,506,508],{"id":507},"key-takeaways","Key Takeaways",[510,511,512,516,519,522],"ul",{},[513,514,515],"li",{},"Bitwise OR sets bits, AND with NOT clears bits, XOR toggles bits — these three operations cover most register manipulation tasks.",[513,517,518],{},"Multi-bit fields require a clear-then-set pattern: mask out the field bits with AND, then write the new value with OR.",[513,520,521],{},"Always respect protocol endianness; big-endian is standard for network and automotive buses.",[513,523,524],{},"Prefer explicit bitwise operations over C bitfields for hardware register access to avoid compiler-specific layout differences.",[14,526,528],{"id":527},"try-it-yourself","Try It Yourself",[10,530,531,532,537],{},"Need to convert register values or debug binary protocols? Use the ",[533,534,536],"a",{"href":535},"\u002Ftools\u002Ftext-binary","Text to Binary Converter"," to encode data, or check the reverse conversion to decode binary output from your embedded device.",[539,540,541],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":35,"searchDepth":49,"depth":49,"links":543},[544,550,551,552,553,554,555],{"id":16,"depth":49,"text":17,"children":545},[546,547,548,549],{"id":24,"depth":55,"text":25},{"id":68,"depth":55,"text":69},{"id":101,"depth":55,"text":102},{"id":123,"depth":55,"text":124},{"id":155,"depth":49,"text":156},{"id":266,"depth":49,"text":267},{"id":352,"depth":49,"text":353},{"id":398,"depth":49,"text":399},{"id":507,"depth":49,"text":508},{"id":527,"depth":49,"text":528},"2026-05-28","Working with binary representations in microcontroller programming and hardware interfaces.","md",{"immutable":560},true,"\u002Fguides\u002Fbinary-in-embedded-systems",{"title":5,"description":557},"guides\u002Fbinary-in-embedded-systems","F-pS-dYeYk71_T17W66tIvegllGAOltpOaXFiufhuHE",1780401331771]