版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第5章程序设计与调试•单片机AT89S52程序相关设计和调试•1
<5.1汇编语言程序设计5.2
C515.3源程序的编辑源程序的编写要依据8051汇编语言的基本规则,特别要用好常用的汇编命令(即伪指令),例如下面的程序段:ORG
0040HMOV
A,#7FHMOV
R1,#44HEND这里的ORG和END是两条伪指令,其作用是告诉汇编程序此汇编源程序的起止位置。编辑好的源程序应以.ASM或.A51扩展名存盘(取决于汇编器要求),以备汇编程序调用。•单片机AT89S52程序相关设计和调试•2
<5.1汇编语言程序设计源程序经过机器汇编后,形成的若干文件中含有两个主要文件,一是列表文件,另一个是目标码文件。因汇编软件的不同,文件的格式及信息会有一些不同。但主要信息如下:列表文件主要信息为:•单片机AT89S52程序相关设计和调试•3
<地址目标码汇编程序ORG
0040H0040H747FMOV
A,#7FH0042H7944MOV
R1,#44HEND目标码文件主要信息为:首地址末地址目标码0040H0044H747F7944伪指令的程序,汇编程序将•单不片机处AT8理9S5。2程序相关设计和•4
<调试伪指令是汇编程序能够识别并对汇编过程进行某种控制的汇编命令。它不是单片机执行的指令,所以没有对应的可执行目标码,汇编后产生的目标程序中不会再出现伪指令。1、起始地址设定伪指令:ORG格式为:ORG表达式该指令的功能是向汇编器说明下面紧接的程序代码或常数存放的起始地址(程序存储器地址)。在一个源程序中,可以多次使用ORG伪指令规定不同程序段或数据段存放的
起始地址,但要求地址值由小到大依序排列,不允许空间重叠。2、汇编结束伪指令:END汇编程序遇到END伪指令后即结束汇编,处于END之后ORG和END例子•单片机AT89S52程序相关设计和调试•5
<ORG
0AJMPORG
3;该段程序的机器码从地址0单元开始存放START;该段程序的机器码从地址3单元开始存放AJMP
INT0_PROCA,#30HORG
0100H
;0100H地址单元开始存放START:MOV…
…ORG
1000H;1000H地址单元开始存放INT0_PROC:CLR
IE0…
…END;所有汇编程序结束[标号:]DB字节数据表功能是从标号指定的地址开始,在程序存储器中定义字节数据。字节数据表可以是一个或多个字节数据、字符串或表达式。该伪指令将字节数据表中的数据根据从左到右的顺序依次存放在指定的存储单元中。一个数据占一个存储单元。例如:ORG
500HDB
8,10,18DB
“ABC”汇编后,500H开始顺序存放:08H,0AH,12H,41H,42H,43H•单片机AT89S52程序相关设计和调试•6
<3、字节数据定义伪指令DB[标号:]DW字数据表功能是从标号指定的地址单元开始,在程序存储器中定义字数据。该伪指令将字或字表中的数据根据从左到右的顺序依次存放在指定的存储单元中。16位的二进制数,高8位存放在低地址单元,低8位存放在高地址单元。例如:•单片机AT89S52程序相关设计和调试•7
<ORGDATA:DW1400H324AH,3CH…
…汇编后,(1400H)=32H,(1401H)=4AH,(1402H)=00H,(1403H)=3CH。4、字数据定义伪指令DW符号名EQU表达式功能是将表达式的值或特定的某个汇编符号定义为一个指定的符号名。例如:MOV
SUM,AEND•单片机AT89S52程序相关设计和调试•8
<LEN
EQU
10SUM
EQU
21HBLOCK
EQU
22H;把BLOCK单元开始存放的10;个无符号数进行求和;并将结果存入SUM单元中CLR
AMOV
R7,#LENMOV
R0,#BLOCKLOOP:
ADD
A,@R0INC
R0DJNZ
R7,LOOP5、赋值伪指令EQU符号名DATA表达式功能是将表达式的值作为内部RAM地址赋给一个指定的符号名。例如:MOV
SUM,AEND•单片机AT89S52程序相关设计和调试•9
<LEN
EQU
10SUM
DATA
21HBLOCK
DATA
22H;;与EQU不同之处是明确指出;符号名代表内部RAM地址CLR
AMOV
R7,#LENMOV
R0,#BLOCKLOOP:
ADD
A,@R0INC
R0DJNZ
R7,LOOP6、内部RAM地址赋值伪指令DATA符号名BIT表达式功能是将表达式的值作为位地址赋给一个指定的符号名。例如:•10
<调试SDABITP1.0;数据输出SCKBITP1.1;时钟输出;移位输出子程序SHIFT_OUT:MOVR6,
#87、位地址赋值伪指令BITLP:RLCAMOVSDA,
CSETBSCKNOPCLRSCKDJNZR6,
LPRET单片机AT89S52程序相关设计和ORG
0000HMOV
DPTR,
#2000HLPCLR:CLR
A•单片机AT89S52程序相关设计和调试•11
<<MOVX
@DPTR,
AINC
DPTR;0送(DPTR);
DPTR+1;地址不到3000H再清零MOV
A,
DPHCJNE
A,
#30H,LPCLRLOOP:
SJMP
LOOP例5.1
将外部RAM2000H~2FFFH的内容清零;共要在16个字节中查找;暂存0的个数•单片机AT89S52程序相关设计和调试•12
<<ORG
0000HMOV
R7,
#10HMOV
R1,
#00HMOV
DPTR,
#2000HRCMP:
MOVX
A,
@DPTRCJNE
A,
#0,
NEXT;比较取出内容与00H相等吗?;相等则0的个数加1INC
R1NEXT:
INC
DPTR;未完继续取出下一个数比较;相同数个数送2100HDJNZ
R7,
RCMPMOV
DPTR,#2100HMOV
A,R1MOVX
@DPTR,ASJMP
$例5.2
在2000H--200FH中查出有几个字节是零,把个数放在2100H单元中5.2
C51程序设计•单片机AT89S52程序相关设计和调试•13
<<5.2.1
C51的程序结构5.2.2
C51的数据类型与存储类型5.2.3
C51的指针5.2.4
C51的函数与中断处理程序5.2.5
C51程序实例5.2.1
C51的程序结构环境初始化,如片内•单R片A机MAT清89S零52程等序相。关设计和调试•14
<与一般C语言的结构相同,以main()函数为程序入口,程序体中包含若干语句还可以包含若干函数。预处理语句类型
函数名(参数表){数据说明部分;执行语句部分;}由于没有操作系统的支持,main()必须设计成循环结构或以循环结束,实际在进入main()之前,先执行了一个汇编语言的初始化程序Startup.A51,完成必须的//其中包括SFR定义,要用到P1//定义P1.0引脚•单片机AT89S52程序相关设计和调试•15
<//在P1.0引脚上产生方波#include
<reg51.h>sbit
SQW=P1^0;main(){while(1){SQW=!SQW;}}简单例子1//要用到sfr:P1//声明函数•单片机AT89S52程序相关设计和调试•16
<//无限循环//在P1.0引脚上产生方波#include
<reg51.h>void
delay(void);sbit
SQW=P1^0;main(){
while(1)
{SQW=!SQW;delay();
}}void
delay(void){int
i,j
;for(i=0;
i<1000;
i++)for(j=0;j<100;j++);}简单例子2C语言的关键字共有32个,根据关键字的作用,可分四类:数据类型关键字(12个):char,double,enum,float,int,long,short,signed,struct,union,unsigned,void;控制语句关键字(12个):break,case,continue,default,do,else,for,goto,if,return,switch,while;存储类型关键字(4个):auto,extern,register,static;其它关键字(4个):const,sizeof,typedef,volatile。•单片机AT89S52程序相关设计和调试•17
<标准(ANSI)C关键字C51扩展的关键字•单片机AT89S52程序相关设计和调试<•18
<<<5.2.2
C51的数据类型与存储类型•单片机AT89S52程序相关设计和调试•191、基本数据类型2、C51扩充定义的数据类型•20
<调试sfr:特殊功能寄存器声明sfr16:sfr的16位数据声明sbit:特殊功能位声明bit:位变量声明上述扩充定义的数据类型中,只有bit类型是普通变量类型与int、char功能一样,可用于定义变量或函数。其余扩充类型均与SFR有关。sfr
SCON
=
0X98;sfr16
T2
=
0xCC;
/*T2L=0CCH,T2H=0CDH*/sbit
OV
=
PSW^2;sbit
P1_0=0x90^0;bit
a,b,c;bit
function1(void);b=function1();i•f单片(机bA)T89rSe52t程u序r相n关;设计和sbit•单片机AT89S52程序相关设计和调试•21
<使用关键字sbit可以独立访问可位寻址对象中的某一位,这个对象除了SFR外,也可以是bdata区定义的变量。从这一点也可以看出bit和sbit的区别。例如:bdata
int
ibase;/*在位寻址区定义一个变量*/bdata
char
array
[4]/*在位寻址区定义一个数组*/sbit
mybit_0=
ibase^0;sbit
mybit_15=ibase
^15;sbit
Ary07=array[0]
^7;sbit
Ary37=array[3]
^7;采用这种方法定义可位寻址变量时要求基址对象的存储器类型为bdata,操作符“^”后面的位位置的最大值取决于指定的基址类型,对于char来说是0~7;对于int来说是0~15;对于long来说是0~31。头文件•单片机AT89S52程序相关设计和调试•22
<
所有特殊功能寄存器的定义都在C51的头文件中定义,如reg52.h,使用#include<reg52.h>语句包含需要的头文件即可直接使用定义完成的特殊功能寄存器或位名称;
参看文件reg51.h,reg52.h,at89x52.h等,所有头文件在keil\C51\inc目录下。
常用头文件有:reg51.h
math.h
ctype.h
stdio.hstdlib.h
absacc.h。reg51.h和reg52.h定义特殊功能寄存器和位寄存器,math.h定义常用数学运算。3、C51数据的存储类型由于MCS-51结构的特殊性,C51通过存储类型来声明将变量定义在哪一个存储空间,存储类型如下表:•单片机AT89S52程序相关设计和调试•23
<对于非指针的普通变量,定义格式为:[存储类型]数据类型变量名;也可写为:数据类型[存储类型]变量名;例如:data
char
i,
j,
k;idata
unsigned
char
display[16];xdata
unsigned
int
buf[100];code
unsigned
char
bcd_seg_tab[10]={0x40,0x7c,0x12,0x18,0x2c,0x41,1,0x5c,0,0x8};//共阴7段码
char
data
m,n;unsigned
int
xdata
len;float
idata
x,y,z;•单片机AT89S52程序相关设计和调试•24
<变量的定义方法变量的定义方法•单片机AT89S52程序相关设计和调试•25
<由于大多数情况下使用无符号数,为了书写简便,通常在文件开头用#define定义几种常用数据类型,如:#define
uchar
unsigned
char#define
uint
unsigned
int#define
ulong
unsigned
longdata
uchar
i,j,
k;idata
uint
m,n;如有必要,可以用关键字:_at_对变量绝对定位格式:[存储类型]数据类型变量名_at_
constant;Constant为定位的地址如:data
char
musich
_at_
0x29,musicl
_at_
0x2a;idata
char
buf[8]_at_
0x30;4、C51的存储模式定义C51变量时,也可以不用显式声明该变量的存储类型,如:int
i,
j,
k;unsigned
char
num;在这种情况下,使用默认的(缺省)的存储类型,而默认的存储类型与C51编译器使用的存储模式有关,C51定义了三种存储模式,如下表:一般使用小模式(缺省即是),当需要使用xdata或pdata区时,通过•单显片机式AT8声9S52明程序变相关量设计的和存储类型实现。调试<
•26
<5.2.3
C51的指针•27
<调试1、通用指针定义时不用指明指针所指向数据的存储空间,指针本身占3个字节。由于指针本身也是一个变量,因此可以声明该变量的存储类型。定义格式:[存储类型]数据类型*指针名;例如:char
*p;//占3字节,由存储模式确定存储类型idata
int
*pm,*pn;bdata
long
*p2;//占idata区3字节//占bdata区3字节xdata
unsigned
char
*px
//占xdata区3字节
data
char
buf[10];p=buf;单片机AT89S52程序相关设计和2、专用指针•28
<调试定义时要指明指针所指向数据的存储类型,指针本身只占1个或2个字节。定义格式:[存储类型]数据类型存储类型*指针名;例如:char
data
*p;
//占1字节,由存储模式确定存储类型int
xdata
*px=0x2000;unsigned
char
code
*p1;int
idata
*p=0x30;idata
int
xdata
*pm,*pn;bdata
long
data
*p2;//占2字节,缺省占data区//占2字节,缺省占data区//占1字节,缺省占data区//占idata区2字节//占bdata区1字节xdata
unsigned
char
code
*px
//占xdata区2字节单片机AT89S52程序相关设计和比较专用指针和通用指针•单片机AT89S52程序相关设计和调试<•29
<5.2.4
C51的函数与中断处理程序•单片机AT89S52程序相关设计和调试•30
<1、Keil
C51函数格式[return_type]
function_name([args])[small|compact|large]
[reentrant]
[using
m]small|compact|large:存储模式
reentrant:重入函数(可被多个进程同时调用执行,并且函数自身可以递归调用)using
m:使用的工作寄存器组。m=0---3例:bit
receive(unsigned
char
*buf,
unsigned
char
len);void
delay(void);2、Keil
C51中断处理程序的格式•单片机AT89S52程序相关设计和调试}<•31
<中断号012345---中断源外中断0T0溢出外中断1T1溢出串行中断……格式:void
function_name(
)
[{small|compact|large}]interrupt
n
[using
m]interrupt
n:中断号。n=0---4,5---
using
m:使用的工作寄存器组。m=0---3例如:void
key(void)
interrupt
0{…
…5.2.5
C51程序实例•单片机AT89S52程序相关设计和调试•32
<例5.3将外部RAM2000H~2FFFH的内容清零main(
){int
i;unsigned
char
xdata
*p=0x2000;/*指针指向外部RAM
2000H单元*/for(i=0;i<0x1000;i++)*p++=0;/*
清零2000H-2FFFH单元
*/while(1);
/*以循环结束*/}#define
uchar
unsigned
charmain
(
){uchar
xdata
*p=0x2000;/*指针p指向2000H单元*/int
n=0,i;for(i=0;
i<16;
i++)•单片机AT89S52程序相关设计和调试•33
<{
if(*p==0)
n++;p++;
}/*若该单元内容为零,则n+1
*//*指针指向下一单元*/p=0x2100;*p=n;for(;;);/*指针p指向2100H单元*//*把个数放在2100H单元中*//*以循环结束*/}例5.4
在2000H--200FH中查出有几个字节是零,把个数放在2100H单元中for(
i=0;
i<200;
i++){
*p=sin_tab[i];•单片机AT89S52程序相关设计和调试•34
<somenop();
//延时4个Tm}}//end
of
for(;;)}//end
of
main例子5.5设程序存储区定义了一个大小为200字节的正弦函数表,设外部RAM地址2000H处为D/A转换器端口,试将200字节的数据循环复制到2000H处。#include
<intrins.h>//定义了直接对应汇编语言的函
#define
somenop()_nop_();_nop_();_nop_();_nop_();
unsigned
char
code
sin_tab[200]={0,1,…,0xff,…,1main(){unsigned
char
i
;unsigned
char
xdata
*p=0x2000;for(;;)
//无限循环作为main的结束{方法1#include
<intrins.h>#include
<absacc.h>•单片机AT89S52程序相关设计和调试}•35
<//定义了绝对地址访问的方法#define
somenop()
_nop_();
_nop_();
_nop_();
_nop_();unsigned
char
code
sin_tab[200]={0,
1,
…,
0xff,
…
,
1,main
(){unsigned
char
i
;do{for(
i=0;
i<200;
i++){XBYTE
[0x2000]=sin_tab[i];
//XBYTEsomenop();
//延时4个Tm}}while(1);
//无限循环作为main的结束方法2#include
<intrins.h>•单片机AT89S52程序相关设计和调试•36
<//定义了直接对应汇编语言的函数#define
somenop()
_nop_();
_nop_();
_nop_();
_nop_()unsigned
char
code
sin_tab[200]={0,
1,
…,
0xff,
…
,
1main
(){unsigned
char
i,*p1,
*p2
;p1=(unsigned
char
xdata
*)0x2000;//须指出0x2000类型
p2=sin_tab;//p2指向code区while(1)
//无限循环作为main的结束{for(
i=0;
i<200;
i++){
*p1=*p2++;somenop();
//延时4个Tm}//指针回到初值p2=sin_tab;}}方法3例5.6计算RAM
30开始的16字节无符号数的和,若
为0,点亮P1.7接的绿色LED,为FFH点亮P1.6接的红色LED,其它值则点亮P1.5接的黄色LED。•单片机AT89S52程序相关设计和调试•37
<#include
<reg51.h>/*包含对P1等SFR的定义*/sbitsbitsbitGreen=P1^7;Red=P1^6;Yellow=P1^5;main(
){
unsigned
char
i,
sum=0;unsigned
char
data
*p=0x30;for(i=0;
i<16;
i++)
sum+=*p++;if
(sum==0)
{Green=0;
Red=1;
Yellow=1;}else
if
(sum==0xff){Green=1;
Red=0;
Yellow=1;}elsewhile(1);}编程实现{Green=1;
Red=1;
Yellow=0;}/*以循环结束*/单片机AT89S52程序相关设计和 调试<
•38
<5.3程序调试方法•单片机AT89S52程序相关设计和调试•39
<5.3.1单片机开发系统5.3.2源程序调试5.3.3程序下载运行5.3.1单片机开发系统•单片机AT89S52程序相关设计和调试•40
<
单片机开发系统的作用是用来调试目标系统(用户系统)的硬件和软件,最终得到硬件和软件都正确的目标系统。
从硬件上看,单片机开发系统由计算机和仿真器组成,二者之间通过RS-232串口、并口或USB连接,实现双向通信交互;
从软件上看,单片机开发系统由集成调试环境(IDE)构成,在该环境下可以进行编辑、汇编、编译、模拟、仿真、下载等工作;单片机开发系统和目标系统连接示意图•单片机AT89S52程序相关设计和调试•41
<<<•单片机AT89S52程序相关设计和调试•42仿真器与目标系统连接•单片机AT89S52程序相关设计和调试•43
<<<•单片机AT89S52程序相关设计和调试•44<<•单片机AT89S52程序相关设计和调试•45使用Keil的开发工具其项目开发周期和任何软件开发项目都大致一样:创建C或汇编语言的源程序;编译或汇编源文件;纠正源文件中的错误;从编译器和汇编器连接目标文件;测试连接的应用程序。•单片机AT89S52程序相关设计和调试•46
<开发流程开发流程示意图•单片机AT89S52程序相关设计和调试•47
<德国Keil软件公司的8051单片机软件开发工具可用于众多的8051派生器件的应用开发,工具清单如下:◎C51优化C编译器◎A51宏汇编器◎8051工具(连接器/目标文件转换器/库管理器)◎dScope源程序级调试器/模拟器◎μVision集成开发环境•单片机AT89S52程序相关设计和调试•48
<Keil公司8051单片机软件开发工具Keil
8051开发环境•单片机AT89S52程序相关设计和调试<•49
<μVision/51是一个集成的软件开发平台,包括全功能编辑器、项目管理器、程序生成工具和环境控制。当用户使用μVision/51时,就不再需要学习任何一个工具的命令语句。μVision/51提供以下特性可加速用户的应用开发:标准Windows用户界面所有环境的对话框和开发工具设置多文件编辑能力用户可自定义密码序列的全功能编辑器将外部程序加入下拉式菜单的应用管理器创建和保存项目的项目管理器从项目中建立目标程序的集成程序生成工具<•50
<调试在线帮助系统μVision/51单片机AT89S52程序相关设计和·dScope-51是一个源程序级的调试器和模拟器,可调试/模拟由Keil
C51编译器和A51汇编器所创建的程序;·
dScope-51是一个纯软件产品它可使用户在没有目标硬件的情况下模拟8051的特性,用户可在硬件准备之前用dScope-51调试自己的应用程序;·dScope-51可模拟许多8051的外围功能包括内部串行口、外部I/O口和定时器/计数器;·dScope-51通过Monitor-51目标调试器实现对目标系统(用户应用系统)的在线仿真调试(In-Circuit
Emulator);·调试命令:参看html在线帮助uVision2
Debug
Commands,如e
char
d:0x90=0,d
char
i:0x80,d
int
x:0xc000等。<•51
<调试dScope-51单片机AT89S52程序相关设计和C51编译器和A51汇编器由μVision2
IDE创建的源文件,可以被C51编译器或A51汇编器处理,生成可重定位的object文件。Keil
C51编译器遵照ANSI
C语言标准,支持C语言的所有标准特性。另外,还增加了几个可以直接支持80C51结构的特性。KeilA51宏汇编器支持80C51及其派生系列的所有指令集。LIB51库管理器LIB51库管理器可以从由汇编器和编译器创建的目标文件建立目标库。这些库是按规定格式排列的目标模块,可在以后被链接器所使用。当链接器处理一个库时,仅仅使用了库中程序使用了的目标模块而不是全部加以引用。•单片机AT89S52程序相关设计和调试<•52
<C51、A51和LIB51BL51链接器/定位器BL51链接器使用从库中提取出来的目标模块和由编译器、汇编器生成的目标模块,创建一个绝对地址目标模块。绝对地址目标文件或模块包括不可重定位的代码和数据。所有的代码和数据都被固定在具体的存储器单元中。RTX51实时操作系统(高级应用,了解)RTX51实时操作系统是针对80C51微控制器系列的一个多任务内核。RTX51实时内核简化了需要对实时事件进行反应的复杂应用的系统设计、编程和调试。这个内核完全集成在C51编译器中,使用非常简单。任务描述表和操作系统的一致性由BL51链接器/定位器自动进行控制。•单片机AT89S52程序相关设计和调试<•53
<BL51和RTX515.3.2源程序调试模拟调试(软件模拟)在纯软件环境下,由PC机模拟8051运行,调试用户程序。μVision2的调试器dScope可以配置成软件模拟方式,调试器包括一个高速模拟器,可以模拟整个80C51系统,包括片上外围器件和外部硬件,能进行快速、可靠的程序调
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 针制作工岗前工作实操考核试卷含答案
- 烷基苯装置操作工岗前前瞻考核试卷含答案
- 供排水泵站运行工诚信道德模拟考核试卷含答案
- 脱酚工岗前技术评优考核试卷含答案
- 柠檬酸原料粉碎工成果转化评优考核试卷含答案
- 混凝土模具工安全技能测试知识考核试卷含答案
- 2026 三年级上册《课堂交际口语表达》课件
- 桌游竞技活动免责协议书
- 2026年环卫工人道路作业安全防范知识考试
- 2026年中国邮政储蓄银行风险控制知识考核
- 2026云南昆明市禄劝县第一人民医院昆明市延安医院禄劝医院编外人员招聘19人笔试备考试题及答案解析
- 2026年自然资源管理知识手册基础试题库及参考答案详解(夺分金卷)
- 湖北省新八校2026年4月高三年级4月教学质量教研考试英语试卷(含答案)
- 2026河北省国控商贸集团有限公司招聘建设笔试参考题库及答案解析
- 2026年交管12123驾驶证学法减分试题(含参考答案)
- 2026年甘肃省陇南市宕昌县人民法院招聘聘用制司法辅助人员笔试备考试题及答案解析
- APQC跨行业流程分类框架 (8.0 版)( 中文版-2026年4月)
- 2026年记者招聘无领导小组讨论题目
- 高考英语阅读理解真题专项突破训练试题含参考答案5篇
- 2026春季四川成都环境投资集团有限公司下属成都市兴蓉环境股份有限公司校园招聘47人笔试备考题库及答案解析
- 药品耗材采购审批制度
评论
0/150
提交评论