<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 一個(gè)從定時(shí)計(jì)數(shù)器賦初值引起的故事

          一個(gè)從定時(shí)計(jì)數(shù)器賦初值引起的故事

          作者: 時(shí)間:2016-11-29 來源:網(wǎng)絡(luò) 收藏
          最近單片機(jī)課講到了定時(shí)計(jì)數(shù)器,在C語言中定時(shí)計(jì)數(shù)器的初值可以采用這種方式(假設(shè)計(jì)數(shù)10000次)TH0=(65536-10000)/256;TL0=(65536-10000)%256;這是通用的方法,65536-10000=55536=0xD8F0;賦值后TH0=0xD8,TL0=0xF0。我聯(lián)想到補(bǔ)碼的規(guī)則,65536-10000的數(shù)值在計(jì)算機(jī)中和-10000數(shù)據(jù)存儲(chǔ)是一樣的,于是我就簡單賦值為TH0=(-10000)/256.;TL0=(-10000)%256;可以少寫一個(gè)數(shù)據(jù),減少敲字的工作。我就這樣給學(xué)生講了。這兩種方法都可以。

          在一天李老師看到我的學(xué)生作業(yè)都是寫TH0=(-10000)/256.;TL0=(-10000)%256;她說-10000可能使用不對(duì)。當(dāng)天晚上的時(shí)候在QQ上發(fā)消息過來說,經(jīng)驗(yàn)證,在Keil中,TH0=(65536-10000)/256;TL0=(65536-10000)%256;的賦值方式TH0=0xD8,TL0=0xF0。但是TH0=(-10000)/256.;TL0=(-10000)%256;的賦值方式TH0=0xD9,TL0=0xF0。TH0的數(shù)值總是要大1,而且取不同的數(shù)值驗(yàn)證均是這個(gè)結(jié)果,兩種方式TH0總是相差1,而TL0數(shù)值是一樣的。我打開Keil,輸入程序,然后調(diào)試查看匯編指令,得到如下結(jié)果:

          本文引用地址:http://www.ex-cimer.com/article/201611/323235.htm

          8: TH0=(65536-10000)/256;
          C:0x009B 758CD8 MOV TH0(0x8C),#0xD8
          9: TH1=(-10000)/256;
          C:0x009E 758DD9 MOV TH1(0x8D),#0xD9

          發(fā)現(xiàn)匯編指令直接對(duì)于TH0和TH1進(jìn)行賦值,沒有經(jīng)過任何的運(yùn)算,但是就是相差1,這是為什么呢?我無法理解,后來在百度知道上提問,得到的回答是:這個(gè)和默認(rèn)數(shù)據(jù)類型有關(guān),TH0=(65536-10000)/256,默認(rèn)unsigned char,即TH0=0xD8;TH0=(-10000)/256,默認(rèn)signed char,二進(jìn)制最高位為符號(hào)位,負(fù)數(shù)為1,所以TH0=0xD9 。

          原來是Keil編譯器計(jì)算數(shù)據(jù)的時(shí)候默認(rèn)的數(shù)據(jù)類型不一樣,65536-10000=55536是unsigned類型,55536/256=216=0xD8,而-10000是signed類型,(-10000)/256=-39=0xD9。原來如此,Keil的編譯器預(yù)先處理的時(shí)候根據(jù)不同類型的數(shù)據(jù)進(jìn)行了不同的運(yùn)算,然后直接賦值。我又驗(yàn)證了一下,TH0=(unsigned int)(-10000)/256;發(fā)現(xiàn)先把-10000強(qiáng)制轉(zhuǎn)換為unsigned類型后,得到的結(jié)果就是正確的了TH0=0xD8。得到答案后臉紅了,不過多虧是在放假期間,沒有學(xué)生看到。開學(xué)后立即在課堂上更正了。╮(╯▽╰)╭,這次糗大了。

          我重新寫了一個(gè)程序,#include
          void main()
          {
          unsigned int i;
          unsigned char j;
          i= - 10000;
          j=i/256;

          while(1)
          ;
          }

          中間加一個(gè)變量,看Keil會(huì)怎么處理,結(jié)果發(fā)現(xiàn)

          2: void main()
          3: {
          4: unsigned int i;
          5: unsigned char j;
          6: i=-10000;
          C:0x000F 7ED8 MOV R6,#0xD8
          7: j=i/256;
          8:
          C:0x0011 8E08 MOV 0x08,R6
          9: while(1)
          C:0x0013 80FE SJMP C:0013

          還是直接賦值,編譯器太聰明了,知道80C51對(duì)于數(shù)據(jù)運(yùn)算非常非常的不擅長,于是直接處理完數(shù)據(jù),然后用賦值的方式來寫匯編的指令。而且還知道,i的低字節(jié)沒有用到,在指令里根本沒有出現(xiàn),這也太聰明了吧。Keil軟件是最流行,最好用的編譯器,不是浪得虛名的。

          我再修改:

          include
          void main()
          {
          unsigned int i;
          unsigned char j;
          i=-10000;
          i++;
          j=i/256;

          while(1)
          ;
          }

          結(jié)果發(fā)現(xiàn)代碼只增加了一點(diǎn)。

          2: void main()
          3: {
          4: unsigned int i;
          5: unsigned char j;
          6: i=-10000;
          C:0x0003 7FF0 MOV R7,#B(0xF0)
          C:0x0005 7ED8 MOV R6,#0xD8
          7: i++;
          C:0x0007 0F INC R7
          C:0x0008 BF0001 CJNE R7,#0x00,C:000C
          C:0x000B 0E INC R6
          8: j=i/256;
          9:
          C:0x000C 8E08 MOV 0x08,R6
          10: while(1)
          C:0x000E 80FE SJMP C:000E

          但對(duì)于j的運(yùn)算還是用賦值的方式。我再改,把i類型變成signed類型,結(jié)果大吃一驚:

          include
          void main()
          {
          int i;
          unsigned char j;
          i=-10000;

          j=i/256;

          while(1)
          ;
          }


          上一頁 1 2 下一頁

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();