⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.lst

📁 实验7 在RAM中执行程序代码 实验7 在RAM中执行程序代码 实验7 在RAM中执行程序代码
💻 LST
字号:
C51 COMPILER V7.06   MAIN                                                                  03/29/2007 22:55:54 PAGE 1   


C51 COMPILER V7.06, COMPILATION OF MODULE MAIN
OBJECT MODULE PLACED IN main.OBJ
COMPILER INVOKED BY: E:\Keil\C51\BIN\C51.EXE main.c BROWSE DEBUG OBJECTEXTEND SRC(.\main.SRC)

stmt level    source

   1          /*******************************************************************************
   2          程序名称:引导程序,通过串行口加载HEX程序文件到片外RAM并运行
   3          硬件接法:P1.2控制交流蜂鸣器发声
   4                    片外接16KB RAM,地址范围0x8000~0xBFFF
   5          功能描述:通过串行口加载HEX程序文件,转换成BIN格式并保存在片外RAM中;
   6                    加载完毕后蜂鸣器鸣叫,并等待按下K4;
   7                    K4按下后,跳转到RAM去执行程序。
   8          *******************************************************************************/
   9          
  10          
  11          #include <REG52.h>
  12          #include <ABSACC.H>
  13          #include <ctype.h>
  14          #include <string.h>
  15          #include <stdio.h>
  16          
  17          
  18          //定义I/O端口
  19          sbit BUZZER = P1^2;     //交流蜂鸣器
  20          sbit K4 = P3^5;         //按键,按下时输入低电平
  21          
  22          
  23          //设置晶振频率
  24          #define MCLK            11059200L
  25          //设置波特率
  26          #define BaudRate        4800L
  27          
  28          
  29          //外部中断INT0入口
  30          void INT0_ISR() interrupt 0
  31          {
  32   1      #pragma asm
  33   1              LJMP    0x8003
  34   1      #pragma endasm
  35   1      }
  36          
  37          //定时器T0中断入口
  38          void T0_ISR() interrupt 1
  39          {
  40   1      #pragma asm
  41   1              LJMP    0x800B
  42   1      #pragma endasm
  43   1      }
  44          
  45          //外部中断INT1入口
  46          void INT1_ISR() interrupt 2
  47          {
  48   1      #pragma asm
  49   1              LJMP    0x8013
  50   1      #pragma endasm
  51   1      }
  52          
  53          //定时器T1中断入口
  54          void T1_ISR() interrupt 3
  55          {
C51 COMPILER V7.06   MAIN                                                                  03/29/2007 22:55:54 PAGE 2   

  56   1      #pragma asm
  57   1              LJMP    0x801B
  58   1      #pragma endasm
  59   1      }
  60          
  61          //串行口收发中断入口
  62          void Serial_ISR() interrupt 4
  63          {
  64   1      #pragma asm
  65   1              LJMP    0x8023
  66   1      #pragma endasm
  67   1      }
  68          
  69          //定时器T2中断入口
  70          void T2_ISR() interrupt 5
  71          {
  72   1      #pragma asm
  73   1              LJMP    0x802B
  74   1      #pragma endasm
  75   1      }
  76          
  77          
  78          //串行口初始化
  79          void UartInit()
  80          {
  81   1      //串行口设置:8位UART,允许接收,TI置位
  82   1              SCON = 0x52;
  83   1      //波特率加倍
  84   1              PCON |= 0x80;
  85   1      //设置定时器T1为8位自动重装模式
  86   1              TMOD &= 0x0F;
  87   1              TMOD |= 0x20;
  88   1      //设置定时器T1的初值
  89   1              TH1 = 256 - ( MCLK / 12 ) / (16 * BaudRate );
  90   1              TL1 = TH1;
  91   1      //启动定时器T1
  92   1              TR1 = 1;
  93   1      }
  94          
  95          
  96          //定义联合整型结构,为访问整型变量的字节部分提供了方便
  97          typedef union
  98          {
  99                  unsigned int i;
 100                  struct
 101                  {
 102                          unsigned char H;
 103                          unsigned char L;
 104                  }CharPart;
 105          }UnionInt;
 106          
 107          
 108          //定义Intel HEX记录的结构
 109          typedef struct
 110          {
 111                  unsigned char ll;       //长度
 112                  unsigned int aaaa;      //地址
 113                  unsigned char tt;       //记录类型,0-数据,1-终止
 114                  char dd[32];            //数据
 115                  char cc;                        //校验和
 116                  unsigned int BootAddr;  //启动地址
 117          }CIntelHEX;
C51 COMPILER V7.06   MAIN                                                                  03/29/2007 22:55:54 PAGE 3   

 118          
 119          
 120          /*******************************************************************************
 121          函数:AnalyseHEX()
 122          功能:分析一条HEX记录(把Intel HEX记录的文本转换成IntelHEX结构)
 123          参数:hex[]是记录的文本一行内容
 124                转换后的结果保存在IntelHEX结构中
 125          返回:1-转换成功
 126                0-HEX记录文本中有错误
 127          *******************************************************************************/
 128          bit AnalyseHEX(CIntelHEX idata *IntelHEX, char pdata *hex)
 129          {
 130   1              unsigned char i;
 131   1              unsigned char j;
 132   1              unsigned char t;
 133   1              unsigned char n;
 134   1              unsigned char cc;
 135   1              UnionInt x;
 136   1      //检查冒号
 137   1              if ( hex[0] != ':' ) return 0;
 138   1      //检查长度
 139   1              t = (toint(hex[1])<<4) + toint(hex[2]);
 140   1              if ( t > 32 ) return 0;
 141   1              n = 2 * t + 11;
 142   1              if ( n != strlen(hex) ) return 0;
 143   1              IntelHEX->ll = t;
 144   1              cc = t;
 145   1      //提取地址
 146   1              t = (toint(hex[3])<<4) + toint(hex[4]);
 147   1              cc += t;
 148   1              x.CharPart.H = t;
 149   1              t = (toint(hex[5])<<4) + toint(hex[6]);
 150   1              cc += t;
 151   1              x.CharPart.L = t;
 152   1              IntelHEX->aaaa = x.i;
 153   1      //提取记录类型
 154   1              t = (toint(hex[7])<<4) + toint(hex[8]);
 155   1              if ( (t==0) || (t==1) )
 156   1              {
 157   2                      cc += t;
 158   2                      IntelHEX->tt = t;
 159   2              }
 160   1              else
 161   1              {
 162   2                      return 0;
 163   2              }
 164   1      //提取数据
 165   1              i = 9;
 166   1              if ( t == 0 )
 167   1              {
 168   2                      j = 0;
 169   2                      n = IntelHEX->ll;
 170   2                      do
 171   2                      {
 172   3                              t = (toint(hex[i++])<<4);
 173   3                              t += toint(hex[i++]);
 174   3                              cc += t;
 175   3                              IntelHEX->dd[j++] = t;
 176   3                      } while ( --n != 0 );
 177   2              }
 178   1      //提取校验和
 179   1              t = (toint(hex[i++])<<4);
C51 COMPILER V7.06   MAIN                                                                  03/29/2007 22:55:54 PAGE 4   

 180   1              t += toint(hex[i++]);
 181   1              cc += t;
 182   1              IntelHEX->cc = t;
 183   1      //检查校验和
 184   1              if ( cc == 0 )
 185   1                      return 1;
 186   1              else
 187   1                      return 0;
 188   1      }
 189          
 190          
 191          //蜂鸣器鸣叫
 192          void Beep()
 193          {
 194   1              unsigned int n;
 195   1              TMOD &= 0xF0;   //T0设置在方式1,即16位定时器(不改变T1的模式)
 196   1              TMOD |= 0x01;
 197   1              n = 800;
 198   1              do
 199   1              {
 200   2                      TH0 = 0xFC;                     //设置T0初值=65536-(11059200/12)/(2*f)
 201   2                      TL0 = 0x66;                     //f为发声频率(500Hz)
 202   2                      TR0 = 1;                        //启动定时器
 203   2                      while ( !TF0 );         //等待定时器溢出
 204   2                      TR0 = 0;                        //停止定时器
 205   2                      TF0 = 0;                        //清除溢出标志
 206   2                      BUZZER = !BUZZER;       //翻转I/O口,产生方波振荡,使蜂鸣器发声
 207   2              } while ( --n != 0 );
 208   1              BUZZER = 1;
 209   1      }
 210          
 211          
 212          /*******************************************************************************
 213          函数:Delay()
 214          功能:延时0.01s~2.56s
 215          参数:t>0时,延时(t*0.01)s
 216                t=0时,延时2.56s
 217          说明:定时10ms的定时器初值=65536-0.01/(1/(f/12)),其中f为晶振频率
 218          *******************************************************************************/
 219          void Delay(unsigned char t)
 220          {
 221   1              TMOD &= 0xF0;   //T0设置在方式1,即16位定时器(不改变T1的模式)
 222   1              TMOD |= 0x01;
 223   1              do
 224   1              {
 225   2                      TH0 = 0xDC;                     //设置定时器初值(定时10ms)
 226   2                      TL0 = 0x00;
 227   2                      TR0 = 1;                        //启动定时器
 228   2                      while ( !TF0 );         //等待定时器溢出
 229   2                      TR0 = 0;                        //停止定时器
 230   2                      TF0 = 0;                        //清除溢出标志
 231   2              } while ( --t != 0 );   //循环t次
 232   1      }
 233          
 234          
 235          //跳到RAM执行程序
 236          void GotoRam()
 237          {
 238   1      //下载完毕后,发送OK、蜂鸣器鸣叫
 239   1              printf("OK, press K4 to executing.\r\n");
 240   1              Beep();
 241   1      //等待按键K4按下,当K4抬起时,才运行RAM程序
C51 COMPILER V7.06   MAIN                                                                  03/29/2007 22:55:54 PAGE 5   

 242   1              while ( K4 );
 243   1              Delay(40);
 244   1              while ( !K4 );
 245   1      //复位重要SFR寄存器
 246   1              IE = 0x00;
 247   1              TCON = 0x00;
 248   1              TMOD = 0x00;
 249   1              IP = 0x00;
 250   1              SCON = 0x00;
 251   1      //恢复堆栈指针SP默认值;跳到RAM地址0x8000处
 252   1      #pragma asm
 253   1              MOV             SP, #0x07
 254   1              LJMP    0x8000
 255   1      #pragma endasm
 256   1      }
 257          
 258          
 259          /*******************************************************************************
 260          函数:GetString()
 261          功能:从串行口读入一行HEX记录
 262          参数:*s-字符缓冲区,保存读入的数据
 263                size-最大限制长度
 264          *******************************************************************************/
 265          void GetString(char pdata *s, unsigned char size)
 266          {
 267   1              char c;
 268   1              unsigned char n;
 269   1              n = 0;
 270   1              for (;;)
 271   1              {
 272   2                      c = _getkey();
 273   2                      if ( (c==':') || isxdigit(c) )
 274   2                      {
 275   3                              if ( n < size )
 276   3                              {
 277   4                                      s[n++] = c;
 278   4                              }
 279   3                      }
 280   2                      else if ( c == '\n' )
 281   2                      {
 282   3                              s[n] = '\0';
 283   3                              return;
 284   3                      }
 285   2              }
 286   1      }
 287          
 288          
 289          //主程序
 290          void main()
 291          {
 292   1              unsigned char n;
 293   1              unsigned char i;
 294   1              unsigned int addr;
 295   1              CIntelHEX idata IntelHEX;
 296   1              char pdata buf[76];
 297   1              UartInit();
 298   1              printf("Ready\r\n");
 299   1              for (;;)
 300   1              {
 301   2                      GetString(buf,sizeof(buf)-1);   //从串行口读入一行HEX记录
 302   2                      if ( AnalyseHEX(&IntelHEX,buf) )        //分析HEX记录,转换成BIN格式
 303   2                      {
C51 COMPILER V7.06   MAIN                                                                  03/29/2007 22:55:54 PAGE 6   

 304   3                              switch ( IntelHEX.tt )
 305   3                              {
 306   4                              case 0x00:      //HEX类型:数据
 307   4                              //保存BIN代码到RAM
 308   4                                      addr = IntelHEX.aaaa;
 309   4                                      n = IntelHEX.ll;
 310   4                                      for ( i=0; i<n; i++ )
 311   4                                      {
 312   5                                              XBYTE[addr+i] = IntelHEX.dd[i];
 313   5                                      }
 314   4                                      break;
 315   4                              case 0x01:      //HEX类型:结束
 316   4                              //跳到RAM中运行程序代码
 317   4                                      GotoRam();
 318   4                                      break;
 319   4                              default:
 320   4                                      break;
 321   4                              }
 322   3                      }
 323   2              }
 324   1      }
 325          


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    649    ----
   CONSTANT SIZE    =     37    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----      76
   DATA SIZE        =   ----      17
   IDATA SIZE       =   ----      39
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -