音影先锋亚洲天堂网|电影世界尽头的爱完整版播放|国产 熟女 91|高清无码免费观看欧美日韩|韩国一区二区三区黄色录像|美女亚洲加勒比在线|亚洲综合网 开心五月|7x成人在线入口|成人网站免费日韩毛片区|国产黄片?一级?二级?三级

登錄 免費(fèi)注冊 首頁 | 行業(yè)黑名單 | 幫助
維庫電子市場網(wǎng)
技術(shù)交流 | 電路欣賞 | 工控天地 | 數(shù)字廣電 | 通信技術(shù) | 電源技術(shù) | 測控之家 | EMC技術(shù) | ARM技術(shù) | EDA技術(shù) | PCB技術(shù) | 嵌入式系統(tǒng)
驅(qū)動編程 | 集成電路 | 器件替換 | 模擬技術(shù) | 新手園地 | 單 片 機(jī) | DSP技術(shù) | MCU技術(shù) | IC 設(shè)計(jì) | IC 產(chǎn)業(yè) | CAN-bus/DeviceNe

有關(guān)volatile變量和const常量

作者:上善若水 欄目:ARM技術(shù)
有關(guān)volatile變量和const常量
看到《深入淺出ARM7—LPC213X/214X》上有很多外部變量前都加了volatile,很多常量定義都加了const,在通用的c語言里,加volatile是為了c編譯器的優(yōu)化器對數(shù)據(jù)流進(jìn)行分析,盡可能避免訪問存儲器,如果在程序中與訪問存儲器有關(guān)的代碼和用c語言書寫的代碼完全相同,必須使用volatile來標(biāo)明這些訪問,編譯器不能優(yōu)化任何對volatile變量的引用,而const則是對常量的定義。上面的解釋,是從書上抄下來的,并不明白。請解釋一下這樣用的必需性?如果不加這個定義可以嗎?

2樓: >>參與討論
eleven11
const只是添加只讀屬性
不會存到FLASH

3樓: >>參與討論
上善若水
請問eleven11
“const只是添加只讀屬性不會存到FLASH中”這樣做有什么好處呢?我如果把程序下載到RAM中調(diào)試呢?




4樓: >>參與討論
xiaoerge
volatile
使用關(guān)鍵詞__volatile限定的一個對象,可以告訴編譯器該對象可能在程序之外被修改,這樣編譯器在編譯時將不優(yōu)化對該操作對象的操作。對于系統(tǒng)中的IO寄存器,通常使用volatile類型的結(jié)構(gòu)來訪問。
                               ——《ARM體系結(jié)構(gòu)與編程》

5樓: >>參與討論
yamoon
const
const添加只讀屬性,以保證某些量不會被誤操作修改,同時可增加程序的可讀性

6樓: >>參與討論
上善若水
請問xiaoerge
我已經(jīng)從超星上下了這本《ARM體系結(jié)構(gòu)與編程》,但是周立功給出的很多示例程序,和IO寄存器無關(guān)的變量也用了volatile定義,還有“對象可能在程序之外被修改”,是不是說該變量和硬件有關(guān),可能因輸入信號的原因而改變,比如一個IO口設(shè)置為輸入,接收外部按鍵的信號?

7樓: >>參與討論
yyccaa
re
http://www.ithack.net/Articles/vc/200505042661.html
這篇文章可能解釋得比較清楚,以下這句比較符合實(shí)際使用(句子里的“內(nèi)存”可以理解為地址指向的存儲單元):
當(dāng)要求使用volatile 聲明的變量的值的時候,系統(tǒng)總是重新從它所在的內(nèi)存讀取數(shù)據(jù),即使它前面的指令剛剛從該處讀取過數(shù)據(jù)。而且讀取的數(shù)據(jù)立刻被保存。

8樓: >>參與討論
LPC900
我對volatile、code和const的理解
    volatile是ANSI C語言關(guān)鍵字之一。其作用可以用一句話來概括:用volatile修飾的變量可以防止被編譯器優(yōu)化。
    定義一個普通變量時,有可能被編譯器優(yōu)化成寄存器變量。如果加上volatile,那它一定是存儲器變量。
    編譯器可能會認(rèn)為某些語句是多余的,從而自動優(yōu)化掉。例如“{int x; x=57; x=24; ...}”,其中“x=57;”是多余的。如果加上volatile,則不會被優(yōu)化掉。
    某些全局變量,在中斷服務(wù)函數(shù)中可能會被隱含地改變。這樣的全局變量應(yīng)當(dāng)要用volatile修飾。主程序每次訪問該變量時,都可以確保是最新的值。
    存儲器映射的I/O變量,也可能會自動地改變。因此也要加上volatile屬性。

    code和const的區(qū)別。用code聲明的對象會被編譯器安排在ROM中,而ROM通常是只讀的,無法更改。用const聲明的對象可能會被安排在ROM中,但也可能在RAM中。如果在ROM中,當(dāng)然不能修改了;如果在RAM中,理論上仍然可以修改,只是編譯器不允許你去修改而已。const對象只能在聲明時初始化一次。


9樓: >>參與討論
dracoduan
樓上的說得很好,支持
volatile主要是在對寄存器或端口操作的程序里用的多,
比如設(shè)備驅(qū)動程序
const 主要是用于大容量的數(shù)據(jù)定義,比如字庫
當(dāng)然在ram不夠的時候也會用^_^


10樓: >>參與討論
上善若水
謝謝大家
大家講的我還要認(rèn)真體會,我想知道,如果我做個中等大小的程序,如果一些變量該設(shè)成volatile的沒設(shè)成(一些常量該設(shè)成const的沒設(shè)成)會導(dǎo)致什么后果?

11樓: >>參與討論
dracoduan
有可能一切正常
有可能你發(fā)現(xiàn)系統(tǒng)沒有像你想的那樣動作,示波器捕捉不到任何信號,最后通過反匯編才發(fā)現(xiàn)可惡的編譯器把你的一個關(guān)鍵操作給優(yōu)化掉了,針對volatile。

const更好理解了,正如同不是所有的PC機(jī)都有1G的內(nèi)存一樣,ram對于嵌入式系統(tǒng)更是珍貴資源,如果把那些字庫放在ram中我只能說你做設(shè)計(jì)太奢侈了(不過似乎學(xué)校里面的很多設(shè)計(jì)都是這樣的-_-b)

12樓: >>參與討論
chang123
hehe
hehe

13樓: >>參與討論
chang123
re
謝謝大家

大家講的我還要認(rèn)真體會,我想知道,如果我做個中等大小的程序,如果一些變量該設(shè)成volatile的沒設(shè)成(一些常量該設(shè)成const的沒設(shè)成)會導(dǎo)致什么后果?

回答如下:
1.如果一些變量該設(shè)成volatile的沒設(shè)成--通常會引起錯誤。
  當(dāng)I/O被映射成存儲器時,因?yàn)檫B續(xù)讀2次或者3次讀出的結(jié)果應(yīng)該不同。如串口第一次讀和第二次讀對應(yīng)的是不同的時刻所以數(shù)據(jù)也不同,所以不希望編譯器優(yōu)化。此時變量用volatile修飾。
2.一些常量該設(shè)成const的沒設(shè)成會導(dǎo)致什么后果,一般不會引起什么嚴(yán)重的后果。
但聲明為const后代碼可讀性好,并且變量不會被誤修改。


前面樓上的已經(jīng)說的很詳細(xì)了,你綜合著讀一下,應(yīng)該可以明白的。


14樓: >>參與討論
上善若水
請問dracoduan
我現(xiàn)在要定義一個數(shù)碼管的顯示數(shù)組是不是要加個const?
定義一個等待串口發(fā)送的常量數(shù)組是不是也要加個const?
謝謝

15樓: >>參與討論
上善若水
再問
加上了const的常量到底是存在了FLASH中還是ram中呢?如果“code和const的區(qū)別。用code聲明的對象會被編譯器安排在ROM中,而ROM通常是只讀的,無法更改。用const聲明的對象可能會被安排在ROM中,但也可能在RAM中。如果在ROM中,當(dāng)然不能修改了;如果在RAM中,理論上仍然可以修改,只是編譯器不允許你去修改而已。const對象只能在聲明時初始化一次!蹦嵌xconst常量對節(jié)省ram空間有什么意義呢?

為什么加上const能增加程序的可讀性呢?

16樓: >>參與討論
eleven11
const不會為你節(jié)省rom的空間
你看一下ads,const屬性的變量是放在data區(qū)的,而不是code區(qū),const不會為你節(jié)省rom的空間,他只是添加只讀屬性,函數(shù)參數(shù)添加const也可以,因?yàn)檫@只是添加只讀屬性

* - 本貼最后修改時間:2006-1-5 17:14:30 修改者:eleven11

17樓: >>參與討論
上善若水
請問eleven11
我試了半天也沒結(jié)果,請問eleven11:如何“看一下ads,const屬性的變量是放在data區(qū)的,而不是code區(qū)”?

另外,請您再具體說一下,把一個常量設(shè)置為只讀屬性的目的是什么?
謝謝

18樓: >>參與討論
上善若水
ADS不支持code類型嗎?
我把一個常量定義為code類型,想讓它存到rom中,以節(jié)省ram空間,但是ADS不認(rèn),并提示錯誤。請問大家,有什么辦法定義一個常量讓它存到程序存儲器里?

19樓: >>參與討論
zy315
結(jié)構(gòu)問題
ARM是馮若依漫結(jié)構(gòu),ROM和RAM統(tǒng)一編址,統(tǒng)一尋址,code/xdata/data/pdata/idata是針對哈佛結(jié)構(gòu)的存儲類型,是C51規(guī)定的存儲類型!你在ARM的編譯器中使用當(dāng)然會提示出錯了!

20樓: >>參與討論
上善若水
謝謝zy315
能對基本概念大徹大悟才是真正的高手啊。謝了。

21樓: >>參與討論
high
volatile
告訴編譯器,volatile定義的變量必須RAM變量.不能是寄存器變量.
尤其是中斷中使用的全局變量,一定要volatile.否則運(yùn)行結(jié)果有機(jī)會和設(shè)想不同.如果沒有調(diào)試經(jīng)驗(yàn),這種錯誤會讓您坐下來哭.

const 定義的全局變量,一些編譯器可以放到rom.
ads的可以.我已經(jīng)做過測試.


22樓: >>參與討論
上善若水
多謝high
"尤其是中斷中使用的全局變量,一定要volatile"真是幫了我的大忙了。擱淺了好久的一個程序,終于又能正常運(yùn)行了。
請問:
1、為了避免上述的錯誤發(fā)生,我把所有的全局變量都定義成volatile,會有什么壞的結(jié)果?

2、“ads的可以將const 定義的全局變量放到rom里”.我已經(jīng)做過測試.能不能簡要的說說是如何在ads查看一個常量或變量是放在rom還是ram里的?

3、const不是只能定義常量嗎?也能定義變量?


23樓: >>參與討論
computer00
re:
1.“把所有的全局變量都定義成volatile”,如果你的變量本來不需要回寫,你卻弄成volatile的,
   那么程序在執(zhí)行時,就會頻繁操作內(nèi)存,這樣就大大降低了程序運(yùn)行速度。如果不是volatile的,
   則可能暫時放在寄存器中,等運(yùn)行完了或者寄存器不夠用時,再將變量寫回RAM,這樣程序就運(yùn)行快了。

2.不知道ads有沒有FLASH關(guān)鍵詞?有些編譯器可使用FLASH關(guān)鍵詞將常量放在ROM中。

3.const只是修飾一個特殊的變量,這個變量的值是不能(直接)改變的。但也許通過其它方式改變它,例如指針。
  當(dāng)然,如果const的值被放入了ROM,那么就不能改變了。

24樓: >>參與討論
javie
蛋蛋總結(jié)的第一條對大家很有幫助
我以前就犯過這種錯誤

25樓: >>參與討論
high
ads應(yīng)該不支持FLASH
記得iar的可以FLASH關(guān)鍵字.

整了一個全局大數(shù)組,1k以上.const前后.編譯結(jié)果不同.



26樓: >>參與討論
上善若水
感謝圈圈多次解答我問題
1、前面的朋友,說的都很好,我琢磨了這幾天還是不太能準(zhǔn)確的理解,請大家能不能在給我舉出象一樣"尤其是中斷中使用的全局變量,一定要volatile" 其它的哪些情況下,必須把變量定義為volatile和const類型。

2、我剛試過了ads的確沒有FLASH關(guān)鍵詞。

27樓: >>參與討論
computer00
在程序不知情的情況下,那個變量的值會改變時;
或者兩次同樣的寫操作,會產(chǎn)生不同的作用時,要聲明為volatile。

例如一些標(biāo)志寄存器、IO口寄存器、硬件會修改的一些寄存器等等。

28樓: >>參與討論
melearn
再問一下
“優(yōu)化”是不是有“改變”的意思,我總看到優(yōu)化這個詞,具體是什么意思還是沒有真正明白,樓上誰能解釋一下啊

29樓: >>參與討論
上善若水
再問圈圈
1、“IO口寄存器、硬件會修改的一些寄存器”會在程序不知情的情況下發(fā)生改變,這不難理解,但是一些當(dāng)標(biāo)志的變量為什么會在程序不知情的情況下改變呢?“中斷中使用的全局變量”發(fā)生改變時,程序也是知道的啊,只是主程序不知吧?

2、具體的說,在什么情況下必須聲明const類型?


30樓: >>參與討論
computer00
re:
1.因?yàn)椴恢乐袛嗪螘r發(fā)生,所以也不知道這個(全局)變量何時被改變了。

2.const用來修飾你的變量不被其它地方意外的改變。有些時候干脆定義成宏。

31樓: >>參與討論
hongyezhai
還是不明白
看了半天還是不明白到底怎么做才能把常量放在FLASH中,而不放在ram中,請高手講明白點(diǎn)!

32樓: >>參與討論
上善若水
還是圈圈說得明白!
關(guān)于volatile我基本明白了。
關(guān)于const,我看到很多的示例程序,除了修飾一些“不希望在其它地方意外改變的變量”外,還看到把很多大的數(shù)組,比如,數(shù)碼管顯示的表格,定義成const,這種作法是不是為了“const 定義的全局變量,一些編譯器可以放到rom.”以節(jié)省ram空間?


33樓: >>參與討論
William47
很有深度
const的意思是聲名了程序不能改變該變量的值
volatile的意思是改變量可能被意外的改變,例如硬件的寄存器就可能這樣,程序不能改變。

兩個同時用就是程序不能改變改變量的值,但該變量的值可能會意外的改變。

34樓: >>參與討論
上善若水
const常量呢?
在很多示例程序里,大多是常量加const來修飾,比如:
const uint32 LEDS=(0xff<<18);
常量就算不加const修飾,程序應(yīng)該也不會改變它的值吧。那加const來修飾常量的用意何在呢?難道不是為了把這個常量放到rom里嗎?
William47對此怎么看


35樓: >>參與討論
computer00
因?yàn)長EDS是不需要改變的,所以設(shè)置為const。
有些編譯器可以設(shè)置const的保存在ROM中,而有些則只能保存在RAM中。

加上const,增加了程序的可讀性,別人一看聲明,就知道是個常量,下面將拿它做常量使用。

36樓: >>參與討論
William47
const
如果聲名const在程序中如果出現(xiàn)復(fù)職語句之類的試圖改變變量值的語句
編譯器就會報(bào)錯。

看看下面這個
const int a      //定義一個const
const int* a;    //指向一個const的指針,指針能變但a不能變
int const *a;    //和上面一樣
int* const a = &b;    //一個指向整數(shù)變量常指針,b能變
const int* const a;   //指向常整數(shù)的常指針
最后一個有點(diǎn)變態(tài)    


如果為了將變量放到rom里面
keil c51有專用的關(guān)鍵字 code,不缺決于const.

至于ADS把const放不放到rom里面要看他的編譯器優(yōu)化策略。也可能這個const會被編譯器優(yōu)化成一個寄存器值,甚至立即數(shù)。


37樓: >>參與討論
xiaoerge
呵呵,大有收獲啊
 
38樓: >>參與討論
上善若水
請問William47
對于const int* a;    //指向一個const的指針,指針能變但a不能變
給a付值:a=&b;b的值能改變嗎?


39樓: >>參與討論
William47
不能
這里指的就是const int b;

40樓: >>參與討論
aoarm
const 定義的變量在CODE中的,我試了好多變都是這樣的
 
41樓: >>參與討論
hotpower
哈哈,看錯了,被忽悠了
 

* - 本貼最后修改時間:2006-1-21 13:39:02 修改者:hotpower

42樓: >>參與討論
上善若水
請問aoarm
您是怎么測試出“const 定義的變量在CODE中的”?讓我學(xué)習(xí)學(xué)習(xí)。

43樓: >>參與討論
上善若水
轉(zhuǎn)貼
[單片機(jī)]volatile 實(shí)例講解(原創(chuàng))(li3)
[日期:2005-12-31] 來源:水影的筆記  作者:水影 [字體:大 中 小]  

volatile的本意是一般有兩種說法--1.“暫態(tài)的”;2.“易變的”。
這兩種說法都有可行。但是究竟volatile是什么意思,現(xiàn)舉例說明(以Keil-c與a51為例 例子來自Keil FQA),看完例子后你應(yīng)該明白volatile的意思了,如果還不明白,那只好 再看一遍了。

例1.

void main (void)
{
volatile int i;
int j;

i = 1;  //1  不被優(yōu)化 i=1
i = 2;  //2  不被優(yōu)化 i=1
i = 3;  //3  不被優(yōu)化 i=1

j = 1;  //4  被優(yōu)化
j = 2;  //5  被優(yōu)化
j = 3;  //6  j = 3
}
---------------------------------------------------------------------
例2.

函數(shù):

void func (void)
{
unsigned CHAR xdata xdata_junk;
unsigned CHAR xdata *p = &xdata_junk;
unsigned CHAR t1, t2;

t1 = *p;
t2 = *p;
}

編譯的匯編為:

0000 7E00    R     MOV     R6,#HIGH xdata_junk
0002 7F00    R     MOV     R7,#LOW xdata_junk
;---- Variable ’p’ assigned to Register ’R6/R7’ ----

0004 8F82          MOV     DPL,R7
0006 8E83          MOV     DPH,R6

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 注意
0008 E0            MOVX    A,@DPTR
0009 F500    R     MOV     t1,A

000B F500    R     MOV     t2,A
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
000D 22            RET      

將函數(shù)變?yōu)椋?
void func (void)
{
volatile unsigned CHAR xdata xdata_junk;
volatile unsigned CHAR xdata *p = &xdata_junk;
unsigned CHAR t1, t2;

t1 = *p;
t2 = *p;
}

編譯的匯編為:
0000 7E00    R     MOV     R6,#HIGH xdata_junk
0002 7F00    R     MOV     R7,#LOW xdata_junk
;---- Variable ’p’ assigned to Register ’R6/R7’ ----

0004 8F82          MOV     DPL,R7
0006 8E83          MOV     DPH,R6

;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
0008 E0            MOVX    A,@DPTR
0009 F500    R     MOV     t1,A        ;a處

000B E0            MOVX    A,@DPTR
000C F500    R     MOV     t2,A
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

000E 22            RET      


比較結(jié)果可以看出來,未用volatile關(guān)鍵字時,只從*p所指的地址讀一次
如在a處*p的內(nèi)容有變化,則t2得到的則不是真正*p的內(nèi)容。

---------------------------------------------------------------------
例3


volatile unsigned CHAR bdata var;  // use volatile keyword here
sbit var_0 = var^0;
sbit var_1 = var^1;
unsigned CHAR xdata values[10];

void main (void)  {
  unsigned CHAR i;

  for (i = 0; i < sizeof (values); i++)  {
    var = values[i];
    if (var_0)  {
      var_1 = 1; //a處
        
      values[i] = var;  // without the volatile keyword, the compiler
                        // assumes that ’var’ is unmodified and does not
                        // reload the variable content.
    }
  }
}


在此例中,如在a處到下一句運(yùn)行前,var如有變化則不會,如var=0xff; 則在
values[i] = var;得到的還是values[i] = 1;

---------------------------------------------------------------------
應(yīng)用舉例:

例1.
#define DBYTE ((unsigned CHAR volatile data  *) 0)

說明:此處不用volatile關(guān)鍵字,可能得不到真正的內(nèi)容。
---------------------------------------------------------------------

例2.


#define TEST_VOLATILE_C  

//***************************************************************
// verwendete Include Dateien
//***************************************************************
#if __C51__ < 600
  #error: !! Keil 版本不正確
#endif

//***************************************************************
// 函數(shù) void v_IntOccured(void)
//***************************************************************
extern void v_IntOccured(void);

//***************************************************************
// 變量定義
//***************************************************************
CHAR xdata cValue1;          //全局xdata
CHAR volatile xdata cValue2; //全局xdata

//***************************************************************
// 函數(shù): v_ExtInt0()
// 版本:
// 參數(shù):
// 用途:cValue1++,cValue2++
//***************************************************************
void v_ExtInt0(void) interrupt 0 {
  cValue1++;
  cValue2++;  
}  

//***************************************************************
// 函數(shù): main()
// 版本:
// 參數(shù):
// 用途:測試volatile
//***************************************************************

void main() {
CHAR cErg;

//1. 使cErg=cValue1;
cErg = cValue1;

//2. 在此處仿真時手動產(chǎn)生中斷INT0,使cValue1++; cValue2++
if (cValue1 != cErg)
  v_IntOccured();

//3. 使cErg=cValue2;
cErg = cValue2;

//4. 在此處仿真時手動產(chǎn)生中斷INT0,使cValue1++; cValue2++
if (cValue2 != cErg)
  v_IntOccured();
   
//5. 完成
  while (1);
}

//***************************************************************
// 函數(shù): v_IntOccured()
// 版本:
// 參數(shù):
// 用途: 死循環(huán)
//***************************************************************
void v_IntOccured() {
  while(1);
}

仿真可以看出,在沒有用volatile時,即2處,程序不能進(jìn)入v_IntOccured();
但在4處可以進(jìn)入v_IntOccured();  



44樓: >>參與討論
bird67

const定義視分散加載文件情況而定。

如果分散加載文件將代碼都放到RAM里執(zhí)行,即使你聲明的是const類型,也被放到了RAM。

如果分散加載文件將代碼都放到ROM里執(zhí)行,則當(dāng)被聲明的變量為const類型時,編譯器將其放到ROM中,如果被聲明的變量為非const類型,則編譯器將其放到RAM里。

參與討論
昵稱:
討論內(nèi)容:
 
 
相關(guān)帖子
求助:lpc2138的JTAG調(diào)試
如何才能通過串口將我的程序下載到LPC2210的片外flash?
高手求助!一改VPB頻率,就出現(xiàn)錯誤。!
定時器捕獲功能可不可以連續(xù)捕獲?
2119定時器捕獲
免費(fèi)注冊為維庫電子開發(fā)網(wǎng)會員,參與電子工程師社區(qū)討論,點(diǎn)此進(jìn)入


Copyright © 1998-2006 m.58mhw.cn 浙ICP證030469號