当前位置:网站首页>简易电子琴设计(c语言)
简易电子琴设计(c语言)
2022-08-03 19:28:00 【@简单就好】
目录
1.1 矩阵键盘代表琴键,实现至少8个音的弹奏,分别为1,2,3,4,5,6,7,i.
1 设计内容:
1.1 矩阵键盘代表琴键,实现至少8个音的弹奏,分别为1,2,3,4,5,6,7,i.
1.2 键按下时间的长短代表节拍的长短
1.3 用蜂鸣器发出声音
1.4 8*8led点阵动态显示音符高低(自用显示)
2 系统硬件设计
2.1 硬件组成
本次设计简易电子琴,通过STC89C52芯片最小控制电路,以16位矩阵电盘,蜂鸣器产生16个音阶,8x8点阵led显示音符高低,独立按键控制复位。将不同模块结合起来,实现简易电子琴的设计。
硬件以ST89C52芯片为核心,外部扩展4x4矩阵式键盘来模拟16个按键,用蜂鸣器来发声,外部扩展8*8LED点阵来动态显示音符的简谱。
基本引荐结构图如图2所示。
图2
2.2 显示模块
点阵屏的8个行引脚与单片机的P0口相连并且接上拉电阻;而点阵的8个列引脚则直接与单片机的P2口相连。
显示模块的电路图如图2.1所示。
2.3 按键模块
16位矩阵键盘,通过P1口控制音阶的产生和led点阵显示,按下相应的的键产生设定的声音和点亮对应的led点阵屏,按键模块的电路图如图2.3所示。
图2.3
2.4 发音模块
使用无源蜂鸣器,通过内部程序产生不同频率的方波,使蜂鸣器产生16个基本的音阶,16个按键分别是中音和高音的Do,Re,Mi,Fa,So,La,Si,Do.蜂鸣器与P3^6相接,电路图如图2.4所示。
图2.4
3 系统主程序流程图
4 protues原理图
5 AD的pcb图
6 程序代码
#include <reg51.h>
#include<intrins.h>
#include<absacc.h>
//#define PA XBYTE[0xff7c]
//#define PB XBYTE[0xff7d]
//#define PC XBYTE[0xff7e]
#define CTRL XBYTE[0xff7f]
#define temp P1
#define uchar unsigned char
uchar code Table_of_Digits[] = { //8*8led点阵段码 ,1~f
0xFF,0xFF,0xF9,0xFB,0xFB,0xFB,0xF1,0xFF,/*"1",0*/
0xFF,0xFF,0xF8,0xFA,0xFD,0xFE,0xF8,0xFF,/*"2",1*/
0xFF,0xFF,0xF8,0xFB,0xFD,0xFB,0xF8,0xFF,/*"3",2*/
0xFF,0xFF,0xFB,0xF9,0xFA,0xF0,0xF1,0xFF,/*"4",3*/
0xFF,0xFF,0xF8,0xF8,0xFB,0xFB,0xF8,0xFF,/*"5",4*/
0xFF,0xFF,0xF9,0xF8,0xFA,0xFA,0xF8,0xFF,/*"6",5*/
0xFF,0xFF,0xF9,0xFB,0xFB,0xFB,0xFB,0xFF,/*"7",6*/
0xFF,0xFF,0xF8,0xFA,0xFD,0xFA,0xF8,0xFF,/*"8",7*/
0xFF,0xFF,0xF8,0xFA,0xF8,0xFB,0xFC,0xFF,/*"9",8*/
0xFF,0xFF,0xFF,0xF8,0xFB,0xF8,0xF0,0xFF,/*"a",0*/
0xFF,0xFD,0xFD,0xF9,0xF9,0xF9,0xF9,0xFF,/*"b",1*/
0xFF,0xFF,0xFF,0xF9,0xFE,0xFE,0xF8,0xFF,/*"c",2*/
0xFF,0xF9,0xFB,0xF8,0xFA,0xFA,0xF8,0xFF,/*"d",3*/
0xFF,0xFF,0xFF,0xF9,0xF9,0xF9,0xF9,0xFF,/*"e",4*/
0xFF,0xF9,0xFD,0xF8,0xFD,0xFD,0xF8,0xFF,/*"f",5*/
};
void delay(unsigned int z); //延时函数,参数为非负整型,延时1ms
void display( int yin) ; //led显示函数,参数为整型,
void function1 (void) ; //该函数用于主函数中的按键发音 和点阵显示
int keyscan(); //键盘扫描并返回键值
unsigned int pin[]={64580,64684,64777,64820,64898,64985,65030,65058,65110,65157,65178,65217,65252,65265,65283,65290};//16个音阶简谱码(T值)
unsigned int syin[16]={ 0}; //存储16音阶
sbit P36=P3^6; //beep蜂鸣器引脚
int yin,i;
unsigned poe; //用于存储按键扫描函数返回的键值
unsigned char key_num;
main() //???
{ EA=1; //总中断允许
TMOD=0x01; //定时器T0工作方式1
ET0=1; //T0中断允许
PT0=1; //T0为高级中断
CTRL=0x89;
while(1)
{
function1();
}
}
void function1 (void) //按键返回值存储,长按发音和显示
{ poe = keyscan(); //????????
switch(poe)
{
case 1:yin=1; //按键对应的音阶
break;
case 2:yin=2;
break;
case 3:yin=3;
break;
case 4:yin=4;
break;
case 5:yin=5;
break;
case 6:yin=6;
;break;
case 7:yin=7;
break;
case 8:yin=8;
break;
case 9:yin=9;
break;
case 10:yin=10;
break;
case 11:yin=11;
break;
case 12:yin=12;
break;
case 13:yin=13;
break;
case 14:yin=14;
;break;
case 15:yin=15;
break;
case 16:yin=16;
break;}
if(poe!=0xff) //按键按下
{ if (yin==1) {
TH0=pin[yin-1]/256; //寻找对应的简谱码给T0赋值,以获取相应的脉冲,蜂鸣器按照相应的频率发音
TL0=pin[yin-1]%256;
while(poe==1)
{
TR0=1; //定时器开始计数
poe = keyscan(); //用于不断扫描,判断键值是否还等于while小括号里面的值,如果等于,说明按键没有松开,则进入中断实现发音。
display(yin -1 );
}
TR0=0;
}
if (yin==2){
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==2)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==3) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==3)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==4) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==4)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==5) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==5)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==6) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==6)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==7) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==7)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==8) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==8)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==9) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==9)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==10) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==10)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==11) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==11)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==12) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==12)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==13) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==13)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==14) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==14)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==15) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==15)
{
TR0=1;
poe = keyscan();
display(yin -1 );
}
TR0=0;
}
if (yin==16) {
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
while(poe==16)
{
TR0=1;
poe = keyscan();
display(yin -1 );
// display(syin);
}
TR0=0;
}
for (i=15;i>0;i--)
syin[i]=syin[i-1];
syin[0]=yin;
} P36=1;
}
void delay(unsigned int z) //延时函数,延时1ms
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=125;y>0;y--);
}
void fasheng() interrupt 1 //T0 中断
{
TH0=pin[yin-1]/256;
TL0=pin[yin-1]%256;
P36=~P36; //P3^6引脚发出相应的脉冲信号驱动蜂鸣器发声
}
int keyscan() //矩阵键盘扫描函数,返回按键值num
{
uchar num;
temp=0xf0;
if(temp!=0xf0) //先将高四位全部置高电平,低四位全部置低电平,当高四位不全为高电平时,说明有按键按下,然后通过接受的数据值,判断是哪一列有按键按下
{
delay(10); //延时10ms消抖
if(temp!=0xf0)
{
temp=0xf0;
switch(temp)
{
case 0x70: num=1; break;
case 0xb0: num=5; break;
case 0xd0: num=9; break;
case 0xe0: num=13; break;
}
temp=0x0f;
switch(temp)
{
case 0x07: num=num+0; break;
case 0x0b: num=num+1; break;
case 0x0d: num=num+2; break;
case 0x0e: num=num+3; break;
}
}
else
num = 0xff;
}
return num;
}
void display(yin)
{
uchar i;
for(i = 0 ;i < 8;i++)
{
P0= i%8; //位值
P2 = Table_of_Digits[i+yin*8]; //段码
delay(1);
P2 = 0xff; //熄灭
}
}
边栏推荐
猜你喜欢
如何理解即时通讯开发移动网络的“弱”和“慢”
Word另存为PDF后无导航栏解决办法
系统太多,多账号互通如何实现?
ctfshow php features
Don't look down upon the WebSocket!Long connection, stateful, two-way, full-duplex king is Fried
Protobuf Grpc使用异常 类型有未导出的方法,并且是在不同的软件包中定义
怎么将自己新文章自动推送给自己的粉丝(巨简单,学不会来打我)
Teach you to locate online MySQL slow query problem hand by hand, package teaching package meeting
基于DMS的数仓智能运维服务,知多少?
揭秘5名运维如何轻松管理数亿级流量系统
随机推荐
盘点在线帮助中心对企业能够起到的作用
Matlab论文插图绘制模板第42期—气泡矩阵图(相关系数矩阵图)
设备树基本原理与操作方法
基础软件与开发语言开源论坛| ChinaOSC
丙二醇二乙酸酯(Propylene Glycol Diacetate)
Postgresql snapshot optimization Globalvis new system analysis (performance greatly enhanced)
面试突击:什么是粘包和半包?怎么解决?
盘点在线帮助中心对企业能够起到的作用
Introduction to Cosine Distance
Don't look down upon the WebSocket!Long connection, stateful, two-way, full-duplex king is Fried
LOL英雄联盟卡顿掉帧问题解决办法 2022年8月1日
微信小程序分享功能
梅科尔工作室-14天华为培训六
Shell编程之循环语句
go语言实现导出string字符串到文件中
云图说丨初识华为云微服务引擎CSE
Network protocol-TCP, UDP difference and TCP three-way handshake, four wave
Zhong Hua, senior architect of Ali: China-Taiwan strategic thinking and architecture practice; including internal implementation manual
Jingdong cloud released a new generation of distributed database StarDB 5.0
【C语言学习笔记(五)】while循环与for循环