📄 main.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 + -