之前為大家分享的《Cortex-M位帶操作的原理》,雖然現(xiàn)在不常用位帶操作了,但里面很多知識(shí)點(diǎn)值得學(xué)習(xí)和了解。
指針變量及例子
位帶操作牽涉到的一個(gè)重要知識(shí)點(diǎn)就是指針變量。
這種位帶映射操作,就是操作映射過后的地址,其實(shí)就是操作指針變量(存放地址的變量)。
指針變量是一種特殊的變量,它不同于一般的變量,一般變量存放的是數(shù)據(jù)本身,而指針變量存放的是數(shù)據(jù)的地址。《摘自百度百科【指針變量】》
指針變量的例子:
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”,只是強(qiáng)制轉(zhuǎn)換成(uint32_t *)這種指針類型。
而*p = 0;代表該地址上的數(shù)據(jù)值為0;也就是上面說的該地址存放的數(shù)據(jù)為0;
前面有一個(gè)朋友問過我關(guān)于指針變量的問題,看到這里,相信你應(yīng)該知道使用指針變量,直接打印指針就可以判斷指針是否越界。
指針變量---位帶操作
上面代碼中“0x42210184”代表STM32F103系列芯片中PA1的位帶別名地址(就是映射過去的地址),截一個(gè)圖,大家看看:
提示:上圖中對(duì)p的賦值,其實(shí)是一樣的(在STM32中),都是0x42210184。
結(jié)合公式理解:
之前文章《位帶操作原理》列出了關(guān)于片上外設(shè)區(qū)計(jì)算公式:
AliasAddr = 0x42000000+(A-0x40000000)*32 + n*4
對(duì)比截圖中第一個(gè)p賦的值,就是片上外設(shè)的計(jì)算公式。
第二個(gè)p只是對(duì)代碼優(yōu)化了:“ ”到“-”的優(yōu)化,可以看編譯器相關(guān)手冊(cè)。
第4個(gè)p就是上一節(jié)代碼中值,有沒有發(fā)現(xiàn),位帶操作其實(shí)就操作指針變量???
這樣相比讀出寄存器,再 或者|再寫入寄存器的效率要高多啦?
位帶別名區(qū)最低有效位
有朋友發(fā)現(xiàn),*p = 0;這樣操作對(duì)地址0x42210184(PA1輸出)寫入0,PA1輸出低。假如我寫入0x10,那么PA1輸出多少呢?
答案:輸出低。
原因在于:在位帶區(qū)中,每個(gè)比特都映射到別名地址區(qū)的一個(gè)字只有 LSB 有效,也就是最低一位有效。
位帶操作另一種宏定義
有通過之前的兩個(gè)公式,可以推出下圖的公式:
上面框起來的定義適合RAM和外設(shè)兩種,假如定義一個(gè)LED為PA1,只需要將PA1相關(guān)參數(shù)傳入即可。
LED另外一種定義:
#define LED BIT_ADDR((GPIOA_BASE+ 12),1)
這種定義需要注意:+12,其實(shí)是ODR相對(duì)GPIOA的基地址的偏移地址。
我曾在這里遇到的坑:我將STM32F1的移植到F4上,出現(xiàn)了問題,我找了半天才發(fā)現(xiàn)由于這個(gè)偏移地址不一樣導(dǎo)致的。
STM32F1的ODR偏移是12,而F4的ODR偏移是20。所以,建議大家使用GPIOA->ODR這種方式。(不管是標(biāo)準(zhǔn)外設(shè)庫還是HAL庫都有這樣定義)。
來源:strongerHuang
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問題,請(qǐng)聯(lián)系小編進(jìn)行處理(聯(lián)系郵箱:cathy@eetrend.com)。
審核編輯 黃宇
-
led
+關(guān)注
關(guān)注
240文章
23062瀏覽量
657055 -
單片機(jī)
+關(guān)注
關(guān)注
6030文章
44489瀏覽量
631981 -
指針
+關(guān)注
關(guān)注
1文章
478瀏覽量
70491 -
指針變量
+關(guān)注
關(guān)注
0文章
17瀏覽量
7227
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論