數值
無號
0
有號
0
位元圖
點一下位元就會翻轉,下面所有表示法同步更新。
運算
位元運算
位移與旋轉
A
0x00
A 永遠是上面那個數值。
結果
二進位
0b0000_0000
十六進位
0x00
十進位
0
暫存器位元欄位檢視
版面只要寫一次,上面的數值一改就自動解碼。
用 name:width 以逗號分隔,從最高位的欄位開始寫;寬度總和不能超過目前的位元寬度。
已存版面
只存在這台瀏覽器裡(localStorage),清掉網站資料或換瀏覽器就會不見。
還沒有存過任何版面。
AND、OR、XOR、位移,加上點得動的位元格網——還有 bitfield 檢視器,直接把眼前那顆暫存器拆給你看。
檔案不會離開你的瀏覽器 — 全部在本機處理。
數值
無號
0
有號
0
位元圖
點一下位元就會翻轉,下面所有表示法同步更新。
運算
位元運算
位移與旋轉
A
0x00
A 永遠是上面那個數值。
結果
二進位
0b0000_0000
十六進位
0x00
十進位
0
暫存器位元欄位檢視
版面只要寫一次,上面的數值一改就自動解碼。
用 name:width 以逗號分隔,從最高位的欄位開始寫;寬度總和不能超過目前的位元寬度。
已存版面
只存在這台瀏覽器裡(localStorage),清掉網站資料或換瀏覽器就會不見。
還沒有存過任何版面。
datasheet 開著,暫存器讀回來是 0x3F80,你要知道的只有一件事:每個欄位在說什麼。把值貼上來,欄位配置只寫一次——reserved:1, mode:3, prescaler:4, enable:1, status:7——每個欄位就會列出自己的位元範圍、原始 2 進位,以及 10 進位與 16 進位的值。配置存在你的瀏覽器裡,所以你翻 reference manual 第 412 頁時打進去的那組定義,下週還在。下次這個值出現在 log 裡,你兩秒就解完,不用在紙上一個 nibble 一個 nibble 數。
signed 與 unsigned 兩種讀法是並排放的,不是藏在切換鈕後面。0xFF 同時是 255 也是 −1,哪個才對完全看產生它的那段程式碼把變數宣告成什麼;抓錯邊是一整類 bug——把 −1 °C 報成 255 的感測器、看起來大到不合理的狀態欄位。兩欄同時看得到,這件事就從「你會犯的錯」變成「你能回答的問題」:unsigned 那欄是 65,535、signed 那欄是 −1,你就知道自己在看什麼了。
寬度不是裝飾。1 << 40 在 32-bit 是 0,在 64-bit 是 1,099,511,627,776;NOT 0x0F 在一個位元組裡是 0xF0,在一個 word 裡是 0xFFFFFFF0;負數右移的結果也要看它住在幾個位元裡。JavaScript 自己的 <<、>>、& 會在開算之前先把每個運算元砍成 32-bit,這就是一堆網頁計算機的 64-bit 答案默默算錯的原因——1 << 31 變成負數,超過 2^32 的東西直接歸零。這頁全部用 BigInt 算,算完才按你選的寬度做遮罩,所以 64-bit 的結果是精確的,8-bit 也會像真正的 uint8_t 那樣繞回去。
盯著螢幕上的 0b0011_1111_1000_0000 判斷 bit 7 有沒有立起來,正是凌晨兩點的人類最容易數錯的那種事。所以這裡有點得動的位元格網:每個 bit 都是一格、上面標著編號,點一下就翻,2 進位、10 進位、16 進位、signed 與 unsigned 的讀法,還有 bitfield 的逐欄解碼,全部一起更新。所有計算都在你的瀏覽器裡完成,這頁是靜態檔案,背後沒有 API——這點在這裡是真的有差:還沒發表的硬體,暫存器值本身就是機密,而你在逆推某顆 peripheral 時取的那些欄位名字,洩漏的資訊跟數字一樣多。
>> 和 >>> 差在哪裡?>> 是算術位移:它會把符號位元複製到上面空出來的位元,符號因此保住,所以 -8 >> 1 是 -4,負的還是負的。>>> 是邏輯位移,上面一律補 0,同一組位元模式滑下來就變成一個很大的正數。值是正的時候兩者結果一樣,所以差別要等最高位元立起來才咬人。C 只有一個 >>,行為由型別決定——signed 走算術、unsigned 走邏輯——所以這頁把寬度和有沒有符號都攤在檯面上,不讓它靠猜。
1 << 31 在 JavaScript 是負的,在這裡不是?因為 JavaScript 的位元運算子會先把運算元轉成 32-bit 有號整數。1 << 31 立起 32-bit signed 的最高位元,也就是符號位元,所以印出來是 −2147483648;再往前一步,1 << 32 又回到 1,因為位移量會對 32 取餘數。這台計算機用 BigInt 算,算完才套上你選的寬度,所以 32-bit 時 unsigned 那欄是 2,147,483,648、旁邊擺著 −2,147,483,648;64-bit 的 1 << 40 是實實在在的 1,099,511,627,776,不是 0。
一個欄位一組 name:width,用逗號隔開:status:4, error:1, reserved:3 就是一顆 8-bit 的暫存器。順序照 datasheet 畫的那樣,從最高位元往下排,各欄寬度加起來要剛好等於你選的暫存器寬度——少了或爆了,工具會直接告訴你。不在意的空隙就用 reserved: 填掉;把它留在配置裡,下面那些欄位的位元位置才不會跑掉。每組存下來的配置都有自己的名字,所以同一顆晶片的 CTRL1、STATUS、FIFO_CFG 可以並排放著。
因為你剛把值貼上來的那一刻,常常還不知道答案。從 serial dump 撈出來的一個位元組就只是八個位元;0xFE 是 254 還是 −2,取決於寫出它的那段程式碼,不是位元本身的性質。逼你先選,就是有一定機率選錯而且不會發現,因為兩種讀法單獨看都很合理。並排擺出來,0xFE 是 254 和 −2,哪個對得上物理量一眼就看出來——位元組數不會是負的,溫度會。
改的是每個結果要套的遮罩,連帶改了符號位元的位置。8-bit 時 0x1FF 會被切成 0xFF、NOT 0 是 0xFF、signed 的讀法從 0x80 開始變負;64-bit 時同樣的運算保留全部 64 個位元,符號位元是 bit 63。位移也會跟著變,因為被推出寬度上緣的位元是直接丟掉、不會記著——uint16_t 暫存器對它們做的就是這件事。切換寬度之後,2 進位、16 進位、位元格網、bitfield 解碼,每一塊都會用新的寬度重算。
不會。這頁是靜態檔案,計算全在你的瀏覽器裡完成,存下來的欄位配置放在瀏覽器的 localStorage,不會離開這台機器,也沒有帳號要登入。代價是它綁瀏覽器、綁使用者設定檔:清掉網站資料就沒了,你在筆電上定義的配置也不會出現在桌機上。所以真的不想再從 datasheet 打一遍的配置,自己留一份備份。