根据STM32的电子琴设计.docx

上传人:b****0 文档编号:8917968 上传时间:2023-05-16 格式:DOCX 页数:22 大小:2.42MB
下载 相关 举报
根据STM32的电子琴设计.docx_第1页
第1页 / 共22页
根据STM32的电子琴设计.docx_第2页
第2页 / 共22页
根据STM32的电子琴设计.docx_第3页
第3页 / 共22页
根据STM32的电子琴设计.docx_第4页
第4页 / 共22页
根据STM32的电子琴设计.docx_第5页
第5页 / 共22页
根据STM32的电子琴设计.docx_第6页
第6页 / 共22页
根据STM32的电子琴设计.docx_第7页
第7页 / 共22页
根据STM32的电子琴设计.docx_第8页
第8页 / 共22页
根据STM32的电子琴设计.docx_第9页
第9页 / 共22页
根据STM32的电子琴设计.docx_第10页
第10页 / 共22页
根据STM32的电子琴设计.docx_第11页
第11页 / 共22页
根据STM32的电子琴设计.docx_第12页
第12页 / 共22页
根据STM32的电子琴设计.docx_第13页
第13页 / 共22页
根据STM32的电子琴设计.docx_第14页
第14页 / 共22页
根据STM32的电子琴设计.docx_第15页
第15页 / 共22页
根据STM32的电子琴设计.docx_第16页
第16页 / 共22页
根据STM32的电子琴设计.docx_第17页
第17页 / 共22页
根据STM32的电子琴设计.docx_第18页
第18页 / 共22页
根据STM32的电子琴设计.docx_第19页
第19页 / 共22页
根据STM32的电子琴设计.docx_第20页
第20页 / 共22页
亲,该文档总共22页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

根据STM32的电子琴设计.docx

《根据STM32的电子琴设计.docx》由会员分享,可在线阅读,更多相关《根据STM32的电子琴设计.docx(22页珍藏版)》请在冰点文库上搜索。

根据STM32的电子琴设计.docx

根据STM32的电子琴设计

综合设计任务书

学生班级:

学生姓名:

学号:

设计名称:

电子琴的设计与实现

起止日期:

2013.11.18—2013.12.15指导教师:

设计要求:

利用单片机设计一简易电子琴。

功能要求:

(1)按下不同按键,发出不同1、2、3、4、5、6、7七个音符;

(2)用LED或LCD显示当前按键。

总体要求:

给出电路原理图、电路调试结果、程序源代码;提交设计报告。

综合设计学生日志

时间

设计内容

2013.11.19-2013.11.22

相关资料的查找;

2013.11.23-2013.11.25

搭建硬件电路;

2013.11.26-2013.11.29

单片机基本知识的复习以及软件系统框架的搭建;

2013.11.30-2013.12.06

软件程序的编写和完善;

2013.12.07

软硬件结合调试,优化;

2013.12.08-2013.12.14

设计材料的整理和设计报告的书写。

电子琴的设计与实现

摘要:

本次设计是xx专业专业方向设计,利用单片机设计简易电子琴。

其主要功能为:

按下不同按键,发出不同1、2、3、4、5、6、7七个音符并且用LED或LCD显示当前按键。

选用stm32f103C8T6,它有8个定时器,部分定时器有多达4个用于输入捕获/输出比较/PWM或脉冲计数的通道和增量编码器输入。

利用芯片内部相关定时器来输出PWM,从而来驱动蜂鸣器。

通过读取外部按键输入的值来相应改变定时器相关寄存器的值,从而来改变PWM的输出频率来达到发出不同音调。

关键词:

STM32f103C8T6;PWM;定时器

TheDesignoftheKeyboard

Abstract:

Thisdesignistheprofessionaldirectionofbiomedicalengineeringdesign.UsingSingleChipMicrocomputertoachieveasimpleKeyboard.Itsmainfunctionis:

Whileauserpressthedifferentkeys,itwillmakedifferentsoundsfromthebuzzeranddisplaydifferentnumberswhichcorrespondedtothesounds.Usingstm32f103--C8T6ascontrolchip.Ithas16-bittimers.Someofthemwithupto4IC/OC/PWMorpulsecounter.MakinguseoftheTimerstogeneratedrivingsignal.Byreadingthestateoftheexternalkeytochangethefrequencyofoutput.DifferentfrequencyofthePWMwillcontrolbuzzermakesdifferentsounds.

Keywords:

STM32f103C8T6;PWM;Timer

一、设计目的和意义

本综合设计是为xx专业高年级本科生开设的必修课,是对学生运用所学知识的一次综合训练。

其目的是让学生得到一次进行独立设计的工程实践锻炼,不仅培养严谨的科学态度和扎实的实践技能、良好的工程意识,并在设计中学会如何发现、分析和解决工程实践问题的技能和方法,将所学知识综合应用于工程实践中,为后续的毕业设计做好准备。

二、控制要求

利用单片机设计简易电子琴。

功能要求:

(1)按下不同按键,发出不同1、2、3、4、5、6、7七个音符;

(2)用LED或LCD显示当前按键。

总体要求:

给出电路原理图、电路调试结果、程序源代码;提交设计报告。

三、设计方案论证

3.1设计方案:

方案一:

采用MCS-51系列单片机来实现设计要求的功能。

MCS-51系列单片机中的基本型产品是8051,8031和8751,这三个产品只是片内程序存储器制造工艺不同。

8051的片内程序存储器ROM为掩膜型的在制造芯片时已将应用程序固化进去,使它具有了某种专用功能。

8位CPU拥有片内震荡器及时钟电路;32根I\O线;外部存储器ROM和RAM寻址范围各64KB;2个16位的定时器/计数器;5个中断源,2个中断优先级;全双工串行口;8051的中央处理器CPU由运算器和控制逻辑构成51单片机是一款比较基础的单片机。

I/O(输入/输出)引脚系统结构紧凑,功能简单,低成本。

可以实现各种丰富的应用。

通过控制I/O口的输出电平的翻转频率来实现对蜂鸣器发音音调的控制。

方案二:

采用STM32f03C8T6来实现此次设计,最高72MHz工作频率。

它有多个外部中断,八个定时器,有PWM输出模式,其中2个高级定时器,两个基本定时器,其他的是通用定时器,共48个引脚,除基本的I/O功能之外还包含有复用功能,其外设功能强大,是一款能够很方便使用的功能强大的芯片,同时可以直接对相关寄存器进行操作,。

3.2方案选择

上述两种方案相比,51单片机虽然价格便宜,但是其功能简单,I/O口少,并且仅仅只有5个中断源,而STM32f03C8T6共48个引脚,并且其定时器有PWM输出模式,可以更加方便的控制蜂鸣器的发音。

本次设计包括了七个按键,数码管,蜂鸣器,因此至少需要17个I/O口。

因此先比较而言选用I/O口较多的STM32f03C8T6来作为控制芯片。

四、系统设计

4.1硬件结构设计

如图4-1所示,硬件系统主要由数码管显示电路、蜂鸣器驱动电路、按键电路、晶振、复位、电源指示、转压电路、控制芯片等组成。

图4-1硬件系统图

4.1.1核心控制器硬件电路

核心控制芯片的各个输出引脚如图4-2所示:

图4-2STM32f103C8T6引脚图

核心控制器是由核心控制芯片以及相关的外围电路组成,包括了专业电路、外部晶振、滤波电路、按键复位电路、电源指示电路等,如图4-3所示。

图4-3核心控制器外围电路

4.1.2蜂鸣器驱动电路

此次设计选用有源蜂鸣器。

有源蜂鸣器的发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发音,因此需要一定的电流才能驱动它。

单片机的I/O引脚的输出电流比较小输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路,如图4-4所示,选用NPN的三极管来达到电流放大的作用。

图4-4蜂鸣器驱动电路

4.1.3数码管电路:

设计中需要使用一位数码管,如图4-5所示,为四位数码管的驱动电路,在实际的运用中仅仅选用了com4位选端口以及5、6、7、8、9、10、11、接口作为段选。

图4-5数码管显示电路

4.1.4按键电路:

按键都采用了上拉电阻,当按键处于不被按下的状态时,连接到单片机的一端的输入信号为高电平,当按键按下时,输入为低电平,如图4-6所示。

图4-6按键电路

4.2软件系统设计

4.2.1软件系统框图

设计选用STM32F103C8T6芯片,相关的配置主要包括:

,时钟配置、I/O口配置、定时器配置。

主函数中进行显示参数以及PWM输出频率的改变,具体流程图如图4-7所示。

图4-7软件流程图

4.2.2数码管显示相关段选计算:

在此次设计中选用的是共阴极的数码管,段选为高电平有效,位选为低电平有效。

选用STM32f103C8T6的PB0、1、2、.10、11、12、13、14作为段选位,分别对应数码管的h、g、f、e、d、c、b、a段,PB15对应数码管的位选。

图4-8一位数码管

当数码管显示0时,选用a、b、c、d、e、f、.段,对应的十六进制为:

0x7c04;

当数码管显示1时,选用b.、c.段,对应的十六进制为:

0x7c04;

当数码管显示2时,选用a、b、g、e、d.段,对应的十六进制为:

0x7c04;

当数码管显示3时,选用a、b、g、c、d.段,对应的十六进制为:

0x7c04;

当数码管显示4时,选用f、g、b、c.段,对应的十六进制为:

0x7c04;

当数码管显示5时,选用a、f、g、c、d段,对应的十六进制为:

0x7c04;

当数码管显示6时,选a、f、e、g、d、c.段,对应的十六进制为:

0x7c04;

当数码管显示7时,选用a、b、c.段,对应的十六进制为:

0x7c04;

4.2.3蜂鸣器发音音调改变原理

蜂鸣器分为有源蜂鸣器合无源蜂鸣器。

有源蜂鸣器内部带震荡源,所以只要一通电就会叫,价格比无源贵。

无源蜂鸣器必须用2K-5K的方波去驱动它。

此次设计选用有源蜂鸣器。

有源蜂鸣器的发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发音,因此需要一定的电流才能驱动它。

单片机的I/O引脚的输出电流比较小输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。

如图4-4所示蜂鸣器的正极接到VCC(+5V)电源上面,蜂鸣器的负极接到三极管的发射极E,三极管的基级B经过限流电阻R1后由单片机引脚控制,当单片机引脚输出高电平时,三极管T1截止,没有电流流过线圈,蜂鸣器不发声;当单片机引脚输出低电平时,三极管导通,这样蜂鸣器的电流形成回路,发出声音。

因此,我们可以通过程序控制引脚的电平来使蜂鸣器发出声音和关闭。

蜂鸣器是的音调改变实际上是通过改变驱动蜂鸣的高低电平的翻转频率来决定,高低电平的变化的频率不同,音调不同,在此次设计中采用TIM1的PWM的频率变化来控制。

4.2.4PWM输出频率计算:

TIM定时器相关配置:

voidTIM_yingyue(unsignedintNoteSet)

{

staticunsignedcharIfIsInit=0;

if(IfIsInit==0)

{

TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;

TIM_OCInitTypeDefTIM_OCInitStructure;

TIM_TimeBaseStructure.TIM_Period=NoteSet;

TIM_TimeBaseStructure.TIM_Prescaler=0;

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);

/*PWM1Modeconfiguration:

Channel4*/

TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;

TIM_OCInitStructure.TIM_Pulse=NoteSet/2;

TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;

TIM_OC1Init(TIM1,&TIM_OCInitStructure);

TIM_CtrlPWMOutputs(TIM1,ENABLE);

TIM_Cmd(TIM1,ENABLE);

IfIsInit=1;

}

else

{

TIM1->ARR=NoteSet;

TIM1->CCR1=NoteSet/2;

}

}

TIM_Period设置了在下一个更新事件装入活动的自动重装载寄存器周期的值。

TIM_Prescaler:

设置了用来作为TIM1时钟频率除数的预分频值。

TIM_CounterMode选择了计数器模式为向上计数模式。

TIM_OCMode选择定时器模式为TIM脉冲宽度调制模式1。

.TIM_OutputState=TIM_OutputState_Enable定时器输出比较状态使能。

TIM_Pulse设置了待装入捕获比较寄存器的脉冲值和TIM_Period的值一起决定占空比。

TIM_OCPolarity设置了输出比较极性为高。

根据以上设置

(4-1)

(4-2)

在主函数中,通过扫描按键的状态来执行相关操作:

if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==0)

{

display

(1);//数码管显示函数

TIM_yingyue(D1);//调用定时器函数

}

注:

每次调用TIM_yingyue()函数,通过判断IfIsInit的状态,直接通过修改ARR(自动重装载寄存器),CCR1(TIM1捕获/比较寄存器1)来修改频率,提高了程序的效率,避免其他相关值重复定义。

五、设计结果及分析

5.1设计结果:

实现了简易电子琴功能。

按下不同按键,发出不同1、2、3、4、5、6、7七个音符并用LED显示当前的键值。

每个音符发音的长短由按键按下的时间长短来控制,能够更好的完成一首歌曲。

PWM输出波形下列各图所示:

DO:

图5-1DoPWM输出波形

Rai:

图5-2RaiPWM输出波形

Mi:

图5-3MiPWM输出波形

Fa:

图5-4FaPWM输出波形

So:

图5-5SoPWM输出波形

La:

图5-6LaPWM输出波形

Xi:

图5-7XiPWM输出波形

5.2结果分析:

初次软硬件联调的时候,蜂鸣器发出的音符虽然也是七个调,但是声音明显不清脆。

结合软件分析,当时的TIM_yingyue()函数里面有很多关于定时器和PWM的参数的定义,改变频率只与其中两个寄存器有关系,而每次调用这个函数的时候会把整个函数中德参数全部重新赋值,导致了执行效率不高,对TIM_yingyue()函数进行修改,通过判断IfIsInit的状态,直接修改ARR(自动重装载寄存器),CCR1(TIM1捕获/比较寄存器1)来到到改变频率的效果,提高了程序的效率,避免其他相关值重复定义。

再次进行联调时,整个声音也就清楚了很多。

在按键的扫描方面放弃最初开始想要使用的外部中断触发的方式,一方面是为了能够更加简单的完成此次设计,另一方面是为了实现发音的长短可以用按键按下的时间长短来决定,使之更加具备电子琴的功能,能够很好的完成一首曲子。

结束语

通过本次专业方向设计,我不仅加深了对单片机理论的理解,将理论很好地应用到实际当中去,而且我还学会了如何去培养我们的创新精神,从而不断地战胜自己,超越自己。

创新可以是在原有的基础上进行改进,使之功能不断完善,成为真己的东西。

这个设计过程中,通过在原有的按键中断的基础上进行了改进,使之具备了电子琴的基本功能。

设计结果能够符合题意,成功完成了此次实习要求,我不只在乎这一结果,更加在乎的,是这个过程。

这个过程中,自己更加注重了一些基础的理知识的学习,很好的把平时课堂上的知识运用到了实际的操作中。

同时,软硬件的结合调试也让自己明白了理论上的很多东西也是需要实际实验的验证的。

本综合设计是让得到一次进行独立设计的工程实践锻炼,不仅培养严谨的科学态度和扎实的实践技能、良好的工程意识,并在设计中学会如何发现、分析和解决工程实践问题的技能和方法,为后续的毕业设计做好准备。

同时在这里也感谢在整个设计中帮助过我的老师和同学们。

参考文献

[1]冯建华,赵亮.单片机应用系统设计与产品开发[M].北京:

人民邮电出版社2004

[2]谭浩强.C语言程序设计[M].北京:

清华大学出版社1999

[3]吴国经等单片机应用技术中国电力出版社,2004.1

[4]李全利,迟荣强编著单片机原理及接口技术高等教育出版社,2004.1

[5]张毅刚等,MCS-51单片机应用设计,哈工大出版社,2004年第2版

[6]霍孟友等,单片机原理与应用,机械工业出版社,2004.1

[7]霍孟友等,单片机原理与应用学习概要及题解,机械工业出版社,2005.3

[8]许泳龙等,单片机原理及应用,机械工业出版社,2005.1

附录(程序、电路图等)

附录1:

程序代码

#include"stm32f10x.h"

unsignedinti=0;

unsignedintj=0;

unsignedintmykey=0;

unsignedlongcode[10]={0x7c04,0x3000,0x6c02,0x7802,0x3006,0x5806,0x5c06,0x7000,0x7c06

0x7806};

//数组里面的16进制正好对应着显示0-9的二进制码(数码管的位选,选择哪一位就让相关位为1,来表示选择了它)

#defineD155042

#defineD249037

#defineD343687

#defineD441235

#defineD536735

#defineD632728

#defineD729157

voidRCC_Configuration(void)

{

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO

|RCC_APB2Periph_TIM1|RCC_APB2Periph_GPIOB,ENABLE);//APB2时钟是72MHz的,APB1的时钟是36MHz的

}

voidGPIO_Configuration(void)

{

GPIO_InitTypeDefGPIO_InitStructure;//蜂鸣器

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;//选择PA8

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用功能,PA8作为复用是TIM1的PWM1的输出端口,不再作为一个普通的I/O口使用

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_5|GPIO_Pin_4|GPIO_Pin_15;

//按键的几个输入引脚

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;//上拉输入

GPIO_Init(GPIOB,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=0x7C07;//数码管段选and位选

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出

GPIO_Init(GPIOB,&GPIO_InitStructure);//表示选择的是PB的引脚

}

voidTIM_yingyue(unsignedintNoteSet)

{

staticunsignedcharIfIsInit=0;

if(IfIsInit==0)

{

TIM_TimeBaseInitTypeDefTIM_TimeBaseStructure;

TIM_OCInitTypeDefTIM_OCInitStructure;

/*Timebaseconfiguration*/

TIM_TimeBaseStructure.TIM_Period=NoteSet;//设置了在下一个更新事件装入活动的自动重装载//寄存器周期的值

TIM_TimeBaseStructure.TIM_Prescaler=0;//设置了用来作为TIM1时钟频率除数的预分频值

TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//选择了计数器模式为向上计数模式

TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);

/*PWM1Modeconfiguration:

Channel4*/

TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM1;//选择定时器模式为TIM脉冲宽度调制模式1

TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;//定时器输出比较状态使能

TIM_OCInitStructure.TIM_Pulse=NoteSet/2;//设置了待装入捕获比较寄存器的脉冲值和TIM_Period的值一起决定占空比

TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;//设置了输出比较极性为高

TIM_OC1Init(TIM1,&TIM_OCInitStructure);

TIM_CtrlPWMOutputs(TIM1,ENABLE);//TIM1的PWM输出使能

TIM_Cmd(TIM1,ENABLE);//Tim1定时器使能

IfIsInit=1;

}

else

{

TIM1->ARR=NoteSet;//改变输出的频率

TIM1->CCR1=NoteSet/2;

}

}

voiddelay(unsignedinti)//延时函数

{

unsignedintj,k;

for(j=0;j

for(k=0;k<100;k++);

}

voiddisplay(unsignedintj)//数码管显示函数

{

GPIO_SetBits(GPIOB,code[j]);

GPIO_ResetBits(GPIOB,0x001);//共阴极数码管,段选为高电平有效,位选为低电平有效

}

intmain()

{

RCC_Configuration();

GPIO_Configuration();

while

(1)//按键扫描

{

if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_15)==0)

{

display

(1);//修改显示的数据

TIM_yingyue(D1);//修改输出的频率

}

elseif(GPIO_ReadInputDataBit(GPIOB,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2