久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

C51編譯器bug?

 guitarhua 2016-07-12
C51編譯器bug
三段代碼如下,,不明白為什么第一段代碼會(huì)有問題?

void Ext_INT0 (void) interrupt INT0_VECTOR
{
  unsigned char pos=5-(P3&0x07);
 display_buffer[pos]=P1;//有問題,,偶爾出現(xiàn)數(shù)據(jù)讀取出錯(cuò)
}

void Ext_INT1 (void) interrupt INT1_VECTOR
{
unsigned char pos=5-(P3&0x07);
display_buffer[pos]=P1&0x0f;//沒問題,,功能正常
}

void Ext_IN0T2 (void) interrupt INT2_VECTOR //
{
unsigned char pos=5-(P3&0x07);
unsigned char value=P1;
display_buffer[pos]=value;//沒問題,功能正常
}

編譯后的匯編代碼如下
    28: void Ext_INT0 (void) interrupt INT0_VECTOR            //進(jìn)中斷時(shí)已經(jīng)清除標(biāo)志 
    29: { 
C:0x048F    C0E0     PUSH     ACC(0xE0)
C:0x0491    C0D0     PUSH     PSW(0xD0)
C:0x0493    75D000   MOV      PSW(0xD0),#0x00
C:0x0496    C000     PUSH     0x00
C:0x0498    C007     PUSH     0x07
    30:                 unsigned char pos=5-(P3&0x07); 
C:0x049A    E5B0     MOV      A,P3(0xB0)
C:0x049C    5407     ANL      A,#0x07
C:0x049E    FF       MOV      R7,A
C:0x049F    C3       CLR      C
C:0x04A0    7405     MOV      A,#0x05
C:0x04A2    9F       SUBB     A,R7
    31:           display_buffer[pos]=P1; 
C:0x04A3    2431     ADD      A,#display_buffer(0x31)
C:0x04A5    F8       MOV      R0,A
C:0x04A6    A690     MOV      @R0,P1(0x90)
    32: } 
C:0x04A8    D007     POP      0x07
C:0x04AA    D000     POP      0x00
C:0x04AC    D0D0     POP      PSW(0xD0)
C:0x04AE    D0E0     POP      ACC(0xE0)
C:0x04B0    32       RETI     


    35: void Ext_INT1 (void) interrupt INT1_VECTOR            //進(jìn)中斷時(shí)已經(jīng)清除標(biāo)志 
    36: { 
C:0x001D    C0E0     PUSH     ACC(0xE0)
C:0x001F    C0D0     PUSH     PSW(0xD0)
C:0x0021    75D000   MOV      PSW(0xD0),#0x00
C:0x0024    C000     PUSH     0x00
C:0x0026    C006     PUSH     0x06
C:0x0028    C007     PUSH     0x07
    37:                 unsigned char pos=5-(P3&0x07); 
C:0x002A    E5B0     MOV      A,P3(0xB0)
C:0x002C    5407     ANL      A,#0x07
C:0x002E    FF       MOV      R7,A
C:0x002F    C3       CLR      C
C:0x0030    7405     MOV      A,#0x05
C:0x0032    9F       SUBB     A,R7
C:0x0033    FF       MOV      R7,A
    38:                 display_buffer[pos]=P1&0x0f; 
C:0x0034    E590     MOV      A,P1(0x90)
C:0x0036    540F     ANL      A,#0x0F
C:0x0038    FE       MOV      R6,A
C:0x0039    7431     MOV      A,#display_buffer(0x31)
C:0x003B    2F       ADD      A,R7
C:0x003C    F8       MOV      R0,A
C:0x003D    A606     MOV      @R0,0x06
    39: } 
C:0x003F    D007     POP      0x07
C:0x0041    D006     POP      0x06
C:0x0043    D000     POP      0x00
C:0x0045    D0D0     POP      PSW(0xD0)
C:0x0047    D0E0     POP      ACC(0xE0)
C:0x0049    32       RETI     


    42: void Ext_IN0T2 (void) interrupt INT2_VECTOR     // 
    43: { 
C:0x03F5    C0E0     PUSH     ACC(0xE0)
C:0x03F7    C0D0     PUSH     PSW(0xD0)
C:0x03F9    75D000   MOV      PSW(0xD0),#0x00
C:0x03FC    C000     PUSH     0x00
C:0x03FE    C006     PUSH     0x06
C:0x0400    C007     PUSH     0x07
    44:         unsigned char pos=5-(P3&0x07); 
C:0x0402    E5B0     MOV      A,P3(0xB0)
C:0x0404    5407     ANL      A,#0x07
C:0x0406    FF       MOV      R7,A
C:0x0407    C3       CLR      C
C:0x0408    7405     MOV      A,#0x05
C:0x040A    9F       SUBB     A,R7
    45:         unsigned char value=P1; 
C:0x040B    AE90     MOV      R6,P1(0x90)
    46:         display_buffer[pos]=value; 
C:0x040D    2431     ADD      A,#display_buffer(0x31)
C:0x040F    F8       MOV      R0,A
C:0x0410    A606     MOV      @R0,0x06
    47: } 
    48:  
    49: 
C:0x0412    D007     POP      0x07
C:0x0414    D006     POP      0x06
C:0x0416    D000     POP      0x00
C:0x0418    D0D0     POP      PSW(0xD0)
C:0x041A    D0E0     POP      ACC(0xE0)
C:0x041C    32       RETI     

總結(jié)如下:
1.通過長表達(dá)式進(jìn)行賦值時(shí)有時(shí)會(huì)出錯(cuò),,最后把復(fù)雜表達(dá)式分解為簡單表達(dá)式并把結(jié)果存在中間變量里,,最后把結(jié)果賦值給需要的變量,這個(gè)可能是C51編譯器的問題,,碰到過很多次了,,在標(biāo)準(zhǔn)C編譯器或者pc環(huán)境下沒發(fā)現(xiàn)過這個(gè)問題。

2.再一個(gè)就是讀取端口數(shù)據(jù)的問題  

MOV      @R0,P1(0x90) 
直接把端口數(shù)據(jù)進(jìn)行間接尋址可能出錯(cuò),,

 MOV      R6,P1(0x90)
 MOV      @R0,0x06
先把端口數(shù)據(jù)讀取到中間寄存器中,,最后再把中間寄存器值賦給間接地址,

最后,,很遺憾,,只是看到匯編代碼層級(jí)的代碼差別,,未能明白出問題的更深層次原理。
單純從匯編代碼上分析也看不出什么問題,??赡芨布C(jī)制有關(guān)系?


總結(jié):最后發(fā)現(xiàn)問題不是編譯器導(dǎo)致的,而是因?yàn)閿?shù)據(jù)和中斷引腳在同一個(gè)端口P3,,
數(shù)據(jù)在P3^0-P3^3,而中斷引腳是在P3^6和P3^7,,到中斷引腳上接受到信號(hào)是,
再一定程度上引腳到了數(shù)據(jù)P3^0-P3^3,,因?yàn)樗麄兌荚谕粋€(gè)端口,,而作為數(shù)據(jù)的P1端口則沒有收到影響。

一開始數(shù)碼管地址數(shù)據(jù)P3^0-P3^3讀取的,,導(dǎo)致前后兩個(gè)位置的數(shù)據(jù)管有時(shí)出現(xiàn)交錯(cuò)顯示,,
最后根據(jù)數(shù)碼管是以連續(xù)地址顯示的情況,改成在同一個(gè)中斷觸發(fā)的情況下由一個(gè)固定地址自減,,而不是在中斷中從P3^0-P3^3讀取,,處理原理類似乒乓機(jī)制,這樣處理,,數(shù)碼管穩(wěn)定顯示,。

最后還要說的是為什么一開始懷疑是C51編譯器bug的問題了,因?yàn)?span style="line-height: 1.5;">在中斷處理程序中通過增加或減少一行代碼,,發(fā)現(xiàn)數(shù)據(jù)管交錯(cuò)顯示混亂的情況有改變,,因此以為是編譯器bug。
真實(shí)原因是在中斷中增加或減少代碼改變執(zhí)行時(shí)間,,在從P3^0-P3^3讀取地址數(shù)據(jù)的時(shí)候,,
受干擾的情況因?yàn)闀r(shí)間變化有所改變。

代碼如下所示:


unsigned char hpos;
unsigned char lpos;

void Ext_IN0T2 (void) interrupt INT2_VECTOR
{
display_buffer[hpos--]=P1;
lpos=5;
}

void Ext_INT3 (void) interrupt INT3_VECTOR
{
  display_buffer[lpos--]=P1;
hpos=11;
}


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多