首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

單片機 C 語言:如何宣告固定記憶體位址的變數

     編輯:關於C

前言

在嵌入式開發中,常需將變數精確映射到特定硬體暫存器或記憶體位址(如記憶體映射 I/O、共享記憶體區域)。本文整理三大主流單片機平台的寫法。

方法一:指標指向位址法(通用)

利用指標直接指向絕對位址,適用於所有支援 C 語言的單片機:

// 定義位址常數
#define ADDR1 0x10
#define ADDR2 0x11

// 宣告指標並指向固定位址
int8_t *pRStu1 = (int8_t *)ADDR1;   // 8 位元變數
int16_t *pRStu2 = (int16_t *)ADDR2; // 16 位元變數

優點:標準 C 寫法,跨平台可移植。
缺點:每次存取需解參考,語法稍繁瑣。

方法二:Keil C51 專用 _at_ 關鍵字

51 單片機在 Keil 編譯器下可直接指定變數位址:

uint8_t RStu1 _at_ 0x10;  // 直接映射到位址 0x10
uint16_t RStu2 _at_ 0x11; // 直接映射到位址 0x11

編譯器會自動安排該變數於指定位址,存取如同普通變數般直觀。

方法三:STVD (STM8) 專用巨集 DEF_8BIT_REG_AT

STM8 在 STVD/RAISONANCE 環境下使用特定巨集:

DEF_8BIT_REG_AT(RStu1, 0x10);  // 8 位元暫存器
DEF_16BIT_REG_AT(RStu2, 0x11); // 16 位元暫存器

這些巨集定義於 STM8 的標準函式庫標頭檔中,實質上也是將變數置於指定位址。

最佳實踐建議

  1. 定義位址常數:使用 #define 或 enum 集中管理位址,便於維護。
  2. 封裝存取函數:對指標法,建議封裝 ReadReg(addr)/WriteReg(addr, val) 宏或函數,統一處理 volatile、資料對齊等細節。
  3. 注意 volatile:映射硬體暫存器時,務必加上 volatile 防止編譯器優化導致異常。

程式碼範本(通用指標法 + volatile)

#define REG_BASE 0x40000000
#define UART_DR  (*(volatile uint32_t *)(REG_BASE + 0x00))
#define UART_SR  (*(volatile uint32_t *)(REG_BASE + 0x04))

// 使用範例
void uart_send(uint8_t data) {
    while (!(UART_SR & 0x80)); // 等待發送緩衝區空
    UART_DR = data;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved