可存储式电子琴设计报告

时间:2024.4.13

                   目录

前言     ……………………………………………………………… 4

第1章   任务要求…………………………………………………… 4

1.1   任务要求……………………………………………………  4

第2章    控制电路 …………………………………………………5

2.1  说明………………………………………………………………5

2.2   LCD驱动电路………………………………………………… 7

2.2.1   LCD的功能与引脚介绍 ………………………………7

2. 2 .2  LCD特性及操作命令……………………………9        2.3   键盘扫描………………………………………………………15

   2.3.1    键盘分配 ……………………………………………15

   2.3.2    键盘扫描方法 ………………………………………15

     2.3.2 .1   矩阵式键盘的结构与工作原理………………15

     2.3.2 .2   矩阵式键盘的按键识别方法…………………16

2.4   音频处理电路…………………………………………………19

    2.4.1  说明及特点……………………………………………19

2.4.2  原理及能实现功能……………………………………20

第3章  定时器产生各种频率的声音的方法………………………23

3. 1    原理及说明…………………………………………………23

3.2    定时器的工作………………………………………………26

3.2.1  启动定时器及计时工作脉冲 …………………………26

3.2.2  计时时间长短设置及计时溢位处理……………………28

第4章   程序说明…………………………………………………29

参考文献 ………………………………………………………………30

附录1(程序清单)………………………………………………… 31

附录2(电路图)…………………………………………………   43

附录3(程序流程图)…………………………………………………44

总结  …………………………………………………………   45

前言                                                                 

                                                                                                                                                                 此次课程设计是结合LCD设计一台数字式可存储式电子琴,利用单片机8051的控制程序,可以自己弹奏音乐,并自动存储所输入的单音,稍后会一起自动演奏出来。由控制程序的变化,可以做不同类型的电子琴的设计。本设计可以学习按键试电子琴的控制方式,按下键并发出相对音阶,并将输入的单音数据存入8051内部可用的内存RAM区,稍后一起自动演奏出来。

    电子琴核心部分是单片机及其程序。单片机体积小,价格便宜,开发容易,可根据需要制作成为各种智能控制器以代替人工操作,实现自动化。单片机系统主要由中央处理器(CPU)、存储器和I/O接口电路三大部分组成,各部分通过三态门与地址总线、数据总线和控制总线连接起来并相互传递信息(即传送数据)。其结构如图1所示。

          图1.单片机系统结构图

        第一章    任务要求及方法说明

    1.1   任务要求

    可存储式电子琴的任务要求如下:

    使用LCD显示器来显示音阶输入的相关信息。

    当按下键盘组相对按键,压电喇叭会发出相对音阶单音, 共有两个8度音节。

    所输入的单音会存入8051内而保存起来。

    至多可以输入64个单音,可以一起演奏出来。

    有清除存储功能,再重新输入。

    演奏时可以按键来中断。

    可以实时显示目前演奏的单音码及所存储的单音计数。

   

  

第2章    控制电路

可存储式电子琴的控制电路分为以下几部分:

·  单片机8051

·  工作指示LED

·  LCD显示器

·  按键输入

·  喇叭接口

    2.1 说明

    电子琴的核心部件是单片机,下图是MCS-51系列单片机的内部RAM地址分配示意图。

          图2.1  MCS-51系列单片机的内部RAM地址

    完整的控制电路见附录2。

    其中J1为+5V电源输入,当电源加入时电源指示灯LED将亮起,用以指示电源供给

                                                                     过连接线连在I051控制板上的J3接头。可存储式电子琴所输入的音阶值必须存入变量数组中,在演奏时才逐一取出来播放单音。8051程序中的变量是使用内部存储器一般用途RAM区,范围为空间30H~7FH,因此内存规划如下:

    ·  RAM地址30H~70H存放音阶值,最大内存空问为64字节。

    ·  RAM地址71H~7FH存放程序其他变量。

若要扩充音阶的存储容量,必须使用外部内存扩充,最简单的方式是使用串行EEPROM 93C46等系列芯片,除了增加存储容量外.还可以有断电数据保存的功能,关机后音乐数据仍保存着。

2.2   LCD驱动电路

   2. 21   LCD的功能与引脚介绍

程序执行后工作指示LED闪动,表示程序开始执行,LCD显示器显示如下:

    当按下键盘组相对按键,压电喇叭会发出相对单阶单音,共有两个8度音节,DO~SI,HI DO~HI SI,14个音阶,所输入的单音会存入8051内而保存起来,至多可以输入64个单音,可以一起演奏出来,有清除存储功能,再重新输入。

    4X4按键音阶对应如下所示:

22 音阶对应表

    LCD可以实时显示所存储的单音计数,按键9是清除键,将存储的单音计数请为0,按键8是放音键,将内存内的单音逐一演奏出来,演奏中可以按键K4来中断。

    在本设计使用一般的LCD显示器来显示音乐演奏的消息及单音码,按下键盘组按键,喇叭发出相对音阶,并存储起来自动演奏电子琴,可以扩充其功能如下:

   ●  扩充更多组的按键可以输入另外一组高音阶。

   ●  增加多组LED成为音乐走马灯。

   ●  增加串行EEPROM 93C46等系列芯片,将内存内的单音逐一写入93C46内,音乐

   数据可以长久保存,若关机后音乐数据仍保存着。

   ●  增加串行EEPROM等系列芯片,可以实时输入并存储多首歌曲,稍后再播放出来。

    LCD 在电子产品中使用频率相当高,普通的七段显示器只能用来显示数字,要显示英文文字时,要选择使用 LCD(液晶显示器),常见的使用场合有测量仪器及高级电子产品,毕竟LCD 价格不是很便宜。我们在电子材料行买到的 LCD,其背面有控制电路,其上面有专门的IC来完成LCD的控制动作,在设计的接口中,只要送入适当的命令码和欲显示的数据,LCD便会将其字符显示出来,在控程上非常方便。

一般市售的LCD均有统一引脚,本设计采用的LCD为SDEC厂牌(2A16DRG)引脚

                                        

2.3 LCDSDEC厂牌(2A16DRG)引脚

功能说明如下:

   1. D0~D7双向的数据总线,LCD数据读写方式可以分为8位及4位两种,以8位数据进行读写则D0~D7有效,若以4位方式读写,则只用D7~D4。

   2. RS 寄存器选择控制线,当RS=0时,并且做写入的动作时,可以写入指令寄存器,若RS=0,且做读取的动作时,可以读取忙碌标志及地址计数器的内容。如果RS=1则用于读写数据寄存器。

   3. R/W  LCD读写控制线,R/W=0时,LCD执行写入的动作,R/W=1时则做读取的动作。EN启用控制线,高电平动作。

   4. VCC 电源正端。

   5. VO 亮度调整电压输入控制引脚,当输入0V时字符显示最亮。

   6. GND 电源地端。

222  LCD特性及操作命令

    LCD具有入下特性:

    1.  +5V供电,亮度可调整。

    2.  内藏振荡电路,系统内含重置电路。

    3.  提供各种命令,如清除显示器、字符闪烁、显示移位等多种功能。

    4.  显示用数据RAM共80个字节。

    5.  字符产生器ROM有160个5×7点阵字型。

    6.  字符产生器RAM可由用户自定义8个5×7点阵字型。

    

    LCD内部存储器共分为3种:

    固定字型ROM,称为CG(Character Generator)ROM。

    数据显示RAM,称为DD(Data Display)RAM。

    用户自定义字型RAM,称为CGRAM。

    (1)CG ROM

    CG ROM内存储着192个5×7点阵的字型,这些字型均已固定,例如我们将“A”写入LCD中,就是将“A”的ASCII码41H写至DDRAM中,同时至CG ROM中将“A”的字型点阵数据找出来而显示在LCD上。

    (2)DD RAM

    DD RAM内用来存储写至LCD内部的字符,DD RAM的地址分布从00H到67H,分别代表LCD的各列位置,例如我们要将“A”写入第2行的第1个位置,就先设置DD RAM地址为40H,而后写入41H至LCD即可。

    (3)CG RAM

    此区域只有64个字节,可将用户将自行设计的字型写入LCD中,一个字的大小为5x7点阵,工可以存储8个字型,其显示码为00H到07H。

   SDEC的操作命令均为12位,其中高4位为标识码,低8位为参数,各操作命令如下:

    ●空操作:0000xxxxxxxxB(x可为任意值,下同)

    空操作命令对SDEC 2A16不产生任何影响。该命令可以在多个SDEC 2A16级联的应用中透过前级SDEC 2A16向后级SDEC 2A16发送操作命令而不影响前级SDEC 2A16的状态。例如,要将操作命令001000000001B发送给两级级联电路中的后级SDEC 2A16(后级SDEC2A16的DIN引脚连接到前级SDEC 2A16的DOUT引脚),只要在该操作命令后添加空操作命令000000000000B再发送,那么,该操作命令将经过前级SDEC 2A16到达后级SDEC 2A16,

而空操作命令留给了前级SDEC 2A16。另外,为了在不影响SDEC 2A16的前提下变化DCLK以清除看门狗计时器,也可以发送空操作命令。在非级联的应用中,空操作命令可只发送高4位。

    ●芯片内部复位:001000000001B

    内部复位命令可将SDEC 2A16的各个寄存器和各种参数复位到默认的状态。芯片上电时,SDEC 2A16均被复位,此时各个寄存器均复位为0,各种参数均恢复为默认值。

    ●字数据移位:0011000000[D1][D0]B

    字数据移位命令共有4个:开环左移、右移,闭环左移、右移。D0为0时为开环,为1时为闭环,D1为0时左移,为1时为右移。开环左移时 DIG0引脚对应的单元补00H,此时不译码方式显示为空格,BCD译码方式时显示为0;开环右移时,DIG7引脚对应的单元补00H;而在闭环时DIG0与DIG7头尾相接,闭环移位。

    ●设定系统参数:01000000[WDOG][KEYB][DISP]B

    该命令用于设定SDEC 2A16的系统级参数 如看门狗使能WDOG、键盘扫描使能KEYB、显示驱动使能 DISP 等。各个参数均可通过1位数据来进行控制,将相应的数据位置为 1可启用该功能,否则关闭该功能(默认值)。

    ●设定显示参数:0101[MODE][LIMIT][INTENSITY]B

    此命令用于设定SDEC 2A16的显示参数,如译码方式MODE(1位)、扫描极限LIMIT(3位)、显示亮度INTENSITY(4位)等。译码方式MODE为1时选择BCD译码方式,为0时选择不译码方式。SDEC 2A16默认工作于不译码方式,此时8个数据寄存器中字节数据的位7~位0分别对应8个数码管的小数点和段G~段A,当数据位为1时,对应的数据段(或发光管)点亮;数据位为0时熄灭。SDEC 2A16工作于BCD译码方式主要应用于数码管驱动,单片机只要给出二进制数的BCD码,便可由SDEC 2A16将其译码并直接驱动数码管以显示对应的字符。BCD译码方式是对数据寄存器中字节数据的位4~位0进行兼容BCD的译码,可用于控制段驱动引脚SEG6~SEG0的输出,它们对应于数码管的段G~段A,同时可用字节数据的位7控制段来驱动引脚SEG7的输出以对应数码管的小数点,字节数据的位6和位5不影响BCD译码的输出,它们可以是任意值。将位4~位0进行BCD译码可显示以下28个字符,其中00000B~01111B分别对应于“0~F”、10000B~11010B分别对应于“ ”空格、“+”+或加号、“-”负号或减号、“=” 等于号  、“[”左方括号  、“]” 右方括号、“_”下划线、“H” 、“L” 、“P” 、“.” 小数点、其余值为空格。

    扫描极限LIMIT控制位001B~111B和000B(默认值)可分别设定扫描极限1~7和8。显示亮度INTENSITY控制位的0001B~1111B和0000B(默认值)则用于分别设定显示驱动占空比1/16~15/16 和16/16,以实现16级显示亮度控制。

    ●设定闪烁0110[D7S][D6S][D5S][D4S][D3S][D2S][D1S][D0S]B

    设定闪烁控制命令用于设定 SDEC 2A161的闪烁显示属性,其中 D7S~D0S 分别对应于8个字驱动DIG7~DIG0。闪烁属性D7S~D0S分别通过1位数据控制,将相应的数据位置为1可使能闪烁显示,否则为正常显示,不闪烁(默认值)。

    ●加载字数据:1[DIG_ADDR][DIG_DATA]B

    加载字数据命令用于将字节数据DIG_DATA(8位)写入DIG_ADDR(3位)指定的数据寄存器中。DIG_ADDR的000B~111B分别用于指定数据寄存器的地址0~7,并分别对应于DIG0~DIG7引脚驱动的8个数码管。DIG_DATA为待写入的字节数据。

    ●读取按键代码:0111xxxxxxxxB

    读取按键代码命令用于获得 SDEC 最近检测到的有效按键的按键代码。该命令是唯一的具有数据返回的命令,SDEC通常从DOUT引脚输出按键代码,按键代码总是7位数据,最高位是状态码,位5~位0是扫描码。读取按键代码命令的位数据B7~B0可以是任意值,所以控制器可以将该操作命令缩短为4位数据B11~B8。例如,SDEC 2A16检测到有效按键并中断时,如按键代码是5EH,则先向SDEC发出读取按键代码命令0111B,然后再从DOUT获得按键代码5EH。

    SDEC所提供的按键代码为7位,位2~位0是列扫描码,位5~位3是行扫描码,位6是状态码(键按下为1,键释放为0)。例如,连接DIG3与SEG4的键被按下时,按键代码为 63H,键被释放后,按键代码是 23H。单片机可以在任何时候读取按键代码,但一般在SDEC 2A16检测到有效按键而产生键盘中断时读取按键代码,此时按键代码的位6总是1。另外,如果需要了解按键何时释放,单片机可以通过查询方式定期读取按键代码,直到按键代码的位6为0。连接在DIG7~DIG0与SEG7~SEG0之间的键被按下时,SDEC 2A16所提供的按键代码。这些按键代码具有一定的规律,如果需要键被释放时的按键代码,按键代码的位6 置0,也可将表中的按键代码减去40H。应注意的是:SDEC 2A16不支持组合键,也就是说,同一时刻,不能有两个或者更多的键被按下。

    2.3  键盘扫描

    2.3.1   键盘分配

    整个4x4键盘按键分配如下所示:

图2.4   键盘分配

    当实际制作是所使用的键盘按键位置分配时,自行修改按键转换即可。

    2.3.2   键盘扫描方法

    2.3.2 .1 矩阵式键盘的结构与工作原理

图2.5矩阵式键盘结构

    矩阵式结构的键盘虽然比直接法要复杂一些,识别也要复杂一些,但能符合要求。列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。

    2.3.2 .2 矩阵式键盘的按键识别方法

确定矩阵式键盘上何键被按下介绍一种“行扫描法”。

行扫描法:行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。

    (1) 判断键盘中有无键按下 将全部行线 Y0-Y3 置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。

    (2) 判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。

    8051单片机的P2口用作键盘I/O口,键盘的列线接到P2口的低4位,键盘的行线接到 P2 口的高 4 位。列线 P2.7-P2.4 分别接有 4 个上拉电阻到正电源+5V,并把列线P2.7-P2.4设置为输入线,行线P2.0-P2.3设置为输出线。4根行线和4根列线形成16个相交点。

    (1) 检测当前是否有键被按下。检测的方法是 P2.0-P2.3 输出全“0”,读取P2.7-P2.4的状态,若P2.7-P2.4为全“1”,则无键闭合,否则有键闭合。

    (2) 去除键抖动。当检测到有键按下后,延时一段时间再做下一步的检测判断。

    (3) 若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P2.0-P2.3按下述4种组合依次输出:

    P2.0    1    1    1    0

    P2.1    1    1    0    1

    P2.2    1    0    1    1

    P2.3    0    1    1    1

    在每组行输出时读取 P2.7-P2.4,若全为“1”,则表示为“0”这一行没有键闭合,否则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的行值和列值转换成所定义的键值

    (4)为了保证键每闭合一次CPU仅作一次处理,必须却除键释放时的抖动。

    从以上分析得到键盘扫描程序的流程图如图2.5(见下页)所示。

单片机在开发过程中,常常会因为资源不足而不得不大量扩展接口芯片以满足应用系统的需要,其中原因之一是人机界面中的键盘显示占用了系统太多资源,从而造成系统庞大,同时降低了系统的可靠性。在单片机应用系统中,键盘显示通常可采用以下几种方式:

图2.6键盘扫描程序的流程图

   采用串行接口的键盘显示专用芯片,如 BC7280/81、HD7279、CH451 等。这类芯片占用CPU的资源少,传输速度较快,外围器件要求也较少,在中小系统中都可得到广泛的应用。

     

    2.4  音频处理电路

    2.4.1  说明及特点

音频处理器集数字均衡器与数字功率放大为一体,是一种硬件与软件的多功能数字音频处理器。可在数字状态下对音频进行降噪、均衡、时间压扩、限幅,混响、增益控制、声像移动等特技处理。在不变调的同时对声音进行压、扩,从而最大限度地减少了干扰和失真,确保了音频信号的质量。具有高效率、高保真、输出功率大、频响范围宽和没有零瓢的特点,可根椐现场环境对每一通道独立调节高低音,均衡等并保存预设值,方便随时调用。配备 RS-232 控制接口,方便与外部计算机控制软件相连,通过虚拟数字调音台,我们可以实现操作面板的所有控制。方便随时调用。多路音频采集通道与4路线性输入可进行任意切换进行现场监听。 可根椐不同的使环境对背景噪声,回声,及各种杂音进行消除,使监听到的声音层次分明,圆润,饱满,清晰。能用于补偿房间的声学缺陷或系统本身的缺陷。

该数字音频处理器具有以下特点:

2由CPU进行所有操作的控制;

3使用液晶显示屏对各项操作进行显示;

4有短路保护、热保护、DC保护、VHF保护、削波限幅器、长期输出功率限制、AC保护等各项保护功能;

5采用大功率电源变压器,数字功率放大,保证功放有足够的功率;

6完善的系统降噪处理,减低噪声,使音质更加清晰;

7配备RS-232 控制接口,方便与外部单片机控制软件相连,通过虚拟数字调音台,实现面板操作的所有控制;

2.4.2  原理及能实现功能

其起主要作用的是带运算放大器的数字电位器,数字电位器部分的原理框图如图 2.6所示。

图2.7原理框图

由图2.6可知,DS1667包含两个电位器,每个电位器有各自的游标,它由一个包含在8位寄存器中的数值来设定。每一个电位器由256个阻值相等的电阻器组成,相互间以及和最末端电阻器之间是以抽头连接的。

    另外,电位器可以用串联的形式堆积起来,也就是说,电位器0的高端连接到电位器1 的低端,作为堆栈电位器,堆栈选择位用来选择哪个电位器的游标将出现在多路输出端SOUT。如果0写进堆栈多路输出分配器,将连接游标0到SOUT引脚。这个游标将决定从堆栈电位器底部的256个抽头中选择哪一位。如果1被写进堆栈多路输出分配器,将选择游标1,堆栈电位器上部的256个抽头中的其中之一连接到SOUT引脚。

    通过17位I/O移位寄存器,数据可以从游标0和游标1寄存器以及堆栈选择位中读出或写入。I/O移位寄存器是3线串行口负载,而3线串行口由RST、DQ和CLK组成。它通过传送17位数而修改数据。只有当RST输入高电平时,才允许通过DQ引脚串行写入数据。在RST端变为低电平以前,电位器总保持以前的数值不变。当RST变为低电平后,电位器的数值才会改变,当RST输入为低电平时,DQ和CLK输入不起作用。

    当RST是高电平时,CLK输入端由低到高转变,有效数据被写进I/O移位寄存器。无论时钟输入是高电平还是低电平,DQ引脚的输入数据都可以改变,而只有满足设置要求时DQ引脚的数值才被送入移位寄存器。数据写入总是以堆栈选择位的数值开始的。送入的下一个8位是规定电位器1的游标设定数值,这8位数据的最高有效位首先送出,接下来的8位是规定电位器0的游标的设定数值,首先送出的也是最高有效位。送入的第17位数据,是游标0设定的最低有效位。如果写进的数据少于17位数,电位器设置的数值将是被写进的数据加上以前未转换的保留位。如果写进的数据大于17位,最后的17位数据留在移位寄存器中。因此,如果送进的数据不是17位,将导致电位器设置不准确。

    当多位数据被写进移位寄存器时,以前的数据通过级联串行口引脚 COUT 逐位移出,通过连接一个DS1667的COUT到另一个DS1667的DQ引脚,多个电位器能象链子一样串接在一起,如图2.7所示。

图2.8写数据

图2.9读数据

读数据时,DQ引脚处于悬浮状态。当RST保持低电平时,位17总是出现在COUT引脚,它通过电阻器反馈回DQ引脚,该数据通过读设备读出。RST引脚变成高电平则启动数据的传送。CLK输入端从低到高转变时,位17被送进I/O移位寄存器的第一位,位16出现在COUT引脚和DQ引脚。当17位全部传送完后,数据已完全移至初始位置。当RST变回低电平以结束数据传送时,数据(类似于读发生以前的数值)被送进游标0、游标1的寄存器和堆栈选择位。

实现的主要功能:

1使用先进的32位数字音频处理器,进行全程数字化处理,使整机性能更卓越。

2抑制启动阀值可调,通过调节反馈抑制器的阀值(-3dB至-9dB)使其能在不同激励电平的情况下,可靠启动反馈抑制器的滤波器, 具有反馈抑制器所具有功能。

3数字音频控制能对每一路进行音量/平衡/衰减控制、高/低音控制、均衡调节和动态范围压缩等功能的独立调节。

4液晶处理:对液晶显示的背光、字符,数字、汉字、由CPU进行处理。

5背光LCD显示屏,所有功能和设置LCD液晶显示并可以通过RS232接口连接单片机进行设置。

6稳压电源:为系统提供稳定的直流电源。

第3章 定时器产生各种频率的声音的方法

  3. 1 原理及说明

    以定时器产生特定频率的方波信号,以定时器产生各种频率的声音,可以由喇叭发出“DO”、“RE”、“ME”……的音阶,以定时器0工作于模式0,计时时间长短按所发音的频率而定,下表列出各个音符对应的频率值:

31 频率对应表

    定时器计数初值可以由频率值推得。由以下关系式可得:

    t=1/f(us);

    co=(int)t/2;

    lo=(8192--co)%32;

    hi=(8192--co)/32;

    其中符号的含义说明如下:

    ·  f:频率值

    ·  t:方波宽度,以us表示

    ·  co:定时器所计数的次数

    ·  lo:计数初值低字节

    ·  hi:计数初值高字节

    定时器每一个计数时间脉冲宽度为1.0us(石英振荡晶体为12 MHz),为了方便汇编程序设计,我们可以将各个音阶频率值对应的计数初值先求出,在汇编语言中以查表的方式

来加载计数初值。

    执行结果如下:

    ===8051 timer mode 0 sound value calculator===

    XTAL=12 MHz

    f=523      co=956   TH0  value=226   TL0  value= 4

    f=587      co=851   TH0  value=229   TL0  value=13

    f=659      co=758   TH0  value=232   TL0  value=10

    f=698      co=716   TH0  value=233   TL0  value=20

    f=784      co=637   TH0  value=236   TL0  value= 3

    f=880      co=568   TH0  value=238   TL0  value= 8

    f=987      co=506   TH0  value=240   TL0  value= 6

    f=1046     co=478   TH0  value=241   TL0  value= 2

    f=1174     co=425   TH0  value=242   TL0  value=23

    f=1318     co=379   TH0  value=244   TL0  value= 5

    f=1396     co=358   TH0  value=244   TL0  value=26

    f=1567     co=319   TH0  value=246   TL0  value= 1

    f=1760     co=284   TH0  value=247   TL0  value= 4

    f=1975     co=253   TH0  value=248   TL0  value= 3

    any keyte continue...

    8051控制程序执行后,将示波器接往8051 P3_4引脚,可以测量所输出的方波信号,其宽度依不同音阶而变,此时喇叭发出“DO”、“RE”、“ME”……的音阶,一共14个单音,包含两个八度音,若拔下KI键则喇叭再次发出声音测试。

   3.2.    定时器的工作

表3.1定时器工作方式寄存器TMOD格式

表3.2 M1 M0—工作方式选择位

C/T————记数/定时方式选择位         

GATE————门控位—

。    定时器模式0的工作:

    在模式0时定时器0可以进行13位的计时,其值保存在两个8位的定时寄存器中,分别为TL0及TH0(定时器0)。

3.2.1      启动定时器及计时工作脉冲

开关控制位GATE=0时,只要TR0=l,定时器0便会工作。

    ·  开关控制位GATE=1时,除了TR0=1,外部INT0引脚,还必须是高电平才行。

    利用条件2,定时器必须等待外部引脚INT0的输入信号变为高电平才开始计时,因此可以用来测量输入INT0引脚的高电平信号时间的长短,这在工厂产品自动化生产测试系统中是一项经常使用的测量技巧。平时在单片机程序控制中,若使用定时器内部时钟工作,C/T=0,GATE=0,在模式0下,只要下达指令:

    MOV   TMOD,#00H

便可以设置定时器0于模式0开始计时工作。只要将TR0(TCON位4)设为l,定时器便会开始工作了。

    定时器的工作时钟可以由内部或是外部来提供,由 C/T 位(在TMOD 中)来决定,当C/T=1时,由外部引脚T0来提供,作为计数器时使用。当C/T=0时,则由内部时钟来提供,作为一般的定时器使用。而定时器的时钟为系统工作时钟除 12。石英振荡晶体使用11.0592 Maz,所以定时器每一个计数时间脉冲宽度为:

    12/11.0592 MHz=1.085us

    若石英振荡晶体改为12 MHz,定时器每一个计数时间脉冲宽度为:

    12/12MHz=1.0us 

计时模式0可以进行13位的计数,其值是以下列方式存储在寄存器TL0及TH0中:

                   表3.3

    因此最长的计时时间为1.085 us×8192=8.888 ms。

 

   3.2.2  计时时间长短设置及计时溢位处理

    8051 定时器是以上述的方式来计数,在模式 0 下共可计数 13 位,计数器值最多为8192(2 的13次方),由0数到8192便产生溢位而引发中断信号,产生定时器0的中断(TF0=I)。问题是我们可能只要计数 100个脉冲便产生中断,只要将初值 8092(8192--100)加载计数器便可,一旦启动定时器后,计数变为8093、8094、……一直到8192则产生中断,就计数100次了,而时间长度为:

    1.085 us×100=108.5us

    也就是经过108.5/us后便产生中断了。

    至于载入定时器的初值,计算如下:

    TL0=(8192-C).MOD.32

    TH0=(8192-C)/32

    其中,C为所要计数的值,MOD为取余数的运算,除以32后取余数部分。其中“/”为除法运算,在做完除法后取整数部分。

    若计数次数为100,C=100,可得:

    TLO=28

    TH0=252:

    ·  检查其中断控制寄存器TCON中的TF0及TFl位,若为1则代表产生计时溢位了。

    ·  执行相对应的中断服务程序。

    一般程序设计中以方式 2 较常用,一旦计数终止产生溢位后便引发计时中断,若先前已设置好计时中断服务程序,则会自动跳去执行计时中断服务程序,在程序中再加载计数初值后重新计数,当计数终上时,又产生计时中断,如此一直循环下去,便可以每隔一段时间自动去执行中断服务程序,这样的设计架构是单片机程序设计中常用的技巧,也是一种简单的多任务程序设计方法。 

 

第3章   程序说明及流程图

    本次工程实训中,可以学习利用单片机定时器来产生固定频率的方波信号推动压电喇叭,发出旋律。可存储式电子琴所输入的音阶值,是存入内存一般用途RAM区,范围为空间为30H~7FH,共64字节,因此最大存储音阶容量为64个音阶,由于可使用的内存有限,目前只设计单音拍子演奏长度固定为一拍,实际演奏一拍的长度可以依需要由延迟参数来决定。

    目前控制程序只在按键按下放开后才演奏单音,并没有像标准琴键那样可以有按键发音并持续发音功能,直到按键放开来,或是按下一段时间后单音才停止发音。由于单音的演奏是由定时器中断程序来控制,可以在演奏单音的同时并侦测按键是按下,或是放开,适当的修改程序,可以达到上述功能。

    (见附录)为主程序控制的工作流程。

    在主控程序循环中主要工作为等待是否确按链,若有按键则做相应的按键功能处理,是K8键则开始演奏存在内存内的音阶,若是K9键则清除计数。若是其他按键则显示按键值,演奏单音,将按键值存入内存,计数增加,最后判断计数值是否超过最大存储音阶容量64个音阶。

    可存储式电子琴的控制程序文件名为POR.ASM,,在程序的最后有以下的指令:

    SINCLUDE(PORl.ASM)

表示在主程序POR.ASM 的最后还会自动加载另一程序PORl.ASM程序一起进来汇编及编译,这是为了方便程序编辑用,一些测试正确的程序代码可以分别存档好方便管理,此外整个程序源代码长度也不至于太长而不方便编辑。PORl.ASM 主要的程序代码功能为LCD控制程序码,在很多专题设计中都有用到。                        

参考文献

1.徐爱军.《8051单片机实践教程》.北京.电子工业出版社.2005

2.王建校等.《51系列单片机及C51程序设计》.北京.科学出版社.2002

3.李叶紫等.《MCS-51单片机应用教程》.北京.清华大学出版社.2004

4.徐仁贵、廖哲智.《单片微型计算机应用技术》.北京.机械工业出版社.2001

5.李玉峰等编著.《MCS-51系列单片机原理与接口技术》.北京.人民邮电出版社.2004

6单片机和液晶显示器接口及驱动技术

                      -------选自《中国测试技术》2004 年3 月30 卷2 期

7.PIC单片机的应用设计技巧     黄世泽,曾萍,郭其一

                      -------选自《单片机与嵌入式系统应用》20##年8期

8.利用单片机I/O口直接驱动LCD    刘颋鹏

                      -------选自《单片机与嵌入式系统应用》20##年5期

9.现场总线工业控制网络技术   夏继强 ,刑春香

                      -------选自《单片机与嵌入式系统应用》20##年6期

10.单片机应用系统抗干扰技术的研究 张军;胡孝昌; 135-137

                          -------选自《计算机测量与控制》20##年第3期

11   http://www.laogu.com/wz_1881.htm

12   http://www.51c51.com/51test/cc422.htm

13   http://www.8951.com/51test/cc413.htm

14   http://www.8951.com/jxue/dpjjx28.htm

附录1(程序清单)

RS      EQU  P0.0        ; RS引脚由P0.0控制

EN      EQU  P0.1        ; EN引脚由P0.1控制

K_INT   EQU  P2.7        ; 中断键接P2.7引脚

WLED    EQU  P3.7        ; P3.7控制工作指示灯D2

SPK     EQU  P3.4        ; P3.4控制压电喇叭

FKEY    EQU  20H.0       ; 按键标志,有按键时FKEY=1

MNO     EQU  64          ;最大内存空间为64字节,30H~6FH

MEM      EQU  30H        ;MEN设定为内存起始地址

L0       EQU  71H        ; 定义变量用来记录计数初值低字节

H1       EQU  72H        ; 定义变量用来记录计数初值高字节

BUF_KEY  EQU  73H        ; 按键数据缓冲区

KEY_NO   EQU  74H        ; 用来存储按键编号

NO       EQU  75H         ; 存储按键的个数

CO       EQU  76H         ; 计数变量

X        EQU  77H         ; LCD显示的相对地址

;.......................................

ORG    00H                

LJMP   BEGIN

ORG   0BH                  ;0BH为定时器0中断地址

LJMP    T0_INT

;-------------------------------------------

ORG   0026H

BEGIN:

   LCALL LED_BL             ;调用LED_B 子函数 ,D2闪动,表示程序开始执行

   MOV  TMOD,#00000000B   ;设置TMOD,使定时器0工作模式为模式0

   MOV  IE,#10000010B      ;启用定时器0中断产生

   CLR  EN                 ;LCD OFF

   LCALL SET_LCD            ;LCD 初始化

   LCALL  SOUND_ON        ;喇叭打开

   MOV   R4,#1             ;R4表示的是音阶

   MOV   R3,#1             ;R3表示的是拍数

   LCALL  PLAY             ; 确定发音的音阶,控制喇叭的开关

   MOV   R4,#2             

   MOV   R3,#1

   LCALL  PLAY

   MOV   R4,#3            

   MOV   R3,#1

   LCALL  PLAY

   LJMP   RUN               ;开始执行主程序

   JMP   $

 PLAY:                        ; 确定发音的音阶,控制喇叭的开关

    LCALL   LOAD_VALUE     ;载入定时器0计数初值

    LCALL   SOUND_ON        ;喇叭打开,

;*****************************

;DECIDE  PLAY  LENGH...

PL1:MOV  R5,#30            ;延时150ms

    LCALL DELAY              ;调用延时子函数

    DJNZ R3,PL1              ;喇叭打开,启动定时器0开始计时

  ; PAUSE

    LCALL SOUND_OFF        ;喇叭关闭没有声音,停止定时器0计时动作

    MOV  R5,#3              ;延时15ms

    LCALL DELAY

    RET

;-----------------------------

SOUND_ON:                   ;喇叭打开

    SETB TR0                 ;启动定时器0开始计时

    RET

;--------------------------

SOUND_OFF:                   ;喇叭关闭

    CLR TR0                   ;停止定时器0计时动作

    RET

;---------------------------------------

LOAD_VALUE:

    MOV DPTR,#HI_LIST        ;指向数据列表地址

    MOV A,R4

    MOVC A,@A+DPTR

    MOV H1,A                  ;将计数初值高字节送给H1

    MOV DPTR,#LO_LIST        ;指向数据列表地址

    MOV A,R4

    MOVC A,@A+DPTR

    MOV L0,A                   ;将计数初值低字节送给L0

    RET

;----------------------------

T0_INT:                         ;定时器0中断服务程序,在T0有中断的时候,跳转执行此程序

    MOV TL0,L0                 ;将低字节送给TL0

    MOV TH0,H1                 ;将高字节送给TH1

    CPL SPK                     ;P3.4位输出反向,形成周期方波,驱动喇叭发出声音

    RETI                        ;中断程序执行结束,返回

;---------------------------

HI_LIST:           ;音阶对应定时器0计数初值高字节数据列表

    DB 0,226,229,232,233,236,238,240

    DB 241,242,244,244,246,247,248

LO_LIST:           ;音阶对应定时器0计数器低字节数据列表

    DB 0,4,13,10,20,3,8,6

    DB 2,23,5,26,1,4,3

;--------------------------------

    DELAY:                      ;延迟子程序

    MOV R6,#50

D1: MOV R7,#50

D2:DJNZ R7,D2

    DJNZ R6,D1

    DJNZ R5,DELAY

    RET

;---------------------------

LED_BL:              ;工作指示灯D2闪烁3次

    MOV R4,#4

LE1: CPL WLED      ;位反向,使灯的状态取反,实现闪烁

  MOV R5,#10      

  LCALL DELAY

  DJNZ R4,LE1

  RET

;----------------------------------------------------------------

TABLE_DIG:                     ;键盘按键编码表,通过查表,可以将按键转换为按键码

  DB 00H,01H,02H,03H

  DB 04H,05H,06H,07H

  DB 08H,09H,0AH,0BH

  DB 0CH,0DH,0EH,0FH

;------------------------------------------------------------------

; R1:COUNT 1         ;控制循环计数的次数

; R2:COUNT 2         ;控制循环计数的次数

; R3:SCAN SIGNAL     ;循环扫描输出信号

; R4:COUNT KEY_NO    ;按键计数编号

;----------------------------

SCAN:               ;键盘扫描控制程序

  MOV R3,#0FEH        ;加载扫描输出信号初值11111110B

  MOV R4,#0           ;按键计数编号清楚为0

  MOV R1,#4           ;循环1执行4次

  CLR PSW.5           ;PSW.5=0 表示未按键

  MOV A,R3

  MOV P2,A           ;由P2送出扫描输出信号

  MOV R5,#1          ;延迟一会

  LCALL DELAY

  MOV A,P2           ;读取P2数据以便判断是否有按键

  ANL A,#0F0H        ;取得高4位值 EX:1110XXXX

MOV R2,#4          ;循环2执行4次,检查是否按键

L2:JB ACC.4, N1       ;累加器A第4位若为1表示没按键

  MOV KEY_NO,R4     ;加载按键编号

  SETB PSW.5        ;设置按键标志位

N1:                  ;若没有按键,则跳转至此继续执行扫描过程

  INC R4             ;使按键编号加1

  RR A               ;累加器向右移动一位,以便检查下一位

  DJNZ R2,L2         ;循环2判断是否继续执行

  MOV A,R3           ;加载旧的扫描码

  RL  A              ;累加器向左移动一位

  MOV R3,A

  DJNZ R1,L2         ;循环1判断是否继续执行

BACK:

    JNB PSW.5, NO_KEY  ;设置是否按键,设置标志位FKEY的状态

    SETB FKEY          ;若有按键,则置FKEY=1

    RET

NO_KEY:

    CLR  FKEY          ;若没有按键则置FKEY=0

    RET

;----------------------------------------------------------

GET_KEY:                ;等待按键并传回按键码

   CLR FKEY             ;清除按键标志为,置FKEY=0

   LCALL SCAN            ;执行按键扫描

   JB FKEY,GE1           ;测试按键标志

   LJMP GET_KEY

GE1:LCALL SCAN             ;执行按键扫描

   JB FKEY,GE1           ;等待按键放开来

  MOV A,KEY_NO

  MOV DPTR,#TABLE_DIG    ;经过查表的方式找出按键码

  MOVC A,@A+DPTR

  MOV KEY_NO,A

  RET

;--------------------------------------------------------

SO:                        ; 依据按键码发出单音

   MOV R3,#1

   LCALL PLAY              ;调用子函数,确定发音的音阶,控制喇叭的开关

   RET

;-------------------------------

SOP:

  CJNE A,#0,A1             ;判断是不是K0键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#1

  LCALL SO

  RET

A1:

  CJNE A,#1,A2             ; 判断是不是K1键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#2

  LCALL SO

  RET

A2:

  CJNE A,#2,A3             ; 判断是不是K2键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#3

  LCALL SO

  RET

A3:

  CJNE A,#3,A4              ; 判断是不是K3键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#4

  LCALL SO

  RET

A4:

  CJNE A,#4,A5              ; 判断是不是K4键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#5

  LCALL SO

  RET

A5:

  CJNE A,#5,A6               ; 判断是不是K5键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#6

  LCALL SO

  RET

A6:

  CJNE A,#6,A7              ; 判断是不是K6键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#7

  LCALL SO

  RET

; NEXT HIGH TONE 1--7..................

A7:

  CJNE A,#07H,A8            ; 判断是不是K7键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#8

  LCALL SO

  RET

A8:

  CJNE A,#0AH,A9            ; 判断是不是K10键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#9

  LCALL SO

  RET

A9:

  CJNE A,#0BH,A10            ; 判断是不是K11键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#10

  LCALL SO

  RET

A10:

  CJNE A,#0CH,A11              ; 判断是不是K12键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#11

  LCALL SO

  RET

A11:

  CJNE A,#0DH,A12            ; 判断是不是K13键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#12

  LCALL SO

  RET

A12:

  CJNE A,#0EH,A13             ; 判断是不是K14键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#13

  LCALL SO

  RET

A13:

  CJNE A,#0FH,A14              ; 判断是不是K15键被按下,若按下继续执行,否则跳转后继续比较

  MOV R4,#14

  LCALL SO

  RET

A14:                               ;若没有按键则返回程序继续执行

  RET

;-------------------------------------------------

RUN:                           ;主程序

  MOV NO,#0                    ;将计数值初值设为0

  MOV R0,#MEM                  ;初始的内存地址送给R0

LOOP:

  MOV A,NO

  MOV X,#0

  LCALL SHOW_DIG                ;将计数值在LCD中显示出来

  LCALL GET_KEY                 ;等待按键,待有按键后执行下面程序

; CHECK A=9 CLEAR,

  CJNE A,#9,B1                 ;判断是否是K9键按下,若是,清除计数设置初始内存

  LCALL BZ

  LCALL LED_BL

  MOV NO,#0                     ;按下K9键清除计数

  MOV R0,#MEM                   ;设置内存起始地址

  LJMP LOOP                      ;继续循环执行

;A=8 REPLAY........

B1: CJNE A,#8,B2                ;判断是否是K8键按下,若是,调用子函数

                                ; RPLAY,否则,跳到B2继续执行

    LCALL LED_BL

    LCALL RPLAY                  ;按下K8键开始演奏内存内的音阶

    LCALL LED_BL

    LJMP LOOP                    ;继续循环执行

B2:

   MOV A,KEY_NO

   MOV X,#0                    ; 设置显示的地址

   LCALL SHOW_DIG2             ;显示按键值

;PLAY TONE...........................

   MOV A,KEY_NO                 ;演奏单音

   LCALL SOP

; SAVE TO MEM.......            ;将按键值存入内存

   MOV A,KEY_NO

   MOV @R0,A

  

   INC NO                        ;计数增加

   MOV A,NO

   MOV B,#MNO

   CJNE A,B,B3

   LCALL BZ                       ;发出哔的一声

   LCALL LED_BL                   ;LED闪动

   LCALL BZ

   LCALL LED_BL

   MOV NO,#(MNO-1)

   LJMP LOOP                      ;继续循环执行

B3:

; SAVE TO MEM.......             ;将按键值存入内存

   MOV A,KEY_NO

   MOV @R0,A

   INC R0

;....................................

RPLAY:                           ;重新演奏输入进去的音阶

   MOV A,NO

   MOV X,#0

   LCALL SHOW_DIG                  ;显示演奏音阶编号

   MOV A,NO                       ;编号为0则结束

   CJNE A,#0,RP0

   RET

RP0:

   MOV CO,NO

   MOV R0,#MEM

   MOV R1,#1

RP1:

   JB K_INT,RP2                        ;按下K_INT键则停止演奏

   LCALL BZ                          ;发出哔的一声

   LCALL LED_BL                      ;LED闪动

   LCALL LED_BL

   RET

RP2:

   MOV A,R1

   MOV X,#3

   LCALL SHOW_DIG                    ;显示演奏编号

   MOV A,@R0                        ;LOAD KEY FROM MEM

   PUSH ACC

   MOV X,#0                           ; 设置显示的地址

   LCALL SHOW_DIG2                  ;显示音阶编号

   POP ACC

   LCALL SOP                         ;发出单音

   INC R0

   INC R1

   DJNZ CO,RP1                      ;继续循环处理

   RET

 ;-----------------------------------------------

 BZ:                                 ;发出单音,发出D0的音

   MOV R4,#1

   MOV R3,#1

   LCALL PLAY

   RET

 ;-------------------------------------

SET_LCD:                            ;对LCD做初始化设置及测试

    CLR EN; en=0                     ;启用失效

    LCALL INIT_LCD                    ;初始化LCD

    MOV R5,#1                        ;延迟一下

    LCALL DELAY

    MOV DPTR,#LMESS1                 ;指针指到显示消息1

    MOV A,#1                         ;设置显示在第一行

    LCALL LCD_PRINT                  ;显示执行消息1于LCD第一行

    MOV DPTR,#LMESS2                 ;指针指到显示消息2

    MOV A,#2                         ;设置显示在第二行

    LCALL LCD_PRINT                  ;显示执行消息2于LCD第二行

    RET

;----------------------------------------

INIT_LCD1:                           ;LCD控制指令初始化,设置LCD的工作方式

   MOV A,#28H                        ;双列显示,字型使用5×7点阵,四位输入方式

   LCALL WCOM                        ;将命令写入LCD

   MOV A,#0EH                        ;显示开关打开,光标出现,但光标不闪烁

   LCALL WCOM                        ;将命令写入LCD

   MOV A,#14H                        ;每次向右移一位,且每次移一个字节

   LCALL WCOM                        ;将命令写入LCD

   MOV A,#01H                        ;清除LCD 显示屏

   LCALL WCOM                        ;将命令写入LCD

   RET

;----------------------------------------------

; DPTR=MESSAGE POINTER

LCD_PRINT:

   CJNE A,#1,LINE2                   ;判断是否为第一行

LINE1: MOV A,#80H                    ;设置LCD的第一行地址

       LCALL WCOM                     ;将命令写入LCD

       LCALL CLR_LINE                 ;清除该行字符数据

       MOV A,#80H                    ;设置LCD的第一行地址

       LCALL WCOM                       ;将命令写入LCD

       JMP FILL

LINE2: MOV A,#0C0H                   ;设置LCD 的第二行地址

       LCALL WCOM                       ;将命令写入LCD

       LCALL CLR_LINE                 ;清除该行字符数据

       MOV A,#0C0H                   ;设置LCD的第二行地址

       LCALL WCOM                       ;将命令写入LCD

FILL:                                ;填入字符

    CLR A

    MOVC A,@A+DPTR                   ;由消息区取出字符

    CJNE A,#0,LL1                    ;判断是否为结束码

    RET

LL1:

   LCALL WDATA                        ;将数据写入LCD

   INC DPTR                          ;指针加1

   JMP FILL                          ;继续填入字符

   RET

;-----------------------------------------

CLR_LINE:                            ;清除该行LCD的字符

   MOV R0,#16

C1:

 MOV A,#' '

    LCALL WDATA                      ;将数据写入LCD

   DJNZ R0,C1

   RET

;--------------------------------------------

DE:  MOV R7,#5                        ;短暂延迟

DE2: DJNZ R7,DE2

    RET

;---------------------

EN1:                                   ;短脉冲产生启用信号

    SETB EN

    LCALL DE

    CLR EN

    LCALL DE

    RET

;---------------------

INIT_LCD:                              ;4位I/O控制LCD 接口初始化

   MOV P0,#28H                         ;RS=0  R/W=0 D7~D4=0011

   LCALL EN1

   MOV P0,#28H

   LCALL EN1

   MOV P0,#28H

   LCALL EN1

   MOV P0,#28H                          ;启动4位接口命令

   LCALL EN1

   LCALL INIT_LCD1                       ;LCD指令设置初始化

   RET

;---------------------------

WCOM:                                ;以4位控制方式将命令写至LCD

;  WEIT HI 4 BIT                          ;写入高4位数据

   MOV P0,A

   CLR RS;    SET COMMAND                 ;设置写入命令

   LCALL EN1

   RLC A                                  ;左移4位

   RLC A

   RLC A

   RLC A

 ; WEIT L0 4 BIT                          ;写入低4位数据

   MOV P0,A

   CLR RS ; SET COMMAND                   ;设置写入命令

   LCALL EN1

   RET

 ;-----------------------------------------

 WDATA:                                   ;以4位控制方式将数据写入LCD

 ; WEIT HI 4 BIT                          ;写入高4位数据

   MOV P0,A

   SETB RS; SET DATA                      ;设置写入数据

   LCALL EN1

   RLC A                                  ;左移4位

   RLC A

   RLC A

   RLC A

 ; WRITE L0 4 BIT                         ;写入低4位数据

   MOV P0,A

   SETB RS; SET DATA                      ;设置写入数据

   LCALL EN1

   RET

 ;-------------------------------------

 LMESS1: DB ".. .. .. ..8PLAY",0            ;0为结束符,用来停止显示

 LMESS2: DB ".. .. .. ..9CLR",0             ;0为结束符,用来停止显示

 ;-------------------------------------

 ; PRINT A CHAR ON LCD LINE 1

 ; A-ASC DATA

 ; B=LINE X POS.

 LCDP1:                                  ;在LCD的第一行显示字符

   ; LINE 1

    PUSH ACC                             ;将A放入堆栈

    MOV A,B                              ;设置显示的地址

    ADD A,#80H                           ;设置LCD的第一行地址

    LCALL WCOM                            ;写入命令

    POP ACC                              ;由堆栈取出A

    LCALL WDATA                           ;写入数据

    RET

;-----------------------------------------------

; PRINT A CHAR ON LCD LINE 2

; A=ASC DATA

; B=LINE X POS.

LCDP2:                                  ;在LCD的第二行显示字符

 ; LINE 1

   PUSH ACC                             ;将A放入堆栈

   MOV A,B                              ;设置显示的地址

   ADD A,#0C0H                          ;设置LCD的第二行地址

   LCALL WCOM                            ;写入命令

   POP ACC                              ;由堆栈取出A

   LCALL WDATA                           ;写入数据

   RET

 ;-------------------------------------------

    SHOW_DIG:                     ; 在LCD的第一行显示数字

    MOV B,#10                          ;设置被除数

    DIV AB                         ;除法运算,结果A存商数,B存余数

    ADD A,#30H                         ;A位十位数,转换为字符

    PUSH B                             ;B放入堆栈暂存起来

    MOV B,X                            ;设置LCD显示的位置

    LCALL LCDP1                         ;由LCD显示出来

    POP B                              ;B由堆栈取出来

    MOV A,B                            ;B为个位数

    ADD A,#30H                         ;转换为字符

    INC X                              ;LCD显示位置加1

    MOV B,X                            ;设置LCD显示的位置

    LCALL LCDP1                         ;由LCD显示出来

    RET

 ;---------------------------------------

    SHOW_DIG2:                           ;在LCD的第二行显示数字

    MOV B,#10                          ;设置被除数

    DIV AB                           ;除法运算,结果A存商数,B存余数

    ADD A,#30H                         ;A位十位数,转换为字符

    PUSH B                             ;B放入堆栈暂存起来

    MOV B,X                            ;设置LCD显示的位置

    LCALL LCDP2                         ;由LCD显示出来

    POP B                              ;B由堆栈取出来

    MOV A,B                            ;B为个位数

    ADD A,#30H                         ;转换为字符

    INC X                              ;LCD显示位置加1

    MOV B,X                            ;设置LCD显示的位置

    LCALL LCDP2                         ;由LCD显示出来

    RET

 ;---------------------------------------------

END                                    ;程序结束

                                                            附录2.电路图

附录3程序流程图

总结

    通过理论设计,到仿真软件仿真,再到确定具体方案,再到安装实际电路,最后到调试电路、成型。整个过程都需要我们充分利用所学的知识进行思考、借鉴。可以说,本次课设是针对前面所学的知识进行的一次比较综合的检验。总的来说,这次课设虽然累,但非常充实。

    在这次实习中,正确的思路是很重要的,只有你的设计思路是正确的,那你的设计才有可能成功。因此我们在设计前必须做好充分的准备,认真查找详细的资料,为我们设计的成功打下坚实的基础。要做好本次的课程设计,熟练地掌握课本上的理论知识是前提。这样才能对试验中出现的问题进行一定的分析和解决。

更多相关推荐:
电子琴设计报告

工程设计报告年3月6日电子琴设计信息工程学院二系一队王飞五32420xx001李晓辰32420xx003李笑添32420xx01120xx摘要本文介绍了简易电子琴的设计它通过软硬件结合实现硬件系统是以51系列单...

简易电子琴设计报告

简易电子琴课程设计报告摘要555定时器是一种模拟和数字功能相结合的中规模集成器件555定时器成本低性能可靠只需要外接几个电阻电容就可以实现多谐振荡器单稳态触发器及施密特触发器等脉冲产生与变换电路它也常作为定时器...

单片机电子琴设计报告

单片机课程设计报告设计题目单片机电子琴1单片机课程设计报告目录第1章概述4第2章课程设计任务及要求421设计任务422设计要求4第3章系统设计531设计方案532系统设计5322系统流程图5322系统原理图73...

555简易电子琴设计报告

北京交通大学电子技术课程设计报告随着科学技术的发展和人类的进步电子技术已经成了各种工程技术的核心特别是进入信息时代以来电子技术更是成了基本技术其具体应用领域涵盖了通信领域控制系统测试系统计算机等等各行各业生活中...

单片机电子琴设计报告

单片机课程设计报告设计题目单片机电子琴摘要随着社会的发展进步,音乐逐渐成为我们生活中很重要的一部分,有人曾说喜欢音乐的人不会向恶。我们都会抽空欣赏世界名曲,作为对精神的洗礼。本论文设计一个基于单片机的简易电子琴…

简易电子琴设计报告

电子技术课程设计报告学院电气与电子工程学院专业班级电信班学生姓名指导教师完成时间成绩简易电子琴设计报告一设计要求本设计是基于学校实验室的环境根据实验室提供的实验条件来完成设计任务设计一个简易电子琴1按下不同琴键...

电子琴设计报告(完整)

电子琴设计报告院专业计算机科学与技术学号20xx03784姓名张林峰班级计科1002设计时间设计地点42号机房指导教师严圣华目录一总体方案二硬件介绍三音乐产生原理四软件设计五电子琴演示六完整代码七实验体会一总体...

专业方向课程设计报告-基于单片机的电子琴设计

专业方向课程设计报告基于单片机的电子琴设计班级组员组号基于单片机的电子琴设计1设计要求44按键组成16个按键矩阵设计成16个音然后再用一个音频放大模块来使音乐播出的声音变大用户可通过这16个键的随意组合来随意弹...

电子琴课程设计报告

物理与信息工程系课程设计报告课程名称专业综合课题名称基于单片机的电子琴设计专业电子信息科学与技术年班级09级电科3班学号姓名指导教师20##年6月1日目录封面...1目录...2第一章设计要求及工作原理.31.…

毕业设计(论文)基于单片机AT89C51的简易电子琴系统

四川职科技业技术学院毕业设计论文专科20xx届院系移动通信与软件学院课题专业电子信息工程技术班级电信1班学生姓名宁莎指导老师学号20xx01010121日期20年月日四川科技职业技术学院20xx届毕业设计论文开...

电子琴课程设计报告1

课程设计报告课程题目系别年级专业班级学号学生姓名指导教师职称设计时间目录绪论...2第一章题目要求...31.1设计要求...31.2设计目的...31.3设计环境...4第二章方案设计与论证...42.1主要…

简单电子琴的制作设计报告

电子琴的制作31电子琴的原理1由4X4组成16个按钮矩阵设计成16个音2可随意弹奏想要表达的音乐3相应音符的频率值TABLE1DB0FAH15H0FAH67H0FBH06H0FBH90HDB0FCH0CH0FC...

电子琴设计报告(39篇)