主要內容:
1.指針變量及例子
2.指針變量---位帶操作
3.位帶別名區最低有效位
4.位帶操作另一種宏定義
1指針變量及例子
前面文章【STM32位帶操作】牽涉到的一個重要知識點就是指針變量。
這種位帶映射操作,就是操作映射過后的地址,其實就是操作指針變量。
指針變量:指存放地址的變量。
指針變量是一種特殊的變量,它不同于一般的變量,一般變量存放的是數據本身,而指針變量存放的是數據的地址。《摘自百度百科【指針變量】》
指針變量的例子
intmain(void){ uint32_t *p; p = (uint32_t *)(0x42210184); System_Initializes(); while(1) { *p =0; TIMDelay_Nms(500); *p =1; TIMDelay_Nms(500); }}
上面例子中給p指針變量賦的值是“0x42210184”,只是強制轉換成(uint32_t *)這種指針類型。
而*p = 0;代表該地址上的數據值為0;也就是上面說的該地址存放的數據為0;
前面有一個朋友問過我關于指針變量的問題,看到這里,相信你應該知道使用指針變量,直接打印指針就可以判斷指針是否越界。
2指針變量---位帶操作
上面代碼中“0x42210184”代表STM32F103系列芯片中PA1的位帶別名地址(就是映射過去的地址),截一個圖,大家看看:

提示:上圖中對p的賦值,其實是一樣的(在STM32中),都是0x42210184。
結合公式理解
上一篇文章【STM32位帶操作】列出了關于片上外設區計算公式:
AliasAddr = 0x42000000+(A-0x40000000)*32 + n*4
對比截圖中第一個p賦的值,就是片上外設的計算公式。
第二個p只是對代碼優化了:“&”到“-”的優化,可以看編譯器相關手冊。
第4個p就是上一節代碼中值,有沒有發現,位帶操作其實就操作指針變量啊?
這樣相比讀出寄存器,再&或者|再寫入寄存器的效率要高多啦?
3位帶別名區最低有效位
有朋友發現,*p = 0;這樣操作對地址0x42210184(PA1輸出)寫入0,PA1輸出低。假如我寫入0x10,那么PA1輸出多少呢?
答案:輸出低。
原因在于:在位帶區中,每個比特都映射到別名地址區的一個字只有 LSB 有效,也就是最低一位有效。
4位帶操作另一種宏定義
有通過昨天的兩個公式,可以推出下圖的公式:

上面框起來的定義適合RAM和外設兩種,假如定義一個LED為PA1,只需要將PA1相關參數傳入即可。
LED另外一種定義:
#define LED BIT_ADDR((GPIOA_BASE+ 12),1)
這種定義需要注意:+12,其實是ODR相對GPIOA的基地址的偏移地址。
我曾在這里遇到的坑:我將STM32F1的移植到F4上,出現了問題,我找了半天才發現由于這個偏移地址不一樣導致的。
STM32F1的ODR偏移是12,而F4的ODR偏移是20。所以,建議大家使用GPIOA->ODR這種方式。(不管是標準外設庫還是HAL庫都有這樣定義)。
-
STM32
+關注
關注
2309文章
11162瀏覽量
373404 -
LSB
+關注
關注
0文章
42瀏覽量
13745 -
指針變量
+關注
關注
0文章
17瀏覽量
7370
發布評論請先 登錄
C語言重點—指針篇
函數指針介紹
值傳遞、指針傳遞、引用傳遞介紹
函數指針與回調函數解讀
指針難學的4點原因分析
函數指針及指針函數的區別
如何用函數指針調用函數
GaAs 數字衰減器 5 位、1 dB LSB 400 MHz-4 GHz skyworksinc
帶驅動器的 10 MHz - 1.0 GHz 六位數字衰減器(0.5 dB LSB,31.5 dB 范圍) skyworksinc
0.7-4.0 GHz 五位數字衰減器,帶串轉并行驅動器 (0.5 dB LSB) skyworksinc
DC-3.0 GHz 六位數字衰減器,帶串行或并行驅動器 (0.5 dB LSB) skyworksinc
指針變量, 位帶指針 ,LSB最低有效位 ······
評論