89C51实 训 指导书 目 录 基本I/O口实训··································1 外部数据存储器的应用(6264)····················· 4 外部数据存储器的应用(2864)····················· 6 键盘显示接口芯片的应用·························· 8 并口扩展的应用··································12 A/D转换的实训·································· 14 D/A转换的实训·································· 20 采集温度········································ 21 制作音乐盒······································ 27 制作四字单色显示屏······························ 31 控制微型打印机·································· 39 实验一:基本I/O口的实训 目的:通过对单片机的编程仿真,学会单片机仿真系统的基本工作过程。 要求:用LED的亮/灭来体现单片机高/低电平的变化,连接单片机的基本I/O口,对单片机进行编程使其完成: (1)8个LED顺序点亮,顺序熄灭,依此循环4次。 (2)8个LED,第1、3、5、7与2、4、6、8 LED交替点亮,依此循环4次。 (3)(1)和(2)无限次循环。 原理:  步骤:1,连接系统板的P1口到LED。 2,连接PC机和仿真机的串口线。 3,给仿真机接通电源。 4,打开仿真机的电源开关,电源灯亮表示仿真系统已经带电。 5,编程。 6,调试。 7,改换其它I/O口,调试程序。 参考程序: ORG 0000H MAIN: MOV P1,#0FFH MOV R7,#04H BACK1: SETB P3.0 CLR P1.0 LCALL YS CLR P1.1 LCALL YS CLR P1.2 LCALL YS CLR P1.3 LCALL YS CLR P1.4 LCALL YS CLR P1.5 LCALL YS CLR P1.6 LCALL YS CLR P1.7 LCALL YS SETB P1.0 LCALL YS SETB P1.1 LCALL YS SETB P1.2 LCALL YS SETB P1.3 LCALL YS SETB P1.4 LCALL YS SETB P1.5 LCALL YS SETB P1.6 LCALL YS SETB P1.7 LCALL YS CLR P3.0 DJNZ R7,BACK1 MOV R7,#04H BACK2: SETB P3.0 CLR P1.1 CLR P1.3 CLR P1.5 CLR P1.7 LCALL YS LCALL YS SETB P1.1 SETB P1.3 SETB P1.5 SETB P1.7 CLR P1.0 CLR P1.2 CLR P1.4 CLR P1.6 LCALL YS LCALL YS SETB P1.0 SETB P1.2 SETB P1.4 SETB P1.6 CLR P3.0 DJNZ R7,BACK2 LJMP MAIN YS: MOV TMOD,#01H MOV R5,#05H LOOP: MOV TH0,#4CH MOV TL0,#00H SETB TR0 JNB TF0,$ CLR TF0 CLR TR0 DJNZ R5,LOOP RET SJMP $ END 心得体会: 实验二:外部数据存储器的应用(6264) 目的:学会用单片机和外部数据存储器进行交流,了解单片机和外部数据进行交换时的时序关系。 要求:以6264数据存储器为实例,按照系统板上的硬件地址对其进行编程,写出 单片机与6264的接口地址,读出6264中连续16个字节的随机数,由小到大排序,然后再存放到6264的相应字节中。(由BC7281显示地址及数据,前四位地址,最后两位数据) 原理:  步骤:1,连接PC机和仿真机的串口线。 2,连接P1.0—DAT,P1.1—KEY,P1.2—CLK。 3,给仿真机接通电源。 4,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 5,编程。 6,调试。 参考程序: CCQ EQU 2000H;外部数据RAM的地址从2000H开始到3FFFH结束 BIT_COUNT DATA 06FH TIMER DATA 06EH TIMER1 DATA 06DH TEMP DATA 06CH DATA_IN DATA 02FH DATA_OUT DATA 02EH CLK BIT P1.2 ;定义I/O口 DAT BIT P1.0 ; KEY BIT P1.1 ; ORG 0000H MAIN: LCALL XSFW MOV R0,#30H MOV R1,#10H MOV DPTR,#CCQ BACK: MOVX A,@DPTR MOV @R0,A INC R0 INC DPTR DJNZ R1,BACK LCALL PAIXU MOV R0,#30H MOV R1,#10H MOV DPTR,#CCQ;外部数据RAM的地址从2000H开始到3FFFH结束 BACK1: MOV A,@R0 MOVX @DPTR,A INC R0 INC DPTR DJNZ R1,BACK1 LCALL XSSHJ SJMP $ PAIXU: MOV R0,#30H ;排序子程序 MOV R1,#31H MOV 40H,#0FH LOP: MOV 41H,40H LP: MOV A,@R0 CLR CY SUBB A,@R1 JC NEXT MOV A,@R0 XCH A,@R1 MOV @R0,A NEXT: INC R1 DJNZ 41H,LP INC R0 MOV A,R0 INC A MOV R1,A DJNZ 40H,LOP RET ;*********************************************************** XSFW: MOV TIMER,#50 START_DELAY: MOV TIMER1,#255 ;延时以确保BC728X完成复位 START_DELAY1: DJNZ TIMER1,START_DELAY1 DJNZ TIMER,START_DELAY MOV DATA_OUT,#12H ;BC728X初始化 LCALL SEND MOV DATA_OUT,#80H ;设定为164模式, 不反相 LCALL SEND RET ;************************************************************* ;* 向BC728X发送一个字节子程序,待发送数据存于DATA_OUT ;************************************************************ SEND: CLR CLK ;在CLK输出一脉冲 SETB CLK WAIT1: JB DAT,WAIT1 ;等待DAT变为低电平 CLR CLK ;再输出一CLK脉冲 SETB CLK WAIT2: JNB DAT,WAIT2 ;等待DAT恢复高电平(输入状态) MOV BIT_COUNT,#8 SEND_LOOP: MOV C,DATA_OUT.7 ;输出BIT7 MOV DAT,C CLR CLK ;输出一CLK脉冲 SETB CLK MOV A,DATA_OUT RL A MOV DATA_OUT,A ;DATA_OUT左移一位 NOP ;短暂延时 NOP NOP DJNZ BIT_COUNT,SEND_LOOP SETB DAT ;恢复DAT为高电平 RET ;************************************************************* ;* 从BC728X接收一个字节子程序,接收到的数据存于DATA_IN ;************************************************************* RECEIVE: CLR CLK ;发出一CLK脉冲 SETB CLK WAIT3: JB DAT,WAIT3 ;等待DAT低电平响应信号 CLR CLK ;再发出一CLK脉冲,准备接收数据 SETB CLK MOV BIT_COUNT,#8 RECV_LOOP: NOP ;短暂延时 NOP NOP NOP NOP NOP NOP NOP MOV A,DATA_IN MOV C,DAT ;读入一位 RLC A MOV DATA_IN,A CLR CLK ;发出CLK脉冲 SETB CLK DJNZ BIT_COUNT,RECV_LOOP RET XSSHJ: MOV R0,#30H MOV R1,#10H MOV 41H,#00H MOV DPTR,#CCQ BACK3: MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,DPH ANL A,#0F0H ;取键码的低4位 SWAP A ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#10H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,DPH ANL A,#0FH ;取键码的低4位 ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#10H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,DPL ANL A,#0F0H ;取键码的低4位 SWAP A ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#10H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,DPL ANL A,#0FH ;取键码的低4位 ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#30H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,@R0 ANL A,#0F0H ;取键码的低4位 SWAP A ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#10H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,@R0 ANL A,#0FH ;取键码的低4位 ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND INC R0 INC DPTR LCALL YS2 MOV 41H,#00H DJNZ R1,BACK2 RET BACK2: LJMP BACK3 YS: MOV 60H,#02H YS1: MOV 61H,#33H YS2: MOV 62H,#33H YS3: DJNZ 62H,YS3 DJNZ 61H,YS2 DJNZ 60H,YS1 RET END 心得体会: 实验三:外部数据存储器的应用(2864) 目的:学会单片机和外部程序存储器的交流,知道比较程序存储器和数据存储器的差异。 要求:以2864数据存储器为实例,按照系统板上的硬件地址对其进行编程,写出 单片机与2864的接口地址,读出2864中连续16个字节的随机数,由小到大排序,然后再存放到2864的相应字节中。(由BC7281显示地址及数据,前四位地址,最后两位数据) 原理:  步骤:1,连接PC机和仿真机的串口线。 2,连接P1.0—DAT,P1.1—KEY,P1.2—CLK。 3,给仿真机接通电源。 4,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 5,编程。 6,调试。 参考程序: CCQ EQU 0000H;外部数据RAM的地址从0000H开始到1FFFH结束 BIT_COUNT DATA 06FH TIMER DATA 06EH TIMER1 DATA 06DH TEMP DATA 06CH DATA_IN DATA 02FH DATA_OUT DATA 02EH CLK BIT P1.2 ;定义I/O口 DAT BIT P1.0 ; KEY BIT P1.1 ; ORG 0000H MAIN: LCALL XSFW MOV R0,#30H MOV R1,#10H MOV DPTR,#CCQ;外部数据RAM的地址从0000H开始到1FFFH结束 BACK: MOVX A,@DPTR MOV @R0,A INC R0 INC DPTR DJNZ R1,BACK LCALL PAIXU MOV R0,#30H MOV R1,#10H MOV DPTR,#0050H ;外部数据RAM的地址从0000H开始到1FFFH结束 BACK1: MOV A,@R0 MOVX @DPTR,A LCALL YS4 INC R0 INC DPTR DJNZ R1,BACK1 LCALL XSSHJ SJMP $ PAIXU: MOV R0,#30H ;排序子程序 MOV R1,#31H MOV 40H,#0FH LOP: MOV 41H,40H LP: MOV A,@R0 CLR CY SUBB A,@R1 JC NEXT MOV A,@R0 XCH A,@R1 MOV @R0,A NEXT: INC R1 DJNZ 41H,LP INC R0 MOV A,R0 INC A MOV R1,A DJNZ 40H,LOP RET YS4: MOV TMOD,#01H MOV R5,#01H LOOP: MOV TH0,#0CH MOV TL0,#00H SETB TR0 JNB TF0,$ CLR TF0 CLR TR0 DJNZ R5,LOOP RET ;*********************************************************** XSFW: MOV TIMER,#50 START_DELAY: MOV TIMER1,#255 ;延时以确保BC728X完成复位 START_DELAY1: DJNZ TIMER1,START_DELAY1 DJNZ TIMER,START_DELAY MOV DATA_OUT,#12H ;BC728X初始化 LCALL SEND MOV DATA_OUT,#80H ;设定为164模式, 不反相 LCALL SEND RET ;************************************************************* ;* 向BC728X发送一个字节子程序,待发送数据存于DATA_OUT ;************************************************************ SEND: CLR CLK ;在CLK输出一脉冲 SETB CLK WAIT1: JB DAT,WAIT1 ;等待DAT变为低电平 CLR CLK ;再输出一CLK脉冲 SETB CLK WAIT2: JNB DAT,WAIT2 ;等待DAT恢复高电平(输入状态) MOV BIT_COUNT,#8 SEND_LOOP: MOV C,DATA_OUT.7 ;输出BIT7 MOV DAT,C CLR CLK ;输出一CLK脉冲 SETB CLK MOV A,DATA_OUT RL A MOV DATA_OUT,A ;DATA_OUT左移一位 NOP ;短暂延时 NOP NOP DJNZ BIT_COUNT,SEND_LOOP SETB DAT ;恢复DAT为高电平 RET ;************************************************************* ;* 从BC728X接收一个字节子程序,接收到的数据存于DATA_IN ;************************************************************* RECEIVE: CLR CLK ;发出一CLK脉冲 SETB CLK WAIT3: JB DAT,WAIT3 ;等待DAT低电平响应信号 CLR CLK ;再发出一CLK脉冲,准备接收数据 SETB CLK MOV BIT_COUNT,#8 RECV_LOOP: NOP ;短暂延时 NOP NOP NOP NOP NOP NOP NOP MOV A,DATA_IN MOV C,DAT ;读入一位 RLC A MOV DATA_IN,A CLR CLK ;发出CLK脉冲 SETB CLK DJNZ BIT_COUNT,RECV_LOOP RET XSSHJ: MOV R0,#30H MOV R1,#10H MOV 41H,#00H MOV DPTR,#CCQ BACK3: MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,DPH ANL A,#0F0H ;取键码的低4位 SWAP A ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#10H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,DPH ANL A,#0FH ;取键码的低4位 ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#10H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,DPL ANL A,#0F0H ;取键码的低4位 SWAP A ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#10H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,DPL ANL A,#0FH ;取键码的低4位 ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#30H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,@R0 ANL A,#0F0H ;取键码的低4位 SWAP A ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND MOV A,41H ADD A,#10H MOV 41H,A MOV DATA_OUT,#15H ;HEX译码指令 LCALL SEND MOV A,@R0 ANL A,#0FH ;取键码的低4位 ADD A,41H MOV DATA_OUT,a ;在第0位显示 LCALL SEND INC R0 INC DPTR LCALL YS2 MOV 41H,#00H DJNZ R1,BACK2 RET BACK2: LJMP BACK3 YS: MOV 60H,#02H YS1: MOV 61H,#33H YS2: MOV 62H,#33H YS3: DJNZ 62H,YS3 DJNZ 61H,YS2 DJNZ 60H,YS1 RET END 心得体会: 实验四:键盘显示接口芯片的应用 目的:学会使用键盘显示接口芯片BC7281,了解键盘的工作原理,LED数码管的显示方式及工作原理。 要求:从键盘输入信息,数码管显示对应按键键码。 原理:  步骤: 1,连接PC机和仿真机的串口线。 2,连接P1.0—DAT,P1.1—KEY,P1.2—CLK。 3,给仿真机接通电源。 4,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 5,编程。 6,调试。 参考程序: #include <reg51.h> //*** 函数定义 *** void delay(unsigned char); //短暂延时 void write728x(unsigned char, unsigned char); // 写入到BC728x unsigned char read728x(unsigned char); // 从BC728x读出 void send_byte(unsigned char); //发送一个字节 unsigned char receive_byte(void); //接收一个字节 void chushihua_BC7281(); unsigned char Number(unsigned char); //*** 变量及I/O定义 *** unsigned char key_number; unsigned int tmr; sbit dat=P1^0; // dat 连接于 P1.0 sbit key=P1^1; // key 连接于 P1.1 sbit clk=P1^2; // clk 连接于 P1.2 //*** 主程序 *** main() { unsigned char a; unsigned int i; key=1; chushihua_BC7281(); //初始化 for(;;) { if(key==0) { key_number=read728x(0x13); write728x(0x15,(0x00+(key_number&0xf0)/16)); write728x(0x15,(0x10+(key_number&0x0f))); write728x(0x15,(0x20+(key_number&0xf0)/16)); write728x(0x15,(0x30+(key_number&0x0f))); write728x(0x15,(0x40+(key_number&0xf0)/16)); write728x(0x15,(0x50+(key_number&0x0f))); write728x(0x15,(0x60+(key_number&0xf0)/16)); write728x(0x15,(0x70+(key_number&0x0f))); } } } //****************************************************************** //* 初始化 BC7281 * //****************************************************************** void chushihua_BC7281() { for (tmr=0;tmr<0xffff;tmr++); // 等待BC728x完成复位 write728x(0x12,0x80); // 初始化BC728x 为164模式,不反相 } // ***************************************************************** // *写入BC728X,第一个参数为目标寄存器地址,第二个参数为要写入的数据 * // ***************************************************************** void write728x(unsigned char reg_add, unsigned char write_data) { send_byte(reg_add); //发送寄存器地址 send_byte(write_data); //发送数据字节 } // ********************************************************** // * 读出BC728X内部寄存器的值,调用参数为寄存器地址 * // ********************************************************** unsigned char read728x(unsigned char reg_add) { send_byte(reg_add|0x80); // 发送读指令(bit7=1) return(receive_byte()); //接收数据并返回 } // *********************************************************** // * 向BC728X发送一个字节 * // *********************************************************** void send_byte(unsigned char send_byte) { unsigned char bit_counter; clk=0; // 产生一个clk脉冲 clk=1; do { clk=0; // 发送clk脉冲,直至dat为低电平 clk=1; } while (dat); clk=0; // 15us之内再输出一个clk脉冲 clk=1; while (!dat); // 等待BC728X进入接收状态 for (bit_counter=0;bit_counter<8;bit_counter++) { // 发送8个比特 if ((send_byte&0x80)==0) { dat=0; // 如果待发bit为0, 置dat为0 } else { dat=1; // 反之为1 } send_byte=send_byte*2; // send_byte左移一位 clk=0; // 输出一个clk脉冲 clk=1; delay(1); //短暂延时 } dat=1; // 恢复dat为高电平 delay(2); //指令间设置一个微小延时 } // ************************************************************ // * 从BC728X接受一个字节 * // ************************************************************ unsigned char receive_byte(void) { unsigned char bit_counter, in_byte; clk=0; // 只发送单一的clk脉冲 clk=1; while (dat); // 等待BC728X响应dat低电平 clk=0; // 收到响应,在发一个脉冲等待接收数据 clk=1; for (bit_counter=0;bit_counter<8;bit_counter++) { // 接收8个bit delay(1); // 短暂延时 in_byte=in_byte*2; // in_byte左移一位 if (dat) // 如果dat为'1' { in_byte=in_byte|0x01; // bit0=1 } clk=0; // 输出一个clk脉冲 clk=1; } delay(2); //指令间设置一个微小延时 return(in_byte); } // *********************************************************** // *短暂延时程序,延时时间与time成正比,范围是几个uS到几百个uS * // *********************************************************** void delay(unsigned char time) { while (time!=0) {time--;} } 心得体会: 实验五:并口扩展的应用 目的:学会使用并口扩展芯片8255,了解并口的扩展原理。 要求:用8255扩展出的I/O口来点亮发光二极管,先使发光二极管从左到右依次点亮,然后再逐次熄灭。 原理:  步骤:1,连接系统板上8255的PB或PC口和LED的基本接口。 2,连接PC机和仿真机的串口线。 3,给仿真机接通电源。 4,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 5,编程。 6,调试。 参考程序: ORG 0000H MAIN: MOV DPTR,#4003H ;方式控制字的地址 MOV A,#90H MOVX @DPTR,A MOV DPTR,#4000H ;A口的地址 MOVX A,@DPTR MOV A,30H MOV DPTR,#4001H ;B口的地址 MOV A,#01H ;发光二极管循环点亮测试B口 MOVX @DPTR,A LCALL YS MOV A,#02H MOVX @DPTR,A LCALL YS MOV A,#04H MOVX @DPTR,A LCALL YS MOV A,#08H MOVX @DPTR,A LCALL YS MOV A,#10H MOVX @DPTR,A LCALL YS MOV A,#20H MOVX @DPTR,A LCALL YS MOV A,#40H MOVX @DPTR,A LCALL YS MOV A,#80H MOVX @DPTR,A LCALL YS MOV DPTR,#4002H ;C口的地址 MOV A,#80H ;发光二极管循环点亮测试C口 MOVX @DPTR,A LCALL YS MOV A,#40H MOVX @DPTR,A LCALL YS MOV A,#20H MOVX @DPTR,A LCALL YS MOV A,#10H MOVX @DPTR,A LCALL YS MOV A,#08H MOVX @DPTR,A LCALL YS MOV A,#04H MOVX @DPTR,A LCALL YS MOV A,#02H MOVX @DPTR,A LCALL YS MOV A,#01H MOVX @DPTR,A LCALL YS SJMP MAIN YS: NOP TTY: MOV R3,#01H TTY1: MOV R4,#0FFH TTY2: MOV R5,#0FFH TTY3: DJNZ R5,TTY3 DJNZ R4,TTY2 DJNZ R3,TTY1 RET END 心得体会: 实验六:A/D转换的实训 目的:了解A/D转换的方式及原理,学会使用AD574芯片。 要求:模拟电压值通过574芯片转换成数字量采集出来,然后通过BC7281键盘显示芯片显示已经读出的结果。 原理:(显示部分略)  步骤:1,连接PC机和仿真机的串口线。 2,给仿真机接通电源,接通A/D模块的+12V和—12V直流电源。 3,连接P1.0—DAT,P1.1—KEY,P1.2—CLK,P1.3—SYS,并连接±5V或±10V跳线。 4,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 5,编程。 6,调试。 参考程序: #include<reg51.h> unsigned char xdata start_ad574 _at_ 0x6000; unsigned char xdata high8 _at_ 0x6002; unsigned char xdata low4 _at_ 0x6003; //*** 函数定义 *** void delay(unsigned char); //短暂延时 void write728x(unsigned char, unsigned char); // 写入到BC728x unsigned char read728x(unsigned char); // 从BC728x读出 void send_byte(unsigned char); //发送一个字节 unsigned char receive_byte(void); //接收一个字节 void chushihua_BC7281(); void bit_display(unsigned char,unsigned char); //*** 变量及I/O定义 *** unsigned char key_number; unsigned int tmr; sbit dat=P1^0; // dat 连接于 P1.0 sbit key=P1^1; // key 连接于 P1.1 sbit clk=P1^2; // clk 连接于 P1.2 sbit P1_2=P1^3; //*** 主程序 *** main() { unsigned int i; unsigned char a; unsigned char b; unsigned int c; unsigned char d; unsigned char e; float f=2.048; chushihua_BC7281(); for(;;) { P1_2=1; start_ad574=0; while(P1_2); a=high8; // b=low4; b=(low4&0xf0)/16; c=a*16+b; if(c>2047) { c=(c&0x07ff)/f; d=(c/1000)*16+(c%1000)/100; e=(((c%1000)%100)/10)*16+(((c%1000)%100)%10); write728x(0x14,0x4f); write728x(0x18,0x2f); bit_display(6,d); bit_display(7,e); bit_display(8,e); } else { c=(c^0x07ff)/f; d=(c/1000)*16+(c%1000)/100; e=(((c%1000)%100)/10)*16+(((c%1000)%100)%10); write728x(0x14,0x4a); write728x(0x18,0x2f); bit_display(6,d); bit_display(7,e); bit_display(8,e); } for(i=0;i<30000;i++) { } } } //****************************************************************** //* 初始化 BC7281 * //****************************************************************** void chushihua_BC7281() { for (tmr=0;tmr<0xffff;tmr++); // 等待BC728x完成复位 write728x(0x12,0x80); // 初始化BC728x 为164模式,不反相 } //****************************************************************** //* 按位显示 By BC7281 * //****************************************************************** void bit_display(unsigned char bt,unsigned char date) { switch(bt) { case 1 :write728x(0x15,0x00+(date&0xf0)/16);break; case 2 :write728x(0x15,0x10+(date&0x0f));break; case 3 :write728x(0x15,0x20+(date&0xf0)/16);break; case 4 :write728x(0x15,0x30+(date&0x0f));break; case 5 :write728x(0x15,0x40+(date&0xf0)/16);break; case 6 :write728x(0x15,0x50+(date&0x0f));break; case 7 :write728x(0x15,0x60+(date&0xf0)/16);break; case 8 :write728x(0x15,0x70+(date&0x0f));break; case 9 :write728x(0x15,0x80+(date&0xf0)/16);break; case 10 :write728x(0x15,0x90+(date&0x0f));break; case 11 :write728x(0x15,0xa0+(date&0xf0)/16);break; case 12 :write728x(0x15,0xb0+(date&0x0f));break; case 13 :write728x(0x15,0xc0+(date&0xf0)/16);break; case 14 :write728x(0x15,0xd0+(date&0x0f));break; case 15 :write728x(0x15,0xe0+(date&0xf0)/16);break; case 16 :write728x(0x15,0xf0+(date&0x0f));break; } } // ***************************************************************** // *写入BC728X,第一个参数为目标寄存器地址,第二个参数为要写入的数据 * // ***************************************************************** void write728x(unsigned char reg_add, unsigned char write_data) { send_byte(reg_add); //发送寄存器地址 send_byte(write_data); //发送数据字节 } // ********************************************************** // * 读出BC728X内部寄存器的值,调用参数为寄存器地址 * // ********************************************************** unsigned char read728x(unsigned char reg_add) { send_byte(reg_add|0x80); // 发送读指令(bit7=1) return(receive_byte()); //接收数据并返回 } // *********************************************************** // * 向BC728X发送一个字节 * // *********************************************************** void send_byte(unsigned char send_byte) { unsigned char bit_counter; clk=0; // 产生一个clk脉冲 clk=1; do { clk=0; // 发送clk脉冲,直至dat为低电平 clk=1; } while (dat); clk=0; // 15us之内再输出一个clk脉冲 clk=1; while (!dat); // 等待BC728X进入接收状态 for (bit_counter=0;bit_counter<8;bit_counter++) { // 发送8个比特 if ((send_byte&0x80)==0) { dat=0; // 如果待发bit为0, 置dat为0 } else { dat=1; // 反之为1 } send_byte=send_byte*2; // send_byte左移一位 clk=0; // 输出一个clk脉冲 clk=1; delay(1); //短暂延时 } dat=1; // 恢复dat为高电平 delay(2); //指令间设置一个微小延时 } // ************************************************************ // * 从BC728X接受一个字节 * // ************************************************************ unsigned char receive_byte(void) { unsigned char bit_counter, in_byte; clk=0; // 只发送单一的clk脉冲 clk=1; while (dat); // 等待BC728X响应dat低电平 clk=0; // 收到响应,在发一个脉冲等待接收数据 clk=1; for (bit_counter=0;bit_counter<8;bit_counter++) { // 接收8个bit delay(1); // 短暂延时 in_byte=in_byte*2; // in_byte左移一位 if (dat) // 如果dat为'1' { in_byte=in_byte|0x01; // bit0=1 } clk=0; // 输出一个clk脉冲 clk=1; } delay(2); //指令间设置一个微小延时 return(in_byte); } // *********************************************************** // *短暂延时程序,延时时间与time成正比,范围是几个uS到几百个uS * // *********************************************************** void delay(unsigned char time) { while (time!=0) { time--; } }心得体会: 实验七:D/A转换的实训 目的:了解D/A转换的方式及原理,学会使用DAC0832芯片。了解分辨率和精度 D/A转换中的概念。 要求:将内部数据从0FFH减小到00H并逐一送给0832芯片,把0832转换完的模拟量经 放大后给发光二极管,观察二极管的亮度变化,测量并记录0832的输出电压。 原理:  步骤:1,连接PC机和仿真机的串口线。 2,给仿真机接通电源,接通D/A模块的+12V和—12V直流电源。 3,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 4,编程。 5,调试。 参考程序: ORG 0000H MAIN: MOV R2,#0FFH BACK: MOV DPTR,#8FFFH MOV A,R2 MOVX @DPTR,A LCALL YS DJNZ R2,BACK SJMP MAIN YS: MOV R7,#02H TT0: MOV TMOD,#01H MOV TH0,#0EFH MOV TL0,#00H SETB TR0 JNB TF0,$ CLR TR0 CLR TF0 DJNZ R7,TT0 RET SJMP $ END 心得体会: 实验八:采集温度 目的:熟悉利用单片机的普通I/O口进行串行通行的过程,简单应用温度传器18B20,学会通过程序进行BCD 转换及差值校正。 要求:通过单片机用温度传感器18B20采集当时的室温,并通过BC7281芯片显示当前温度值。 原理:  步骤:1,连接PC机和仿真机的串口线。 2,给仿真机接通电源,连接温度传感器的数据线到P1.3口, P1.0—DAT,P1.1—KEY,P1.2—CLK。 3,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 4,编程。 5,调试。 参考程序: #include <reg51.h> void delay1(unsigned int); void delay(unsigned char); //短暂延时 void write728x(unsigned char, unsigned char); // 写入到BC728x unsigned char read728x(unsigned char); // 从BC728x读出 void send_byte(unsigned char); //发送一个字节 unsigned char receive_byte(void); //接收一个字节 void chushihua_BC7281(); unsigned char init_1820(void); unsigned char read_byte(void); void write_byte(unsigned char); unsigned int Read_Temperature(void); //*** 变量及I/O定义 *** sbit dat=P1^0; // dat 连接于 P1.0 sbit key=P1^1; // key 连接于 P1.1 sbit clk=P1^2; // clk 连接于 P1.2 sbit DQ =P1^3; // DQ 连接于 P1.3 void main(void) //主函数 { unsigned int i; chushihua_BC7281(); while(1) { i=Read_Temperature(); if(i>1250) { i=0xffff-i; write728x(0x18,0x26); } write728x(0x18,0xa6); write728x(0x18,0x37); write728x(0x15,0x50+i/100); write728x(0x15,0x60+i%100/10); write728x(0x15,0x70+i%100%10); for(i=0;i<100;i++) //每次转换需要延时200ms以上 delay(500); } } //延时 void delay(unsigned char time) { while (time!=0) { time--; } } void delay1(unsigned int time) { for(;time>0;time--); } //复位 unsigned char init_1820(void) { unsigned char presence; DQ=0; delay1(29); DQ=1; delay1(3); presence=DQ; delay1(25); return(presence); } //从 1-wire 总线上读取一个字节 unsigned char read_byte(void) { unsigned char i; unsigned char value=0; for (i=8;i>0;i--) { value>>=1; DQ=0; DQ=1; delay1(1); if(DQ)value|=0x80; delay1(6); } return(value); } //向 1-WIRE 总线上写一个字节 void write_byte(unsigned char val) { unsigned char i; for (i=8; i>0; i--) { DQ=0; DQ=val&0x01; delay1(5); DQ=1; val=val/2; } delay1(5); } //读取温度 unsigned int Read_Temperature(void) { union { unsigned char c[2]; int x; }temp; init_1820(); write_byte(0xCC); // Skip ROM write_byte(0xBE); // Read Scratch Pad temp.c[1]=read_byte(); temp.c[0]=read_byte(); init_1820(); write_byte(0xCC); //Skip ROM write_byte(0x44); // Start Conversion return temp.x/2; } //****************************************************************** //* 初始化 BC7281 * //****************************************************************** void chushihua_BC7281() { unsigned int tmr; for (tmr=0;tmr<0xffff;tmr++); // 等待BC728x完成复位 write728x(0x12,0x80); // 初始化BC728x 为164模式,不反相 } // ***************************************************************** // *写入BC728X,第一个参数为目标寄存器地址,第二个参数为要写入的数据 * // ***************************************************************** void write728x(unsigned char reg_add, unsigned char write_data) { send_byte(reg_add); //发送寄存器地址 send_byte(write_data); //发送数据字节 } // *********************************************************** // * 向BC728X发送一个字节 * // *********************************************************** void send_byte(unsigned char send_byte) { unsigned char bit_counter; clk=0; // 产生一个clk脉冲 clk=1; do { clk=0; // 发送clk脉冲,直至dat为低电平 clk=1; } while (dat); clk=0; // 15us之内再输出一个clk脉冲 clk=1; while (!dat); // 等待BC728X进入接收状态 for (bit_counter=0;bit_counter<8;bit_counter++) { // 发送8个比特 if ((send_byte&0x80)==0) { dat=0; // 如果待发bit为0, 置dat为0 } else { dat=1; // 反之为1 } send_byte=send_byte*2; // send_byte左移一位 clk=0; // 输出一个clk脉冲 clk=1; delay(1); //短暂延时 } dat=1; // 恢复dat为高电平 delay(2); //指令间设置一个微小延时 } // ************************************************************ // * 从BC728X接受一个字节 * // ************************************************************ unsigned char receive_byte(void) { unsigned char bit_counter, in_byte; clk=0; // 只发送单一的clk脉冲 clk=1; while (dat); // 等待BC728X响应dat低电平 clk=0; // 收到响应,在发一个脉冲等待接收数据 clk=1; for (bit_counter=0;bit_counter<8;bit_counter++) { // 接收8个bit delay(1); // 短暂延时 in_byte=in_byte*2; // in_byte左移一位 if (dat) // 如果dat为'1' { in_byte=in_byte|0x01; // bit0=1 } clk=0; // 输出一个clk脉冲 clk=1; } delay(2); //指令间设置一个微小延时 return(in_byte); } 心得体会: 实验九:制作音乐盒 目的:了解基本音符的发音机理,学会用单片机产生一定频率的方波,了解简单的乐谱知识。 要求:用单片机控制喇叭,播放一首乐曲。 原理:  步骤:1,连接PC机和仿真机的串口线。 2,给仿真机接通电源,给音乐盒模块接通电源,连接P1.0 口到音乐盒的SPK管脚。 3,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 4,编程。 5,调试。 参考程序: ORG 0000H DO_L EQU 0 DO#_L EQU 1 RE_L EQU 2 RE#_L EQU 3 MI_L EQU 4 FA_L EQU 5 FA#_L EQU 6 SO_L EQU 7 SO#_L EQU 8 LA_L EQU 9 LA#_L EQU 10 SI_L EQU 11 DO DATA 12 DO# DATA 13 RE DATA 14 RE# DATA 15 MI DATA 16 FA DATA 17 FA# DATA 18 SO DATA 19 SO# DATA 20 LA DATA 21 LA# DATA 22 SI DATA 23 MI#_L DATA 36 SI#_L DATA 37 DO_H EQU 24 DO#_H EQU 25 RE_H EQU 26 RE#_H EQU 27 MI_H EQU 28 FA_H EQU 29 FA#_H EQU 30 SO_H EQU 31 SO#_H EQU 32 LA_H EQU 33 LA#_H EQU 34 SI_H EQU 35 FOUT BIT P1.0 ;频率输出口 ;主程序 ORG 0000H MAIN: MOV SP,#70H ;初始化堆栈 MOV TMOD,#01H ;定时器T0用模式1,以防烧坏扬声器 CLR FOUT MODE1: MOV DPTR,#SONG ;乐曲的首地址 LCALL MUSIC ;播放乐曲 SJMP MODE1 ;返回重新选择模式 MUSIC: MOV A,#00H MOVC A,@A+DPTR MOV 31H,A INC DPTR MOV A,#00H MOVC A,@A+DPTR MOV 32H,A PUSH DPH PUSH DPL CJNE A,#0FFH,SING POP DPL POP DPH SJMP STOP SING: MOV DPTR,#TABLE MOV A,31H RL A MOVC A,@A+DPTR MOV TH0,A MOV 33H,A MOV A,31H RL A INC A MOVC A,@A+DPTR MOV TL0,A MOV 34H,A SETB TR0 HOLD: LCALL DELAY POP DPL POP DPH INC DPTR SJMP MUSIC STOP: CLR TR0 CLR FOUT RET DELAY: MOV 36H,#78H DELAY1: MOV 35H,#58H DELAY2: JNB TF0,DELAY4 CLR TF0 MOV TH0,33H MOV TL0,34H CPL FOUT SJMP DELAY5 DELAY4: NOP NOP NOP NOP DELAY5: DJNZ 35H,DELAY2 DJNZ 36H,DELAY1 DJNZ 32H,DELAY DELAYR: RET TABLE: DW 0F922H DW 0F981H DW 0F90E1H DW 0FA37H DW 0FA8CH DW 0FA0D7H DW 0FB23H DW 0FB6CH DW 0FBAAH DW 0FBE9H DW 0FC24H DW 0FC5CH DW 0FC8FH DW 0FCC1H DW 0FCEFH DW 0FD1CH DW 0FD46H DW 0FD6DH DW 0FD92H DW 0FDB5H DW 0FDD6H DW 0FDF5H DW 0FE21H DW 0FE2EH DW 0FE49H DW 0FE61H DW 0FE78H DW 0FE8EH DW 0FEA3H DW 0FEB7H DW 0FEC9H DW 0FEDBH DW 0FEEBH DW 0FEFBH DW 0FF9H DW 0FF17H DW 0FF8CH DW 0FF9FH SONG: DB LA_L,04H,LA_L,02H,LA_L,02H,RE,04H,DO,02H,RE,02H,MI,10H DB MI,02H,SO,02H,DO,04H,SI_L,02H,LA_L,02H,SO_L,02H,LA_L,02H DB MI_L,02H,SO_L,02H,LA_L,14H,MI_L,08H,SO_L,08H,LA_L,04H,RE,02H DB LA_L,02H,DO,08H, LA_L,04H,LA_L,02H,DO,02H,LA_L,04H,SO,02H DB MI,02H,RE,14H,MI,04H,MI,02H,MI,02H,SO,04H,MI,02H,SO,02H DB LA,10H,LA,02H,SO,02H,MI,04H,MI,02H,MI,02H,RE,02H,MI,02H DB LA_L,04H,DO,12H DB 0FFH,0FFH END 心得体会: 实验十:制作四字单色显示屏 目的:了解显示屏的工作原理,学会串口并口的同时使用。 要求:在LED显示屏上由左向右循环显示:“欢迎使用本系统!”字样。 移动和扫描速度均可调。 原理:  步骤:1,连接PC机和仿真机的串口线。 2,连接显示屏数据线(P1.0—P1.3连接A—D,P3.0连接G,P3.1连接CP,P3.2连接DAT)。 3,给仿真机接通电源。 4,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 5,编程。 6,调试。 参考程序: ZISHU EQU 2*4 ;一个字有2个块组成,共4个字 ORG 0000H MAIN: MOV P1,#255 CLR P3.0 LCALL H LCALL RU START: MOV 20H,#01H BACK1: LCALL SM ;扫描十六行,即逐行给显示块送数据 NOP DJNZ 20H,BACK1 LCALL ZY LJMP START H: MOV DPTR,#0C003H ;初始化8255芯片,A口,B口均为输出口,作为行的控制口 MOV A,#90H ;6008H为8155的命令状态口地址 MOVX @DPTR,A RET RU: MOV R3,#010H MOV R2,#00H MOV DPTR,#2000H PUSH DPH PUSH DPL RU1:LCALL DUS POP DPL POP DPH MOV 45H,DPL LCALL CM INC R2 INC R2 MOV A,45H SWAP A INC A SWAP A MOV DPL,A PUSH DPH PUSH DPL DJNZ R3,RU1 POP ACC POP ACC RET DUS:MOV R0,#20H MOV DPTR,#TABLE1 LCALL QM MOV DPTR,#TABLE2 LCALL QM MOV DPTR,#TABLE3 LCALL QM MOV DPTR,#TABLE4 LCALL QM MOV DPTR,#TABLE5 LCALL QM MOV DPTR,#TABLE6 LCALL QM MOV DPTR,#TABLE7 LCALL QM MOV DPTR,#TABLE8 LCALL QM RET ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> QM: MOV A,R2 MOVC A,@A+DPTR MOV @R0,A MOV A,R2 INC DPTR INC R0 MOVC A,@A+DPTR MOV @R0,A INC R0 RET ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> CM: NOP MOV R0,#2FH MOV R6,#ZISHU*2 H1: MOV A,@R0 MOVX @DPTR,A DEC R0 INC DPTR DJNZ R6,H1 RET ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SM: MOV R3,#0FFH ;行扫描的初始值设定,行以循环递推的方式逐行扫描,上8行 MOV R4,#07FH ;下8行 MOV DPTR,#2000H MOV R7,#16 ;扫描16行 XYH: NOP MOV R5,#ZISHU ;给2*4个164芯片送数的次数 PUSH DPH ;入栈保护DPTR PUSH DPL CLR P3.1 HANG: setb P3.0 MOVX A,@DPTR MOV C,ACC.0 MOV P3.2,C SETB P3.1 CLR P3.1 MOV C,ACC.1 MOV P3.2,C SETB P3.1 CLR P3.1 MOV C,ACC.2 MOV P3.2,C SETB P3.1 CLR P3.1 MOV C,ACC.3 MOV P3.2,C SETB P3.1 CLR P3.1 MOV C,ACC.4 MOV P3.2,C SETB P3.1 CLR P3.1 MOV C,ACC.5 MOV P3.2,C SETB P3.1 CLR P3.1 MOV C,ACC.6 MOV P3.2,C SETB P3.1 CLR P3.1 MOV C,ACC.7 MOV P3.2,C SETB P3.1 CLR P3.1 INC DPTR DJNZ R5,HANG clr P3.0 inc p1 MOV 50H,#03FH HANG1: MOV DPTR,#0C001H ;8255芯片的A口地址 MOV A,R3 MOVX @DPTR,A INC DPTR ;8255芯片的B口地址 MOV A,R4 MOVX @DPTR,A DJNZ 50H,HANG1 MOV DPTR,#0C001H MOV A,#0FFH MOVX @DPTR,A INC DPTR MOVX @DPTR,A MOV A,R3 ;将行扫描的初始值循环递推,为扫描下一行做准备 MOV C,ACC.0 MOV A,R4 RRC A MOV R4,A ;保存行扫描的初始值的上8行 MOV A,R3 RRC A MOV R3,A ;保存行扫描的初始值的下8行 POP DPL POP DPH MOV A,DPL SWAP A INC A SWAP A MOV DPL,A DJNZ R7,XYH ;继续扫描下一行 setb P3.0 RET ;16行数据扫描完毕 ZY: MOV R3,#010H MOV DPTR,#2000H MOV 42H,DPH MOV 43H,DPL MOV DPTR,#200FH MOV 40H,DPH MOV 41H,DPL ZY1:MOVX A,@DPTR MOV C,ACC.7 MOV DPH,42H MOV DPL,43H Y: MOV R4,#10H Y1: MOVX A,@DPTR RLC A MOVX @DPTR,A INC DPTR DJNZ R4,Y1 MOV A,41H SWAP A INC A SWAP A MOV 41H,A MOV A,43H SWAP A INC A SWAP A MOV 43H,A MOV DPH,40H MOV DPL,41H DJNZ R3,ZY1 NOP RET SJMP $ ;>>>>>>>>>>>>>>>>>>>>>>>>>>>两行之间延时子程序 DELAY50:MOV TMOD,#11H MOV TH1,#0FEH MOV TL1,#0D0H CLR TF1 SETB TR1 JNB TF1,$ CLR TR1 CLR TF1 RET YS: MOV 40H,#00H YS1: DJNZ 40H,YS1 RET TABLE1:;欢;-- 欢 -- ** 宋体, 12 ** ; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=16x16, 调整后为: 16x16 DB 0FFH,07FH,0FFH,07FH,003H,07FH,0FAH,001H,07AH,0FBH,0B5H,0B7H,0D7H,0BFH,0EFH,0BFH DB 0E7H,0BFH,0E7H,09FH,0DBH,05FH,0DBH,06FH,0BEH,0E7H,079H,0F1H,0C7H,0FBH,0FFH,0FFH TABLE2:;迎;-- 迎 -- ** 宋体, 12 ** ; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=16x16, 调整后为: 16x16 DB 0BFH,0FFH,0DEH,07FH,0C9H,083H,0DBH,0BBH,0FBH,0BBH,0FBH,0BBH,01BH,0BBH,0DBH,0BBH DB 0DAH,0BBH,0D9H,0ABH,0DBH,0B7H,0DFH,0BFH,0DFH,0BFH,0AFH,0FFH,070H,001H,0FFH,0FFH TABLE3:;使;-- 使 -- ** 宋体, 12 ** ; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=16x16, 调整后为: 16x16 DB 0F7H,0BFH,0F3H,0BFH,0E4H,001H,0EFH,0BFH,0C8H,003H,09BH,0BBH,05BH,0BBH,0D8H,003H DB 0DBH,0BBH,0DDH,0BFH,0DEH,07FH,0DFH,07FH,0DEH,08FH,0DDH,0E1H,0D3H,0FBH,0FFH,0FFH TABLE4:;用;-- 用 -- ** 宋体, 12 ** ; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=16x16, 调整后为: 16x16 DB 0FFH,0FFH,0E0H,003H,0EFH,07BH,0EFH,07BH,0EFH,07BH,0E0H,003H,0EFH,07BH,0EFH,07BH DB 0EFH,07BH,0E0H,003H,0EFH,07BH,0EFH,07BH,0DFH,07BH,0DFH,07BH,0BFH,06BH,07FH,077H TABLE5:;本;-- 本 -- ** 宋体, 12 ** ; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=16x16, 调整后为: 16x16 DB 0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,000H,001H,0FCH,07FH,0FCH,0BFH,0FAH,0BFH,0FAH,0DFH DB 0F6H,0EFH,0EEH,0E7H,0D0H,011H,03EH,0FBH,0FEH,0FFH,0FEH,0FFH,0FEH,0FFH,0FFH,0FFH TABLE6:;系;-- 系 -- ** 宋体, 12 ** ; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=16x16, 调整后为: 16x16 DB 0FFH,083H,0C0H,07FH,0FDH,0DFH,0FBH,0DFH,0F7H,0BFH,0E0H,07FH,0FCH,0DFH,0F3H,0EFH DB 0C0H,007H,0EFH,073H,0FBH,05FH,0F7H,06FH,0EFH,077H,0DFH,07BH,0BDH,07BH,0FEH,0FFH TABLE7:;统;-- 统 -- ** 宋体, 12 ** ; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=16x16, 调整后为: 16x16 DB 0EFH,0BFH,0EFH,0DFH,0DCH,001H,0DFH,0BFH,0BBH,0BFH,007H,077H,0F6H,0FBH,0ECH,001H DB 0DFH,06BH,083H,06FH,0FFH,06FH,0FFH,06FH,0E2H,0EDH,01EH,0EDH,0FDH,0F1H,0FBH,0FFH TABLE8:;!;-- ! -- ** 宋体, 12 ** ; 当前所选字体下一个汉字对应的点阵为: 宽度x高度=16x16, 调整后为: 16x16 DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0EFH,0FFH,0EFH,0FFH,0EFH,0FFH,0EFH,0FFH DB 0EFH,0FFH,0EFH,0FFH,0EFH,0FFH,0EFH,0FFH,0EFH,0FFH,0FFH,0FFH,0EFH,0FFH,0FFH,0FFH END 心得体会: 实验十一:控制微型打印机 目的:了解单片机的串行通讯,简单应用微型打印机,熟悉单片机和外设之间的联系,提 高自己的动手能力。 要求:利用单片机的串口和微型打印机连接,打印输出“欢迎使用本系统!”字样。 原理:  步骤:1,连接PC机和仿真机的串口线。 2,给仿真机接通电源,连接打印机的数据线和P3.5口,接通打印机的电源。 5,打开仿真机的电源开关,电源灯亮表示仿真机已经带电。 6,编程。 7,调试。 参考程序: ORG 0000H AJMP MAIN ORG 0040H MAIN: MOV TH1,#0F4H MOV TMOD,#020H MOV SCON,#0D0H MOV TCON,#44H MOV IE,#14H MOV IP,#10H CLR A AA0: MOV DPTR,#TAB AA1: CLR A MOVC A,@A+DPTR CJNE A,#0FFH,AA2 AJMP AA0 AA2: ACALL PRINT INC DPTR JMP AA1 TAB: DB '1','2','3','4','5','6','7','8','9','A' DB 13 DB 1BH,38H,00H,'欢','迎','使','用','本','系','统', DB 1BH,36H PRINT: SETB P1.0 JB P1.0,PRINT MOV SBUF,A JNB TI,$ CLR TI RET END 心得体会: