单片机DPTR(DPH,DPL)和SP特殊寄存器C语言中应用?这三个特殊寄存器对C程序员来说是透明的,不用C程序员操作,编译的时候会自动运用这三个寄存器ACC寄存器和B寄存器也类似

单片机DPTR(DPH,DPL)和SP特殊寄存器C语言中应用?这三个特殊寄存器对C程序员来说是透明的,不用C程序员操作,编译的时候会自动运用这三个寄存器,ACC寄存器和B寄存器也类似

编译器把C译成指令序列时,会根据具体情况处理SP,相对于C的使用者是透明的。https://bbs.21ic.com/icview-42986-1-1.html

指针
汇编语言里面 这样操作 MOVX A, @ DPTR 或者 MOVC A, @A + DPTR

C语言里面不需要程序员操作DPTR,编译器会自动操作的https://zhidao.baidu.com/question/346722123.html

 

C语言出现数组的地方会编译中会自动用DPTR指针。

调用子程序和中断程序的地方采用到堆栈SP

源程序单片机例程中的2402

#include<reg51.h>
#include<intrins.h>    
#define uchar unsigned char
#define uint unsigned int
#define NOP4() {_nop_();_nop_();_nop_();_nop_();}
sbit SCL=P1^0;
sbit SDA=P1^1;
sbit SPK=P3^0;
//标准音符频率对应的延时表
uchar code HI_LIST[]={0,226,229,232,233,236,238,240,241,242,244,245,246,247,248};
uchar code LO_LIST[]={0,4,13,10,20,3,8,6,2,23,5,26,1,4,3};
//待写入24C04的音符
uchar code Song_24C04[]={1,2,3,1,1,2,3,1,3,4,5,3,4,5};
uchar sidx;            //读取音符索引
//延时
void DelayMS(uint ms)
{    
    uchar i;
    while(ms--) for(i=0;i<120;i++);
}
//IIC开始
void Start()
{
    SDA=1;SCL=1;NOP4();SDA=0;NOP4();SCL=0;
}
//IIC停止
void Stop()
{
    SDA=0;SCL=0;NOP4();SCL=1;NOP4();SDA=1;

//读取应答
void RACK()//应该是判断从机的应答啊?怎么此函数是单片机输出应答呢?2019.12.18
{
    SDA=1;NOP4();SCL=1;NOP4();SCL=0;
}
//发送非应答信号
void NO_ACK()
{
    SDA=1;SCL=1;NOP4();SCL=0;SDA=0;
}
//向24C04中写一个字节数据
void Write_A_Byte(uchar b)
{
    uchar i;
    for(i=0;i<8;i++)
    {
        b<<=1;SDA=CY;_nop_();SCL=1;NOP4();SCL=0;
    }
    RACK();
}
//向指定地址写数据
void Write_IIC(uchar addr,uchar dat)
{
    Start();
    Write_A_Byte(0xa0);Write_A_Byte(addr);Write_A_Byte(dat);
    Stop();
    DelayMS(10);
}
//从24C04中读一个字节数据
uchar Read_A_Byte()
{
    uchar i,b;
    for(i=0;i<8;i++)
    {
        SCL=1;b<<=1;b|=SDA;SCL=0;
    }
    return b;
}
//从当前地址读取数据
uchar Read_Current()
{
    uchar d;
    Start();
    Write_A_Byte(0xa1);d=Read_A_Byte();NO_ACK();
    Stop();
    return d;
}
//从任意地址读取数据
uchar Random_Read(uchar addr)
{
    Start();
    Write_A_Byte(0xa0);Write_A_Byte(addr);
    Stop();
    return Read_Current();
}
//定时器0中断
void T0_INT() interrupt 1
{
    SPK=~SPK;
    TH0=HI_LIST[sidx];
    TL0=LO_LIST[sidx];
}
//主程序
void main()
{
    uint i;
    IE=0x82;
    TMOD=0x00;
    for(i=0;i<14;i++)               //向24C04写入音符表
    {
        Write_IIC(i,Song_24C04[i]);
    }
    while(1)                         //反复读取音符并播放
    {
        for(i=0;i<15;i++)            //从24C04中读取音符
        {
            sidx=Random_Read(i);    //从指定地址读取
            TR0=1;                    //播放
            DelayMS(300);
        }
    }
}

反汇编

   126: ?C_STARTUP:     LJMP    STARTUP1 
   127:  
   128:                 RSEG    ?C_C51STARTUP 
   129:  
   130: STARTUP1: 
   131:  
   132: IF IDATALEN <> 0 
C:0x0000    020166   LJMP     STARTUP1(C:0166)
C:0x0003    00       NOP      
C:0x0004    00       NOP      
C:0x0005    00       NOP      
C:0x0006    00       NOP      
C:0x0007    00       NOP      
C:0x0008    00       NOP      
C:0x0009    00       NOP      
C:0x000A    00       NOP      
C:0x000B    020088   LJMP     T0_INT(C:0088)
    94: void main() 
    95: { 
    96:         uint i; 
    97:         IE=0x82; 
C:0x000E    75A882   MOV      IE(0xA8),#DPL(0x82)
    98:         TMOD=0x00; 
C:0x0011    E4       CLR      A
C:0x0012    F589     MOV      TMOD(0x89),A
    99:         for(i=0;i<14;i++)                        //向24C04写入音符表 
C:0x0014    F508     MOV      0x08,A
C:0x0016    F509     MOV      0x09,A
   100:         { 
   101:                 Write_IIC(i,Song_24C04[i]); 
C:0x0018    AF09     MOV      R7,0x09
C:0x001A    EF       MOV      A,R7
C:0x001B    90007A   MOV      DPTR,#Song_24C04(0x007A)
C:0x001E    93       MOVC     A,@A+DPTR
C:0x001F    FD       MOV      R5,A
C:0x0020    1200EE   LCALL    Write_IIC(C:00EE)
   102:         } 
C:0x0023    0509     INC      0x09
C:0x0025    E509     MOV      A,0x09
C:0x0027    7002     JNZ      C:002B
C:0x0029    0508     INC      0x08
C:0x002B    C3       CLR      C
C:0x002C    940E     SUBB     A,#0x0E
C:0x002E    E508     MOV      A,0x08
C:0x0030    9400     SUBB     A,#0x00
C:0x0032    40E4     JC       C:0018
   103:         while(1)                                              //反复读取音符并播放 
   104:         { 
   105:                 for(i=0;i<15;i++)                     //从24C04中读取音符 
C:0x0034    E4       CLR      A
C:0x0035    F508     MOV      0x08,A
C:0x0037    F509     MOV      0x09,A
   106:                 { 
   107:                         sidx=Random_Read(i);    //从指定地址读取 
C:0x0039    AF09     MOV      R7,0x09
C:0x003B    12014B   LCALL    Random_Read(C:014B)
C:0x003E    8F0A     MOV      sidx(0x0A),R7
   108:                         TR0=1;          //播放 
C:0x0040    D28C     SETB     TR0(0x88.4)
   109:                         DelayMS(300); 
C:0x0042    7F2C     MOV      R7,#0x2C
C:0x0044    7E01     MOV      R6,#0x01
C:0x0046    1200D8   LCALL    DelayMS(C:00D8)
   110:                 } 
C:0x0049    0509     INC      0x09
C:0x004B    E509     MOV      A,0x09
C:0x004D    7002     JNZ      C:0051
C:0x004F    0508     INC      0x08
C:0x0051    C3       CLR      C
C:0x0052    940F     SUBB     A,#0x0F
C:0x0054    E508     MOV      A,0x08
C:0x0056    9400     SUBB     A,#0x00
C:0x0058    40DF     JC       C:0039
C:0x005A    80D8     SJMP     C:0034
C:0x005C    00       NOP      
C:0x005D    E2       MOVX     A,@R0
C:0x005E    E5E8     MOV      A,0xE8
C:0x0060    E9       MOV      A,R1
C:0x0061    EC       MOV      A,R4
C:0x0062    EE       MOV      A,R6
C:0x0063    F0       MOVX     @DPTR,A
C:0x0064    F1F2     ACALL    C:07F2
C:0x0066    F4       CPL      A
C:0x0067    F5F6     MOV      0xF6,A
C:0x0069    F7       MOV      @R1,A
C:0x006A    F8       MOV      R0,A
C:0x006B    00       NOP      
C:0x006C    04       INC      A
C:0x006D    0D       INC      R5
C:0x006E    0A       INC      R2
C:0x006F    14       DEC      A
C:0x0070    03       RR       A
C:0x0071    08       INC      R0
C:0x0072    06       INC      @R0
C:0x0073    021705   LJMP     C:1705
C:0x0076    1A       DEC      R2
C:0x0077    0104     AJMP     C:0004
C:0x0079    03       RR       A
C:0x007A    0102     AJMP     C:0002
C:0x007C    03       RR       A
C:0x007D    0101     AJMP     C:0001
C:0x007F    020301   LJMP     C:0301
C:0x0082    03       RR       A
C:0x0083    04       INC      A
C:0x0084    0503     INC      0x03
C:0x0086    04       INC      A
C:0x0087    05C0     INC      0xC0
C:0x0089    E0       MOVX     A,@DPTR
C:0x008A    C083     PUSH     DPH(0x83)
C:0x008C    C082     PUSH     DPL(0x82)
    89:         SPK=~SPK; 
C:0x008E    B2B0     CPL      SPK(0xB0.0)
    90:         TH0=HI_LIST[sidx]; 
C:0x0090    E50A     MOV      A,sidx(0x0A)
C:0x0092    90005C   MOV      DPTR,#HI_LIST(0x005C)
C:0x0095    93       MOVC     A,@A+DPTR
C:0x0096    F58C     MOV      TH0(0x8C),A
    91:         TL0=LO_LIST[sidx]; 
C:0x0098    E50A     MOV      A,sidx(0x0A)
C:0x009A    90006B   MOV      DPTR,#LO_LIST(0x006B)
C:0x009D    93       MOVC     A,@A+DPTR
C:0x009E    F58A     MOV      TL0(0x8A),A
    92: } 
C:0x00A0    D082     POP      DPL(0x82)
C:0x00A2    D083     POP      DPH(0x83)
C:0x00A4    D0E0     POP      ACC(0xE0)
C:0x00A6    32       RETI     
C:0x00A7    1200C0   LCALL    Write_A_Byte(C:00C0)
C:0x00AA    AF05     MOV      R7,0x05
C:0x00AC    1200C0   LCALL    Write_A_Byte(C:00C0)
    27: void Stop() 
    28: { 
    29:         SDA=0;SCL=0;NOP4();SCL=1;NOP4();SDA=1; 
C:0x00AF    C291     CLR      SDA(0x90.1)
C:0x00B1    C290     CLR      SCL(0x90.0)
C:0x00B3    00       NOP      
C:0x00B4    00       NOP      
C:0x00B5    00       NOP      
C:0x00B6    00       NOP      
C:0x00B7    D290     SETB     SCL(0x90.0)
C:0x00B9    00       NOP      
C:0x00BA    00       NOP      
C:0x00BB    00       NOP      
C:0x00BC    00       NOP      
C:0x00BD    D291     SETB     SDA(0x90.1)
    30: }  
    31: //读取应答 
    32: void RACK()//应该是判断从机的应答啊?怎么此函数是单片机输出应答呢?2019.12.18 
    33: { 
    34:         SDA=1;NOP4();SCL=1;NOP4();SCL=0; 
    35: } 
    36: //发送非应答信号 
    37: void NO_ACK() 
    38: { 
    39:         SDA=1;SCL=1;NOP4();SCL=0;SDA=0; 
    40: } 
    41: //向24C04中写一个字节数据 
C:0x00BF    22       RET      
    42: void Write_A_Byte(uchar b) 
    43: { 
    44:         uchar i; 
    45:         for(i=0;i<8;i++) 
C:0x00C0    E4       CLR      A
C:0x00C1    FE       MOV      R6,A
    46:         { 
    47:                 b<<=1;SDA=CY;_nop_();SCL=1;NOP4();SCL=0; 
C:0x00C2    EF       MOV      A,R7
C:0x00C3    25E0     ADD      A,ACC(0xE0)
C:0x00C5    FF       MOV      R7,A
C:0x00C6    9291     MOV      SDA(0x90.1),C
C:0x00C8    00       NOP      
C:0x00C9    D290     SETB     SCL(0x90.0)
C:0x00CB    00       NOP      
C:0x00CC    00       NOP      
C:0x00CD    00       NOP      
C:0x00CE    00       NOP      
C:0x00CF    C290     CLR      SCL(0x90.0)
    48:         } 
C:0x00D1    0E       INC      R6
C:0x00D2    BE08ED   CJNE     R6,#0x08,C:00C2
    49:         RACK(); 
    50: } 
    51: //向指定地址写数据 
C:0x00D5    02013C   LJMP     RACK(C:013C)
    16: void DelayMS(uint ms) 
    17: {        
    18:         uchar i; 
    19:         while(ms--) for(i=0;i<120;i++); 
C:0x00D8    EF       MOV      A,R7
C:0x00D9    1F       DEC      R7
C:0x00DA    AA06     MOV      R2,0x06
C:0x00DC    7001     JNZ      C:00DF
C:0x00DE    1E       DEC      R6
C:0x00DF    4A       ORL      A,R2
C:0x00E0    600B     JZ       C:00ED
C:0x00E2    E4       CLR      A
C:0x00E3    FD       MOV      R5,A
C:0x00E4    ED       MOV      A,R5
C:0x00E5    C3       CLR      C
C:0x00E6    9478     SUBB     A,#0x78
C:0x00E8    50EE     JNC      DelayMS(C:00D8)
C:0x00EA    0D       INC      R5
C:0x00EB    80F7     SJMP     C:00E4
    20: } 
C:0x00ED    22       RET      
    52: void Write_IIC(uchar addr,uchar dat) 
C:0x00EE    AC07     MOV      R4,0x07
    53: { 
    54:         Start(); 
C:0x00F0    12012B   LCALL    Start(C:012B)
    55:         Write_A_Byte(0xa0);Write_A_Byte(addr);Write_A_Byte(dat); 
C:0x00F3    7FA0     MOV      R7,#PPAGE_SFR(0xA0)
C:0x00F5    1200C0   LCALL    Write_A_Byte(C:00C0)
C:0x00F8    AF04     MOV      R7,0x04
    56:         Stop(); 
C:0x00FA    1200A7   LCALL    C:00A7
    57:         DelayMS(10); 
    58: } 
    59: //从24C04中读一个字节数据 
C:0x00FD    7F0A     MOV      R7,#sidx(0x0A)
C:0x00FF    7E00     MOV      R6,#0x00
C:0x0101    0200D8   LJMP     DelayMS(C:00D8)
    60: uchar Read_A_Byte() 
    61: { 
    62:         uchar i,b; 
    63:         for(i=0;i<8;i++) 
C:0x0104    E4       CLR      A
C:0x0105    FE       MOV      R6,A
    64:         { 
    65:                 SCL=1;b<<=1;b|=SDA;SCL=0; 
C:0x0106    D290     SETB     SCL(0x90.0)
C:0x0108    EF       MOV      A,R7
C:0x0109    25E0     ADD      A,ACC(0xE0)
C:0x010B    FF       MOV      R7,A
C:0x010C    A291     MOV      C,SDA(0x90.1)
C:0x010E    E4       CLR      A
C:0x010F    33       RLC      A
C:0x0110    4207     ORL      0x07,A
C:0x0112    C290     CLR      SCL(0x90.0)
    66:         } 
C:0x0114    0E       INC      R6
C:0x0115    BE08EE   CJNE     R6,#0x08,C:0106
    67:         return b; 
    68: } 
    69: //从当前地址读取数据 
C:0x0118    22       RET      
    70: uchar Read_Current() 
    71: { 
    72:         uchar d; 
    73:         Start(); 
C:0x0119    12012B   LCALL    Start(C:012B)
    74:         Write_A_Byte(0xa1);d=Read_A_Byte();NO_ACK(); 
C:0x011C    7FA1     MOV      R7,#0xA1
C:0x011E    1200C0   LCALL    Write_A_Byte(C:00C0)
C:0x0121    120104   LCALL    Read_A_Byte(C:0104)
C:0x0124    120159   LCALL    NO_ACK(C:0159)
    75:         Stop(); 
C:0x0127    1200AF   LCALL    Stop(C:00AF)
    76:         return d; 
    77: } 
    78: //从任意地址读取数据 
C:0x012A    22       RET      
    22: void Start() 
    23: { 
    24:         SDA=1;SCL=1;NOP4();SDA=0;NOP4();SCL=0; 
C:0x012B    D291     SETB     SDA(0x90.1)
C:0x012D    D290     SETB     SCL(0x90.0)
C:0x012F    00       NOP      
C:0x0130    00       NOP      
C:0x0131    00       NOP      
C:0x0132    00       NOP      
C:0x0133    C291     CLR      SDA(0x90.1)
C:0x0135    00       NOP      
C:0x0136    00       NOP      
C:0x0137    00       NOP      
C:0x0138    00       NOP      
C:0x0139    C290     CLR      SCL(0x90.0)
    25: } 
    26: //IIC停止 
    27: void Stop() 
    28: { 
    29:         SDA=0;SCL=0;NOP4();SCL=1;NOP4();SDA=1; 
    30: }  
    31: //读取应答 
C:0x013B    22       RET      
    32: void RACK()//应该是判断从机的应答啊?怎么此函数是单片机输出应答呢?2019.12.18 
    33: { 
    34:         SDA=1;NOP4();SCL=1;NOP4();SCL=0; 
C:0x013C    D291     SETB     SDA(0x90.1)
C:0x013E    00       NOP      
C:0x013F    00       NOP      
C:0x0140    00       NOP      
C:0x0141    00       NOP      
C:0x0142    D290     SETB     SCL(0x90.0)
C:0x0144    00       NOP      
C:0x0145    00       NOP      
C:0x0146    00       NOP      
C:0x0147    00       NOP      
C:0x0148    C290     CLR      SCL(0x90.0)
    35: } 
C:0x014A    22       RET      
    79: uchar Random_Read(uchar addr) 
C:0x014B    AD07     MOV      R5,0x07
    80: { 
    81:         Start(); 
C:0x014D    12012B   LCALL    Start(C:012B)
    82:         Write_A_Byte(0xa0);Write_A_Byte(addr); 
C:0x0150    7FA0     MOV      R7,#PPAGE_SFR(0xA0)
    83:         Stop(); 
C:0x0152    1200A7   LCALL    C:00A7
    84:         return Read_Current(); 
C:0x0155    120119   LCALL    Read_Current(C:0119)
    85: } 
C:0x0158    22       RET      
    37: void NO_ACK() 
    38: { 
    39:         SDA=1;SCL=1;NOP4();SCL=0;SDA=0; 
C:0x0159    D291     SETB     SDA(0x90.1)
C:0x015B    D290     SETB     SCL(0x90.0)
C:0x015D    00       NOP      
C:0x015E    00       NOP      
C:0x015F    00       NOP      
C:0x0160    00       NOP      
C:0x0161    C290     CLR      SCL(0x90.0)
C:0x0163    C291     CLR      SDA(0x90.1)
    40: } 
C:0x0165    22       RET      
   133:                 MOV     R0,#IDATALEN - 1 
C:0x0166    787F     MOV      R0,#0x7F
   134:                 CLR     A 
C:0x0168    E4       CLR      A
   135: IDATALOOP:      MOV     @R0,A 
C:0x0169    F6       MOV      @R0,A
   136:                 DJNZ    R0,IDATALOOP 
C:0x016A    D8FD     DJNZ     R0,IDATALOOP(C:0169)
   185:                 MOV     SP,#?STACK-1 
   186:  
   187: ; This code is required if you use L51_BANK.A51 with Banking Mode 4 
   188: ;<h> Code Banking 
   189: ; <q> Select Bank 0 for L51_BANK.A51 Mode 4 
   190: #if 0    
   191: ;     <i> Initialize bank mechanism to code bank 0 when using L51_BANK.A51 with Banking Mode 4. 
   192: EXTRN CODE (?B_SWITCH0) 
   193:                 CALL    ?B_SWITCH0      ; init bank mechanism to code bank 0 
   194: #endif 
   195: ;</h> 
C:0x016C    75810A   MOV      SP(0x81),#sidx(0x0A)
   196:                 LJMP    ?C_START 
C:0x016F    02000E   LJMP     main(C:000E)
C:0x0172    00       NOP      
C:0x0173    00       NOP      
C:0x0174    00       NOP      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值