当前位置:网站首页>简易电子琴设计(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; //熄灭
}
}
边栏推荐
猜你喜欢
LeetCode 622. Designing Circular Queues
mysql跨库关联查询(dblink)
Word另存为PDF后无导航栏解决办法
MySQL基础
虚拟机vmware设置桥接模式上网
开发即时通讯到底需要什么样的技术,需要多久的时间
Shell programming loop statement
Confused!Ali was abused on the one hand, but was fortunate to be promoted to Huawei's technology, and successfully got the offer, with an annual salary of 40w
MySQL【变量、流程控制与游标】
国产虚拟化云宏CNware WinStack安装体验-5 开启集群HA
随机推荐
ctfshow php features
分享即时通讯开发之WebSocket:概念、原理、易错常识、动手实践
Postgresql中的pg_memory_barrier_impl和C的volatile
MVC vs MVP
微信小程序分享功能
The effective square of the test (one question of the day 7/29)
When does MySQL use table locks and when to use row locks?You should know this
开源教育论坛| ChinaOSC
开发即时通讯到底需要什么样的技术,需要多久的时间
盘点在线帮助中心对企业能够起到的作用
Interview Blitz: What Are Sticky Packs and Half Packs?How to deal with it?
FreeRTOS Intermediate
Standard C language learning summary 11
力扣刷题之分数加减运算(每日一题7/27)
ECCV2022 | 用于视频问题回答的视频图Transformer
U-Net生物医学图像分割讲解(Convolutional Networks for BiomedicalImage Segmentation)
FreeRTOS中级篇
按需视觉识别:愿景和初步方案
Power button brush the topic of merging two orderly array
【QT】入门心法