2017—2018学年度第一学期

《单片机原理及应用》作品考试

八音盒

2017-2018-1《单片机原理及应用》作品设计提交文档

一、作品设计目的

1、利用51单片机的各个部件结合实现八音盒。

2. 通过按键控制蜂鸣器播放设定的歌曲,按键1~8控制8首歌曲的播放,按键0 停止播放歌曲。

3. 熟练掌握C 语言与单片机的结合,单片机的原理和PCB制图原理。

二、作品设计内容

1、总电路图显示

2、总程序

#include
<reg52.h>

#define uchar unsigned
char

#define uint unsigned
int

#define ulong unsigned
long

uchar th0_f;

uchar tl0_f;

unsigned char i=100;

unsigned char
j,k,temp,key;

uchar code
jie8[8]={12,14,16,17,19,21,23,24};

 

sbit datacs=P2^6;   //位选

sbit chipcs=P2^7;         //段选

uchar code table[]={

0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f};                                               ///共阴数码管显示段码0~8

 

sbit row1=P2^5;                //行端口定义

sbit row2=P2^4;

sbit row3=P2^3;

sbit row4=P2^2;

 

sbit col1=P1^7;                 //列端口定义

sbit col2=P1^6;

sbit col3=P2^0;

sbit col4=P2^1;

sbit SPEAK = P3^0;//接蜂鸣器管脚

 

/*按键扫描函数*/

void keyScan(void)

{

                                     col1=0;col2=1;col3=1;col4=1;

                                     temp=P2&0x3f;

                                                    

                                     if(col1==0)                      //假设第一列有按键

                                     {

                                          if(temp!=0x3f)              //没有按键退出这次对第一列键盘扫描

                                          {

                                                 temp=P2&0x3C;

                                                 switch(temp)

                                                 {

                                                        case 0x38: key=12; break;     //0’键被按下时导通,则对应端口变为低电平

                            case
0x34:key=8;break;

                                                     case 0x2C:key=4;break;

                            case
0x1C:key=0;break;

                                                 }

                                          }

                                     }

                                     col1=1;col2=0;col3=1;col4=1;

                                     temp=P2;

                                     temp=temp&0x3f;

                                     if(col2==0)

                                     {

                                          if(temp!=0x3f)

                                          {

                                                 temp=P2&0x3C;

                                                 switch(temp)

                                                 {

                                                        case 0x38: key=13; break;     //0’键被按下时导通,则对应端口变为低电平

                            case
0x34:key=9;break;

                                                     case 0x2C:key=5;break;

                            case
0x1C:key=1;break;

                                                 }

                                          }

                                     }

                                     col1=1;col2=1;col3=0;col4=1;

                                     temp=P2;

                                     temp=temp&0x3f;

                                     if(temp!=0x3f)

                                     {

                                          temp=P2&0x3C;

                                                 switch(temp)

                                                 {

                                                        case 0x38: key=14; break;     //0’键被按下时导通,则对应端口变为低电平

                            case
0x34:key=10;break;

                                                     case 0x2C:key=6;break;

                            case
0x1C:key=2;break;

                                                 }

                                     }

                                     col1=1;col2=1;col3=1;col4=0;

                                     temp=P2;

                                     temp=temp&0x3f;

                                     if(temp!=0x3f)

                                     {

                                     temp=P2&0x3C;

                                                 switch(temp)

                                                 {

                                                        case 0x38: key=15; break;     //0’键被按下时导通,则对应端口变为低电平

                            case
0x34:key=11;break;

                                                     case 0x2C:key=7;break;

                            case
0x1C:key=3;break;

                                                 }

                                     }

 

 

 /**************************中断函数*******************************************/

timer0() interrupt 1

{

                                     TL0=tl0_f;TH0=th0_f;

                                     SPEAK
=~SPEAK; //
取反音乐输出IO

}

 

 /********************T0的值,及输出频率对照表***********************************/

uchar code freq[36*2]={

                                                                      0xA9,0xEF,//00220HZ ,1 //0

                                                                      0x93,0xF0,//00233HZ ,1#

                                                                      0x73,0xF1,//00247HZ ,2

                                                                      0x49,0xF2,//00262HZ ,2#

                                                                      0x07,0xF3,//00277HZ ,3

                                                                      0xC8,0xF3,//00294HZ ,4

                                                                      0x73,0xF4,//00311HZ ,4#

                                                                      0x1E,0xF5,//00330HZ ,5

                                                                      0xB6,0xF5,//00349HZ ,5#

                                                                      0x4C,0xF6,//00370HZ ,6

                                                                      0xD7,0xF6,//00392HZ ,6#

                                                                      0x5A,0xF7,//00415HZ ,7

                                                                      0xD8,0xF7,//00440HZ 1 //12

                                                                      0x4D,0xF8,//00466HZ 1# //13

                                                                      0xBD,0xF8,//00494HZ 2 //14

                                                                      0x24,0xF9,//00523HZ 2# //15

                                                                      0x87,0xF9,//00554HZ 3 //16

                                                                      0xE4,0xF9,//00587HZ 4 //17

                                                                      0x3D,0xFA,//00622HZ 4# //18

                                                                      0x90,0xFA,//00659HZ 5 //19

                                                                      0xDE,0xFA,//00698HZ 5# //20

                                                                      0x29,0xFB,//00740HZ 6 //21

                                                                      0x6F,0xFB,//00784HZ 6# //22

                                                                      0xB1,0xFB,//00831HZ 7 //23

                                                                      0xEF,0xFB,//00880HZ `1

                                                                      0x2A,0xFC,//00932HZ `1#

                                                                      0x62,0xFC,//00988HZ `2

                                                                      0x95,0xFC,//01046HZ `2#

                                                                      0xC7,0xFC,//01109HZ `3

                                                                      0xF6,0xFC,//01175HZ `4

                                                                      0x22,0xFD,//01244HZ `4#

                                                                      0x4B,0xFD,//01318HZ `5

                                                                      0x73,0xFD,//01397HZ `5#

                                                                      0x98,0xFD,//01480HZ `6

                                                                      0xBB,0xFD,//01568HZ `6#

                                                                      0xDC,0xFD,//01661HZ `7 //35

                                                                };

/***************************音乐符号串解释函数****************************/

//入口:要解释的音乐符号串,输出的音调串,输出的时长串

changedata(uchar
*song,uchar *diao,uchar *jie)

{

                                     uchar
i,i1,j;

                                     char gaodi;
//
高低+/-12音阶

                                     uchar
banyin;//
有没有半个升音阶

                                     uchar
yinchang;//
音长

                                     uchar code
jie7[8]={0,12,14,16,17,19,21,23}; //C
调的7个值

                                     *diao=*song;

                                     for(i=0,i1=0;;)

                                     {

                                          gaodi=0; //高低=0

                                          banyin=0;//半音=0

                                          yinchang=4;//音长1

                                          if((*(song+i)=='|') || (*(song+i)==' '))
i++; //
拍子间隔和一个空格过滤

                                          switch(*(song+i))

                                          {     

                                                 case
',': gaodi=-12;i++;//
低音

                                                 break;

                                                 case
'`': gaodi=12;i++; //
高音

                                                 break;

                                          }

                                          if(*(song+i)==0) //遇到0结束

                                          {

                                                 *(diao+i1)=0;
//
加入结束标志0

                                                 *(jie+i1)=0;

                                                 return;

                                          }

                                          j=*(song+i)-0x30; i++; //取出基准音

                                          j=jie7[j]+gaodi; //加上高低音

                                          yinc: switch(*(song+i))

                                                 {

                                                        case '#': //有半音j加一个音阶

                                                               i++;j++;

                                                               goto
yinc;

                                                        case '-': //有一个音节加长

                                                               yinchang+=4;

                                                               i++;

                                                               goto
yinc;

                                                        case '_': //有一个音节缩短

                                                               yinchang/=2;

                                                               i++;

                                                               goto
yinc;

                                                        case '.': //有一个加半拍

                                                               yinchang=yinchang+yinchang/2;

                                                               i++;

                                                               goto
yinc;

                                                 }

                                          *(diao+i1)=j; //记录音符

                                          *(jie+i1)=yinchang; //记录音长

                                          i1++;

                                     }

}

 

/******************************奏乐函数***************************************/

//入口:要演奏的音乐符号串

void play(uchar
*songdata)

{

                                     uchar
i,c,j=0;

                                     uint n;

                                     uchar  diaodata[48]; //音调缓冲

                                     uchar
jiedata[48]; //
音长缓冲

                                     changedata(songdata,diaodata,jiedata);
//
解释音乐符号串

                                     TR0=1;

                                      keyScan();

                                     while(key==1||key==2||key==3||key==4||key==5||key==6||key==7||key==8)

{                                   for(i=0;diaodata[i]!=0;i++)
//
逐个符号演奏

                                     {

                                          tl0_f=freq[diaodata[i]*2]; //取出对应的定时值送给T0

                                          th0_f=freq[diaodata[i]*2+1];

                                          for(c=0;c<jiedata[i];c++) //按照音长延时

                                          {     

                                             
keyScan();

                                                 for(n=0;n<29500;n++);
//29500

                                                 if(key==0)
//
发现按键0,立即退出播放

                                                 {

                                                        TR0=0;

                                                        return;

                                                 }

                                          }

                                          TR0=0;

                                          for(n=0;n<460;n++); //音符间延时

                                          TR0=1;

                                     }TR0=0;

                                     }

}                                  

 

//茉莉花

uchar code
molihua[]={"33_5_6_`1_`1_6_|55_6_5-|33_5_6_`1_`1_6_|55_6_5-|"

                      
"5553_5_|665-|32_3_53_2_|11_2_1|"

                      
//"3_2_1_3_2.3_|56_`1_5-|23_5_2_3_1_,6_|,5-,61|"

                      
//"2.3_1_2-1_,6_|,5--"

                                                                   };

//世上只有妈妈好

uchar code mamahao[]={

"6.5_35|`16_5_6-|35_6_53_2_|1_,6_5_3_2-|"

"2.3_55_6_|321-|5.3_2_1_,6_1_|,5--"

};

//小毛驴

uchar code
xiaomaolv[]={"1_1_1_3_|5_5_5_5_|6_6_6_`1|5-|"

                        
"4_4_4_6_|3_3_3_3_|2_2_2_2_|5-"};

//我是一只菠萝

uchar code boluo[]={

                                                 "1-|2_4_3_2_55|5_6_3_4_22|2_4_3_2_1_`1_7_6_|5_4_2_3_11|"

                                                 "2_4_3_2_55|5_6_3_4_22|2_4_3_2_1_5_2_3_|1---|"

};

//小星星

uchar code
xiaoxingxing[]={

"1155|665-|4433|221-|"

"5544|332-|5544|332-|"

"1155|665-|4433|221-|"

};

//春天在哪里

uchar code
chuntian[]={"3_3_3_1_|,5,5_|3_3_3_1_|3-|5_5_3_1_|,5_,5_,5|,6_,7_1_3_|2-|"

 "3_3_3_1_|,5,5_|3_3_3_1_|3-|5_6_5_6_|5_4_3_1_|,5_3_|2_1_"};

//找朋友

uchar code
zhaopeng[]={"5_6_5_6_|5_6_5|5_`1_7_6_|5_6_5"};

//一分钱

uchar code
yifen[]={"5`1|6_`1_5|3_5_2_3_|5|3_5_6_`1_|5_6_5_3_|5_13_2"};

//乐谱方式输入的音乐播放

/******************************数码管函数***************************************/

 //数码管显示

 void display(unsigned char num)

{

        P0=table[num];

                                            

        datacs=1;

        datacs=0;

        P0=0xfe;

        chipcs=1;

        chipcs=0;

}

 

/*******************************主函数****************************************/

void main(void)

{

                                     TMOD =
0x01; //
使用定时器016位工作模式

                                     TR0 = 0;

                                     ET0 = 1;

                                     EA = 1;

                                     EX0=1;

 

 

                                     while(1)

                                     { 

                                     P3=0xff;

                                   keyScan();

                                     display(key);

                                        switch(key)

                                           {

                                                   case 1:play(molihua);      break;

                                                  case 2:play(mamahao);     break;                        

                                                   case 3:play(xiaomaolv);   break;                               

                                                   case 4:play(boluo);   break;

                                                 case
5:play(xiaoxingxing);   break;                        

                                                 case
6:play(chuntian); break;                 

                                                 case
7:play(yifen); break;

                                                 case
8:play(zhaopeng); break;

   }  
}   }

 

3、PCB设计过程

(1)画原理图

(2)原理图库

(3)画封装图

生成PCB图、

布线

敷铜

三、调试过程

1、  详细连线

用跳线连接单片机P3^0口连接开发板蜂鸣器p6口;用排线连接单片机P0口和开发板的P7口

2、调试过程简介

在单片机中下载好代码之后,按1键播放第一首音乐,按0停止之后,可以按其他按键播放其他音乐

 

四、作品设计心得和经验

      

单片机课程设计>八音盒的更多相关文章

  1. 单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》

    引言 本设计以AT89S52单片机为控制核心,时钟芯片DS1302提供时钟源,配合LCD1602液晶显示模块,组成基本硬件系统,同时利用HC-05嵌入式蓝牙串口通讯模块,可在手机端进行日期.时间的校准 ...

  2. 单片机课程设计-四位加法计算器设计参考程序(c语言)

    #include<reg52.h> typedef unsigned char uint8; typedef unsigned int uint16; sbit rw=P2^; sbit ...

  3. 单片机课程设计——课程设计之四位加法计算器(2)(C代码)

    #include<reg52.h> typedef unsigned char uint8; typedef unsigned int uint16; sbit rw=P2^5; sbit ...

  4. 嵌入式系统及应用课程设计——基于STM32的温湿度监测系统

    大三上学期期末总结,嗯,没错上学期,写在新学期开始,hhh. 上学期学了一门嵌入式系统及应用的课程,期末的课程设计题目是基于STM32的温湿度监测系统. 记得刚开始做课程设计的时候,听说先设计画出原理 ...

  5. Android课程设计——博学谷1.0

    本文讲述了如何应用大三下学期智能移动终端开发技术课程所学知识,完成包含服务器端.客户端程序的应用——博学谷登录模块的开发,结合java语言基本知识,例如:字符串.列表.类.数据库读写等,设计.实现一个 ...

  6. [课程设计]任务进度条&开发日志目录

    任务进度条&开发日志目录 周期 时间 任务 Sprint One   11.14     ●  Scrum团队分工及明确任务1.0    Sprint One   11.15   ●  Scr ...

  7. 课程设计 --- 黑白棋中的 AI

    原文链接:https://www.dreamwings.cn/reversi/3013.html 到了考试周了佯,可是偏偏这个时候迎来了很多很多的课程设计,幸好教授把C语言的课程设计提前发出了,不然都 ...

  8. Java课程设计——扫雷(winmine)

    因为是我的课程设计,要是有冲突就不好了,转载注明出处!!! 程序很简单,毕竟我是搞acm的,我就只介绍一下闪光点. 中心空白搜索的时候,我用的DFS: 有一点是要注意的,就是JFrame不支持重画,还 ...

  9. [课程设计]Scrum 1.6 多鱼点餐系统开发进度

    [课程设计]Scrum 1.6 多鱼点餐系统开发进度(点餐页面按钮添加&修复) 1.团队名称:重案组 2.团队目标:长期经营,积累客户充分准备,伺机而行 3.团队口号:矢志不渝,追求完美 4. ...

随机推荐

  1. hibernate 中对象的3种状态总结

    1.Hibernate把对象分文三种状态:Transient(临时状态).Persistent(持久化状态).Detached(游离状态). 1)Transient:刚刚new出来的对象,就是Tran ...

  2. FocusBI:SSAS体系结构(原创)

    关注微信公众号:FocusBI 查看更多文章:加QQ群:808774277   获取学习资料和一起探讨问题. SSAS是微软BI组件系列中最核心的组件,商业智能的心脏所有的数据都从这里统一输出,它能把 ...

  3. Struts2入门介绍(二)

    一.Struts执行过程的分析. 当我们在浏览器中输入了网址http://127.0.0.1:8080/Struts2_01/hello.action的时候,Struts2做了如下过程: 1.Stru ...

  4. Eclipse提示workspaces is use

    问题描述: 有时候因为强行关闭Eclipse导致再次打开出现workspace提示正在使用 解决办法: 删除workspace目录下隐藏文件夹 .metadata 中的 .lock 文件 worksp ...

  5. vim命令“=”、“d”、“y”的用法(结合光标移动命令,一些场合会非常方便)

    vim有许多命令,网上搜有一堆贴子.文章列举出各种功能的命令. 对于“=”.“d”.“y”,我在无意中发现了它们所具有的相同的一些用法,先举以下三个例子: =nG dnG ynG 其中,n为行号.注意 ...

  6. PAT 1071. Speech Patterns

    又是考输入输出 #include <cstdio> #include <cstdlib> #include <string> #include <vector ...

  7. 软件项目技术点(5)——在canvas上绘制动态网格线

    AxeSlide软件项目梳理   canvas绘图系列知识点整理 grid类的实现 当鼠标在画布上缩放时,网格能跟着我的鼠标滚动而相应的有放大缩小的效果. 下面是具体实现的代码,draw函数里计算出大 ...

  8. 【转】R树空间索引

    R树在数据库等领域做出的功绩是非常显著的.它很好的解决了在高维空间搜索等问题.举个R树在现实领域中能够解决的例子吧:查找20英里以内所有的餐厅.如果没有R树你会怎么解决?一般情况下我们会把餐厅的坐标( ...

  9. 【阿里云产品公测】云引擎ACE公测感受

    听说阿里云ACE开始公测了,怀着激动的心情赶紧试用了一下. 这是我用ACE做出来的效果:http://haoyuming.aliapp.com/ 大家点点看看啊 A*W/Q<~I   :eSwX ...

  10. 解决MFC对话框类不能建立成功的方法(出现unable to open the files XX for class XX)

    原文:http://blog.163.com/wangqi1973_off/blog/static/131034571201011885546230 为新加的对话框资源添加新类,类名取做CColorV ...