《计算机组织结构》实验报告 之 进位控制实验

时间:2024.3.31

《计算机组织结构》实验报告

实验序号:03               实验项目名称: 进位控制实验         


第二篇:单片机实验报告


实验一  LED流水灯

一、实验目的

1. 学习单片机并口的使用方法。

2. 学习延时子程序的编写和使用。

3. 学习集成开发环境MedWin的安装与使用。

4. 学习STC单片机在线下载软件STC-ISP的使用。

二、实验内容

所谓流水灯就是8个发光二极管(LED)轮流点亮,周而复始。实验板上以P0口作输出口,经74LS244驱动,接8只发光二极管LED0-LED7。当单片机的引脚输出为低电平时发光二极管点亮,为高电平时息灭。编写程序,使8个发光二极管循环点亮,时间间隔约0.5秒。

三、试验器具

STC89C51, 74LS244,8个限流电阻接8个LED发光管。

四、实验内容

1、74LS244驱动输出串联8个限流电阻接8个LED发光管,以防止其电流过大而烧坏。单片机的主时钟为11.0592MHz。JMP0和JMP1都短接1-2脚。

P0口作为通用接口时是一准双向口,它作为输出口时与一般的双向口使用方法相同。由准双向口结构可知当P0口用作输入口时必须先对它置“1”。若不先对它置“1”,读入的数据是不正确的。输出时需要接上拉电阻,P0口内部没有上拉电阻,若将外围电路设计为低有效,高无效,则无需再外接上拉电阻。

编写一个软件延时子程序,延时时间约0.5秒,采用三重循环实现,汇编语言程序如下:

DELAY: MOV  R7, #198

DEL1:  MOV  R6, #50

DEL2:  MOV  R5, #23

       DJNZ R5, $

       DJNZ R6, DEL2

       DJNZ R7, DEL1

       RET

查指令表可知执行MOV指令需用1个机器周期,DJNZ指令需用2个机器周期,在11.0592MHz晶振时,一个机器周期时间长度为1.085μs,所以该段程序执行时间为:

[1+(1+2×23)×50]×198×1.085μs ≈ 500mS

流水灯的主程序(汇编语言)为:

       ORG 0000H

       LJMP MAIN

       ORG 0100H

MAIN:  CLR P1.5=0    ; P1.5=0,关闭蜂鸣器。

MOV A,#0FEH

LOP:   MOV P0,A

       LCALL DELAY

       RL A

       SJMP LOP

       END

 

2、代码

ORG 0000H
 LJMP MAIN
ORG 0100H
MAIN: CLR P1.5=0
      MOV A,#0FEH
LOP:  MOV P0,A
      LCALL DELAY
      RL A
 SJMP LOP 
DELAY: MOV R7,#198
DEL1: MOV R6,#50
DEL2: MOV R5,#23
 DJNZ R5,$
 DJNZ R6,DEL2
 DJNZ R7,DEL1
 RET
  END

五、创新

要求实现从左到右先一个LED灯点亮,经过四个LED灯后,再从左到右两个LED灯点亮。一次循环下去。

ORG 0000H
 LJMP MAIN
ORG 0100H
MAIN: CLR P1.5=0
      MOV A,#0EEH
LOP:  MOV P0,A
      LCALL DELAY
      RL A
 SJMP LOP 
DELAY: MOV R7,#198
DEL1: MOV R6,#50
DEL2: MOV R5,#23
 DJNZ R5,$
 DJNZ R6,DEL2
 DJNZ R7,DEL1
 RET
  END

六、思考题

从中间向两边

ORG 0000H
 LJMP MAIN
ORG 0100H
MAIN: CLR P1.5=0
      MOV A,#0EEH
LOP:  MOV P0,A
      LCALL DELAY

     MOV  A,R1

     RL  A

     MOV  R1,A

     MOV  A,R2

     RR   A

     MOV  R2,A

     MOV  A,R1

     SWAP  A

     ADD  R2

     CPL  A

SJMP  LOP

DELAY: MOV R7,#198
DEL1: MOV R6,#50
DEL2: MOV R5,#23
     DJNZ R5,$
     DJNZ R6,DEL2
     DJNZ R7,DEL1
     RET
    END

 六、实验心得

1. 学会了单片机并口的使用方法。

2. 学会了延时子程序的编写和使用。

3. 学会了集成开发环境MedWin的安装与使用。

4. 学会了STC单片机在线下载软件STC-ISP的使用。

    5. 利用51单片机控制LED的亮灭,并且学会了流水灯不同花样的实现

   6. 对mov指令的记忆加强,学会运用。

   7. 学习对延迟语句的应用。

实验二  用一位数码管循环显示数字0~9

一、实验目的

1. 学习单片机并口的使用方法。

2. 学习延时子程序的编写和使用。

3. 学习LED数码管的驱动、编码。

二、实验内容

实验板上有8个LED数码管,编写程序,使最右边的一个LED数码管循环显示0~9十个数字。时间间隔约0.5秒,其余LED数码管关闭。

三、实验电路连线

实验板上与本实验有关的硬件如下图所示。8个共阳的LED数码管(S0-S7)上同名的引脚连接在一起,由单片机P0口通过74HC244驱动(段控制),R12-R19为限流电阻。单片机P2口的8个引脚分别通过三极管Q0-Q7控制8个LED数码管的公共端(位控制)。单片机的主时钟为11.0592MHz。JMP0短接2-3脚,JMP1短接1-2脚。

四、实验说明

1、P0口和P2都是准双向口,输出时需要接上拉电阻。P0内部没有上拉电阻,P2口内部有弱上拉。

2、下表为驱动LED数码管的段代码表,1--代表对应的笔段亮,0--代表对应的笔段不亮。若需要在最右边(S0)显示数字“5”,只要将从表中查得的段代码2CH写入P0口,再将P2.0置高,P2.1-P2.7置低即可。

4、实现最右边的一个LED数码管循环显示0~9十个数字的汇编语言程序如下:

ORG 0000H

       LJMP MAIN

ORG 0100H

MAIN:  MOV P1,#0FFH

       MOV P2,#01H

       MOV R1,#00H

LOOP:  MOV A,R1

       MOV DPTR,#TAB

       MOVC A,@A+DPTR

       MOV P0,A

       LCALL DELAY

       INC R1

      

五、创新思考题

1、分别写出 ABCDEF 六个字母(用于显示十六进制数)的段代码,编写程序,在最右边数码管上实现0-F的循环显示。

   ORG 0000H

LJMP MAIN

ORG 0100H

MAIN: MOV P1,#0DFH

MOV P2,#01H

MOV R1,#00H

LOOP: MOV A,R1

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV P0,A

LCALL DELAY

INC R1

MOV A,R1

CJNE A,#7,LOOP

CLR A

MOV R1,A

SJMP LOOP

DELAY: MOV R7,#198

DEL1: MOV R6,#50

DEL2: MOV R5,#23

DJNZ R5,$

DJNZ R6,DEL2

DJNZ R7,DEL1

RET

TAB: DB 48H,0C0H,45H,5CH,43H,54H,0D4H

       END

2. 能否交替点亮点8个LED数码管?

ORG 0000H

LJMP MAIN

ORG 0100H

MAIN: MOV P1,#0FFH

MOV P2,#01H 

MOV R1,#00H

LOOP: MOV A,R1

MOV DPTR,#TAB

MOVC A,@A+DPTR

MOV P0,A

LCALL DELAY

INC R1

MOV A,P2

RL A

MOV P2,A 

MOV A,R1

CJNE A,#10,LOOP

CLR A

MOV R1,A

SJMP LOOP

DELAY: MOV R7,#198

DEL1: MOV R6,#50

DEL2: MOV R5,#23

DJNZ R5,$

DJNZ R6,DEL2

DJNZ R7,DEL1

RET

TAB: DB 48H,0EBH,52H,62H,0E1H,64H,44H,0EAH,40H,60H

END

六、实验心得

1. 学会了延时子程序的编写和使用

2. 学会了通过语句使数码管循环点亮。

2、学会了每个数码管上每一个数字8上笔画所代表的含义以及它的代码。

3、学习了利用语句实现数码管上灯的左移、右移、延迟。

实验三  LED数码管的动态驱动

一、实验目的

1. 学习LED数码管的动态驱动编程。

2. 学习使用定时/计数器、中断。

3.学习汇编语言的有关运算。

二、实验内容

编写程序,使实验板上的8个LED数码管稳定显示8个不同的数字,并使这四位数从00000000开始,每0.5秒钟加1。

三、实验电路连线

四、实验说明

1. 在实验二中,我们已经能够让某一个LED数码管显示需要的数字,比如选让第一个LED显示“1”,隔一较短的时间(如2.5毫秒)后关闭第一个LED,让第二个LED显示“2”,如此周而复始,让8个LED依次显1、2、3、4、5、6、7、8,我们就能看到8个LED上稳定地显示8个不同的数字。当然,每个瞬间只有一个LED被点亮,大家亮的时间相同,均为2.5毫秒,8个LED数码管点亮一遍需要20毫秒,一秒钟各亮50次,所以看上去不会有闪烁感,但亮度只是实验二中LED亮度的八分之一。

要实现每隔再隔2.5毫秒变换一个LED,最好的方法是使用定时器中断。

2. 汇编语言参考程序为:

LED_PORT  EQU P0  ;笔划输出,低有效

SCN_PORT  EQU P2  ;段扫描输出,低有效(P2.4-P2.7)

       DSEG

       ORG 10H

DISP_BUF: DS  8   ;显示缓冲区

SCN_INX:  DS  1   ;扫描指针

SCN_COD:  DS  1   ;扫描码

CNT:   DS  1   ;中断计数,每2.5ms加1

      

       CSEG

       ORG   00H

       LJMP  MAIN   ;主程序入口,转初始化程序

       ORG   0BH ;定时中断0入口

       LJMP  INTP0  ;每2.5ms中断一次,用于刷新显示

;-----------初------始-----化---------------------------------

       ORG   30H

MAIN:  MOV SP,#50H    ;初始化堆栈指针

       CLR RS0    ;选用第0组通用寄存器

       CLR RS1

       CLR P1.5

      

       CLR A

       MOV CNT,A

       MOV R1,#8

       MOV R0,#DISP_BUF

LOOP1: MOV @R0,A     ;显示缓冲区清零

       INC R0

       DJNZ R1,LOOP1

             

       MOV SCN_INX,A  ;扫描指针置0

          MOV SCN_COD,#80H  ;右边LED先点亮

          MOV TMOD,#01H  ;定时器0,方式1

       MOV   TH0,#0F7H  ;计数初值,每次2.5ms(11.0592MHz晶振)

       MOV   TL0,#000H  ;65536-(2.5ms/1.085us)=65536-2304=63232=0F700H

       SETB  TR0    ;启动定时器0

       SETB   EA        ;中断总允许

          SETB   ET0    ;允许定时器0中断

       SJMP   $      ;主程序在此循环

;-----------定时器0中断服务程序,间隔2.5ms--------------

INTP0: PUSH   ACC

       PUSH   PSW

       MOV    TH0,#0F7H  ;置计数初值

       MOV   TL0,#00H

       SETB   RS0    ;选用第1组通用寄存器

       CLR RS1

      

       MOV A,SCN_INX  ;取扫描指针

       ANL A,#07H     ;清除高5位

       ADD A,#DISP_BUF   ;加显示缓冲区首地址

       MOV R1,A

       MOV A,@R1

       MOV DPTR,#CODE_TAB    ;DPTR指向笔划代码表

       ANL A,#0FH

          MOVC A,@A+DPTR    ;取笔划代码

       MOV LED_PORT,A    ;笔划代码送LED口

      

       MOV A,SCN_COD  ;取扫描段代码

       MOV P2,A

          MOV A,SCN_COD

          RR A          ;扫描段代码循环右移一位

       MOV SCN_COD,A

       INC SCN_INX    ;扫描指针+1

      

       INC CNT

       MOV A,CNT

       CJNE A,#200,EN

       MOV CNT,#0

      

       INC DISP_BUF+7 ;个位加一

       MOV A,DISP_BUF+7

       CJNE A,#10,EN     ;不进位转移

       MOV DISP_BUF+7,#0 ;进位则个位清零

       INC DISP_BUF+6 ;十位加一

       MOV A,DISP_BUF+6

       CJNE A,#10,EN

       MOV DISP_BUF+6,#0 ;进位则十位清零

       INC DISP_BUF+5 ;百位加一

       MOV A,DISP_BUF+5

       CJNE A,#10,EN

       MOV DISP_BUF+5,#0 ;进位则百位清零

       INC DISP_BUF+4 ;千位加一

       MOV A,DISP_BUF+4

       CJNE A,#10,EN

       MOV DISP_BUF+4,#0 ;进位则千位清零

       INC DISP_BUF+3 ;万位加一

       MOV A,DISP_BUF+3

       CJNE A,#10,EN

       MOV DISP_BUF+3,#0 ;进位则万位清零

       INC DISP_BUF+2 ;十万位加一

       MOV A,DISP_BUF+2

       CJNE A,#10,EN

       MOV DISP_BUF+2,#0 ;进位则十万位清零

       INC DISP_BUF+1 ;百万位加一

       MOV A,DISP_BUF+1

       CJNE A,#10,EN

       MOV DISP_BUF+1,#0 ;进位则百万位清零

       INC DISP_BUF+0 ;千万位加一

       MOV A,DISP_BUF+0

       CJNE A,#10,EN

       MOV DISP_BUF+0,#0 ;进位则千万位清零

      

EN:    POP PSW

       POP ACC

       RETI

;----------笔划代码表-------------------------

CODE_TAB: DB  48H,0EBH,52H,62H,0E1H,64H,44H,0EAH,40H,60H

       END

五、创新

实现时钟的功能。让8个LED数码管从00-00-00开始,每秒钟自动加1,前两位代表时,中间两位代表分,后两位代表秒。

LED_PORT  EQU P0  ;笔划输出,低有效

SCN_PORT  EQU P2  ;段扫描输出,低有效(P2.4-P2.7)

       DSEG

       ORG 10H

DISP_BUF: DS  8   ;显示缓冲区

SCN_INX:  DS  1   ;扫描指针

SCN_COD:  DS  1   ;扫描码

CNT:   DS  1   ;中断计数,每2.5ms加1

       CSEG

       ORG   00H

       LJMP  MAIN   ;主程序入口,转初始化程序

       ORG   0BH ;定时中断0入口

       LJMP  INTP0  ;每2.5ms中断一次,用于刷新显示

;-----------初------始-----化---------------------------------

       ORG   30H

MAIN:  MOV SP,#50H    ;初始化堆栈指针

       CLR RS0    ;选用第0组通用寄存器

       CLR RS1

       CLR P1.5 

       CLR A

       MOV CNT,A

       MOV R1,#8

       MOV R0,#DISP_BUF

LOOP1: MOV @R0,A     ;显示缓冲区清零

       INC R0

       DJNZ R1,LOOP        

       MOV SCN_INX,A  ;扫描指针置0

          MOV SCN_COD,#80H  ;右边LED先点亮

          MOV DISP_BUF+5,#10

          MOV DISP_BUF+2,#10         MOV TMOD,#01H  ;定时器0,方式1

       MOV   TH0,#0F7H  ;计数初值,每次2.5ms(11.0592MHz晶振)

       MOV   TL0,#000H  ;65536-(2.5ms/1.085us)=65536-2304=63232=0F700H

       SETB  TR0    ;启动定时器0

       SETB   EA        ;中断总允许

          SETB   ET0    ;允许定时器0中断

       SJMP   $      ;主程序在此循环

;-----------定时器0中断服务程序,间隔2.5ms--------------

INTP0: PUSH   ACC

       PUSH   PSW

       MOV    TH0,#0F7H  ;置计数初值

       MOV   TL0,#00H

       SETB   RS0    ;选用第1组通用寄存器

       CLR RS1 

       MOV A,SCN_INX  ;取扫描指针

       ANL A,#07H     ;清除高5位

       ADD A,#DISP_BUF   ;加显示缓冲区首地址

       MOV R1,A

       MOV A,@R1

       MOV DPTR,#CODE_TAB    ;DPTR指向笔划代码表

       ANL A,#0FH

          MOVC A,@A+DPTR    ;取笔划代码

       MOV LED_PORT,A    ;笔划代码送LED口

       MOV A,SCN_COD  ;取扫描段代码

       MOV P2,A

          MOV A,SCN_COD

          RR A          ;扫描段代码循环右移一位

       MOV SCN_COD,A

       INC SCN_INX    ;扫描指针+1

      

       INC CNT

       MOV A,CNT

       CJNE A,#200,EN

       MOV CNT,#0

      

       INC DISP_BUF+7 ;个位加一

       MOV A,DISP_BUF+7

       CJNE A,#10,EN     ;不进位转移

       MOV DISP_BUF+7,#0 ;进位则个位清零

       INC DISP_BUF+6 ;十位加一

       MOV A,DISP_BUF+6

       CJNE A,#6,EN

       MOV DISP_BUF+6,#0 ;进位则十位清零

      

       INC DISP_BUF+4 ;千位加一

       MOV A,DISP_BUF+4

       CJNE A,#10,EN

       MOV DISP_BUF+4,#0 ;进位则千位清零

       INC DISP_BUF+3 ;万位加一

       MOV A,DISP_BUF+3

       CJNE A,#6,EN

       MOV DISP_BUF+3,#0 ;进位则万位清零

      

       INC DISP_BUF+1 ;百万位加一

       MOV A,DISP_BUF+1

       CJNE A,#4,EN

       MOV DISP_BUF+1,#0 ;进位则百万位清零

       INC DISP_BUF+0 ;千万位加一

       MOV A,DISP_BUF+0

       CJNE A,#2,EN

       MOV DISP_BUF+0,#0 ;进位则千万位清零      

EN:    POP PSW

       POP ACC

       RETI

;----------笔划代码表-------------------------

CODE_TAB: DB  48H,0EBH,52H,62H,0E1H,64H,44H,0EAH,40H,60H,0F7H

       END

 六、实验心得

1. 学习了利用51单片机和数码管进行编码,然后实现时钟的控制。

2. 学习了定时器,中断的语句设计和运用。

3. 学习LED数码管的动态驱动编程。

5.学习汇编语言的有关运算。

实验四  用单片机自动演奏乐曲

一、实验目的

(1)进一步熟悉89C51定时器/计数器的功能及应用;

(2)掌握其初始化与中断服务程序的编程方法;

(3)掌握用定时器/计数器发出不同音调的编程方法。

二、实验内容

用单片机的定时器/计数器0作定时器使用,工作于模式1,中断产生方波发声,根据各个的频率,计算对应的定时时间常数,定时器中断后按此常数赋初值,从而发出对应的音调。将歌曲的音调和节拍编成一个表,用音调作为定时器的初值,用节拍控制发音时间, 就可以实现自动演奏。

三、实验电路连线

本实验有关的硬件如右图所示。

四、实验说明

声单定时初值常数计算方法:

根据下表的音阶频率,计算对应的音阶周期T,用T/2计算定时周期数(晶振11.0592MHz),填入下表中。定时器的计数初值为65536-定时周期数,在程序计算产生。定时周期数增加1倍,音阶降低八度,定时周期数降低1倍,音阶升高八度。

自动演奏《东方红》乐曲的C语言程序为:

#include <REG51.h>

#define uchar unsigned char

#define uint  unsigned int

sbit P15=P1^5;

code uint cyc[]={3600,3200,2880,2702,2400,2158,1920};//音阶1-7对应的计数周期数

code uchar tone[]={15,15,16,12,11,11,06,12,15,15,16,21,16,15,11,11,

            06,12,15,12,11, 7, 6, 5,15,12,13,12,11,11, 6,12,

            13,12,11,12,11, 7, 6, 5, 0};//乐曲《东方红》的简谱表

code uchar time[]={ 8, 4, 4,16, 8, 4, 4,16, 8, 8, 4, 4, 4, 4, 8, 4,

             4,16, 8, 8, 8, 4, 4, 8, 8, 8, 4, 4, 8, 4, 4, 4,

             4, 4, 4, 4, 4, 4, 4,16, 0};//节拍表(8为1拍,约570mS)

uchar H0,L0,cnt;

void cntint0(void) interrupt 1 //定时器0中断用于产生音调

{  TH0=H0;

   TL0=L0;

   P15=~P15;         //P1.5是音乐信号输出脚

}

void cntint1(void) interrupt 3 //定时器1中断用于产生节拍

{  cnt++;            //定时器的计数初值为0,所以不用赋值

}

void main(void)

{  uchar i,a,t;

   uint b;

next:

   TMOD=0x11;

   EA=1;

   ET0=1;

   ET1=1;

   cnt=0;

   TR1=1;

   i=0;

   while(1)

   {   t=tone[i];        //读音调

       if(t==0) break;      //是0,则结束

       b=cyc[t%10-1];

       if(t<10) b=b*2;

       if(t>20) b=b/2;

          b=b/2;

       H0=(65536-b)/256;

       L0=(65536-b)%256;

       cnt=0;

       a=time[i];        //读节拍

       if(a!=255) TR0=1;    //255是休止符

       while(a>cnt);

       TR0=0;

       i++;

       for(b=0;b<1000;b++);

   }

   P15=1;               //关闭喇叭

   goto next;           //重放一遍

}

五、创新

自动演奏乐曲《八月桂花启遍地开》的汇编语言参考程序。

ORG 0000H

LJMP START

ORG 000BH

INC 20H  ;中断服务,中断计数器加1

MOV TH0,#0DCH

MOV TL0,#00H  ;11.0592MHz晶振,形成10毫秒中断

RETI

START:  MOV SP,#50H

MOV TH0,#0DCH

MOV TL0,#00H

MOV TMOD,#01H

MOV IE,#82H

MUSIC0: NOP

MOV DPTR,#DAT  ;表头地址送DPTR

MOV 20H,#00H  ;中断计数器清0

MUSIC1: NOP

CLR A  ;ACC清零

MOVC A,@A+DPTR  ;查表取代码

JZ END0 ;是00H,则结束

CJNE A,#0FFH,MUSIC5 ;如果是休止符,往下执行

LJMP MUSIC3

MUSIC5: NOP

MOV R6,A  ;R6=18H音符的频率

INC DPTR  ;DPTR加一

MOV A,#0

MOVC A,@A+DPTR  ;取节拍代码送R7

MOV R7,A  ;R7=30H音符发音的时间

SETB TR0  ;启动计数 

MUSIC2: NOP

CPL P1.5  ;P1.5是音乐输出引脚

MOV A,R6

MOV R3,A  ;R3=R6=18H

LCALL DEL

MOV A,R7

CJNE A,20H,MUSIC2  ;中断计数器(20H)=R7否? ;不等,则继续循环

MOV 20H,#00H  ;等于,则取下一代码

INC DPTR

LJMP MUSIC1

MUSIC3: NOP ;休止100毫秒

CLR TR0 

MOV R2,#0DH  ;R2=13

MUSIC4: NOP

MOV R3,#0FFH  ;R3=255

LCALL DEL

DJNZ R2,MUSIC4

INC DPTR

LJMP MUSIC1

END0: NOP

MOV R2,#0FFH  ;歌曲结束,延时1秒后继续

MUSIC6: MOV R3,#00H

LCALL DEL

DJNZ R2,MUSIC6

LJMP MUSIC0

DEL: NOP

DEL3:  MOV R4,#02H

DEL4:  NOP

DJNZ R4,DEL4

NOP

DJNZ R3,DEL3

RET

DAT:  DB 18H,30H,1CH,10H,20H,40H,1CH,10H,18H,10H,20H,10H,1CH,10H,18H,40H

DB 1CH,20H,20H,20H,1CH,20H,18H,20H,20H,80H,0FFH,20H,30H,1CH,10H,18H

DB 20H,15H,20H,1CH,20H,20H,20H,26H,40H,20H,20H,2BH,20H,26H,20H,20H

DB 20H,30H,80H,0FFH,20H,20H,1CH,10H,18H,10H,20H,20H,26H,20H,2BH,20H

DB 30H,20H,2BH,40H,20H,20H,1CH,10H,18H,10H,20H,20H,26H,20H,2BH,20H

DB 30H,20H,2BH,40H,20H,30H,1CH,10H,18H,20H,15H,20H,1CH,20H,20H,20H

DB 26H,40H,20H,20H,2BH,20H,26H,20H,20H,20H,30H,80H,20H,30H,1CH,10H

DB 20H,10H,1CH,10H,20H,20H,26H,20H,2BH,20H,30H,20H,2BH,40H,20H,15H

DB 1FH,05H,20H,10H,1CH,10H,20H,20H,26H,20H,2BH,20H,30H,20H,2BH,40H

DB 20H,30H,1CH,10H,18H,20H,15H,20H,1CH,20H,20H,20H,26H,40H,20H,20H

DB 2BH,20H,26H,20H,20H,20H,30H,30H,20H,30H,1CH,10H,18H,40H,1CH,20H

DB 20H,20H,26H,40H,13H,60H,18H,20H,15H,40H,13H,40H,18H,80H,00H

END

自动演奏《康定情歌》乐曲的C语言程序为:

#include <REG51.h>

#define uchar unsigned char

#define uint  unsigned int

sbit P15=P1^5;

code uint cyc[]={3600,3200,2880,2702,2400,2158,1920};//音阶1-7对应的计数周期数

code uchar tone[]={13,15,16,16,15,16,13,12,12, 13,15,16,16,15,16,  13, 13, 13,15,16,16,15,16,  13, 12, 12,  15,13,12,13,12,11, 12, 6,  6,    12,15,13,       12, 6,   16,15,13,12,13,12,11,12, 6,  5, 6 };//乐曲《东方红》的简谱表

code uchar time[]={ 8, 8, 8, 4, 4, 8, 8,12, 4,  8, 8, 8, 4, 4, 8,  16,  8,  8, 8, 8, 4, 4,  8,   8,  12, 4,   8, 8, 4, 4, 4, 4,   8,  24,          8,    24,8,24,        8,16,    8, 8, 8, 4, 4, 4, 4, 8,16,  8,    32};//节拍表(8为1拍,约570mS)

uchar H0,L0,cnt;

void cntint0(void) interrupt 1 //定时器0中断用于产生音调

{ TH0=H0;

TL0=L0;

P15=~P15;  //P1.5是音乐信号输出脚

}

void cntint1(void) interrupt 3 //定时器1中断用于产生节拍

{ cnt++; //定时器的计数初值为0,所以不用赋值

}

void main(void)

{ uchar i,a,t;

uint b;

next:

TMOD=0x11;

EA=1;

ET0=1;

ET1=1;

cnt=0;

TR1=1;

i=0;

while(1)

{ t=tone[i]; //读音调

if(t==0) break; //是0,则结束

b=cyc[t%10-1];

if(t<10) b=b*2;

if(t>20) b=b/2;

          b=b/2;

H0=(65536-b)/256;

L0=(65536-b)%256;

cnt=0;

a=time[i]; //读节拍

if(a!=255) TR0=1; //255是休止符

while(a>cnt);

TR0=0;

i++;

for(b=0;b<1000;b++);

}

P15=1; //关闭喇叭

goto next; //重放一遍

}

六、实验心得

1. 通过这次实验,我们学习并且设计一些歌曲,然后利用单片机进行实现播放。

2. 通过这次实验,我们学习了计时器的使用方法和原理。

3. 进一步熟悉89C51定时器/计数器的功能及应用。

4. 掌握其初始化与中断服务程序的编程方法。

5. 掌握用定时器/计数器发出不同音调的编程方法。

更多相关推荐:
实验二 进位控制实验-报告

沈阳工程学院学生实验报告实验室名称计算机组成原理实验室实验课程名称计算机组成原理实验项目名称进位控制实验实验日期20年月日班级姓名学号指导教师批阅教师成绩一实验目的1验证带进位控制的算术运算功能发生器74LS1...

进位控制实验 计算机组成原理实验报告

上海应用技术学院计算机组成与结构课程实验报告计算机科学与信息工程系20xx年编制上海应用技术学院计算机科学与信息工程系20xx年编制上海应用技术学院计算机科学与信息工程系20xx年编制上海应用技术学院计算机科学...

进位控制实验实验报告

广东技术师范学院实验报告学院姓名实验地点专业学号实验日期班级组别成绩组员指导教师签名实验222项目名称进位控制实验1实验目的1了解带进位控制的运算器的组成结构2验证带进位控制的运算器的功能2实验设备TDNCM或...

加法及进位控制实验

计算机组成原理实验报告计算机组成原理实验报告正文用纸实验目的1了解带进位控制的运算器中进位控制电路的组成结构2验证带进位控制的算术运算器功能发生器的功能实验设备1TDNCM教学实验系统一套排线8条8芯2条6芯1...

带进位控制8位算数逻辑运算实验

计算机组成原理实验报告1234

实验四进位控制与移位运算实验

计算机体系结构实验报告实验序号04实验项目名称进位控制与移位运算实验

计算机组成原理实验报告 进位位控制、通用寄存器判零实验

西华大学数学与计算机学院实验报告课程名称计算机组成原理指导教师祝昌宇实验名称进位位控制通用寄存器判零实验年级20xx级姓名蒋俊学号3120xx080611118实验成绩实验日期20xx1215一目的1熟悉带进位...

计算机组成原理微程序控制器实验报告

计算机组成原理实验报告三微程序控制器实验20xx0506010009分类实验报告标签实验微程序字段微指令信号字号大中小订阅实验三微程序控制器实验一实验目的与要求实验目的1掌握时序产生器的原理和具体操作2掌握微程...

步进电机实训报告

ARM实训报告淮安信息职业技术学院计算机与通信工程学院步进电机实训报告一实训目的1了解步进电机的结果以及工作原理2掌握步进电机控制系统的设计方法及其调试方法二实训设备1硬件教学实验箱pc机2软件pc机操作系统W...

实验三、电机控制实验报告

学生实验报告

基于51单片机的步进电机控制系统-单片机课程设计报告

微机原理与接口技术课程设计报告基于51单片机的步进电机控制系统学号姓名班级20xx级电子2班华侨大学电子工程系摘要步进电机是将电脉冲信号变换成角位移或直线位移的执行部件步进电机可以直接用数字信号驱动使用非常方便...

PLC控制步进电机实验报告

广东技术师范学院实验报告学院姓名实验地点实验3项目名称PLC控制四相步进电机1实验项目名称PLC控制四相步进电机2实验目的和要求1掌握功能指令的用法2掌握步进电机步进控制程序的设计3主要仪器设备1DICEPLC...

进位控制实验报告(9篇)