功能:
0.本项目采用STC89C52作为单片机系统的控制MCU
1.LCD1602液晶实时显示时间和当前工作模式
2.支持电子琴模式和歌曲模式(内置8首歌曲)
3.短触’设置/切换’键可切换工作模式
4.长按’设置/切换‘键可进入时间设置模式
5.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
//
//51单片机音乐播放器程序
//STC89C52+11.0592MHz+无源蜂鸣器
//共三个按键:上一曲、一下曲、播放\暂停
//注意:按键必须按下约1S才有相应动作,播放完一首歌曲无按键按下时顺序播放
//
#include <REG52.H>
#include <stdio.h>
#include "delay.h"
#include "lcd1602.h"
#include "ds1302.h"
#define MUSIC_AMOUNT 8 //歌曲的数量
sbit SPEAKER = P3^2; //无源蜂鸣器
sbit KEY_PAUSE = P1^5;
sbit KEY_SET = P2^7;
sbit KEY_PREVIOUS = P1^2;
sbit KEY_NEXT = P1^3;
//
unsigned char beatTime = 0; //T0RH,T0RL为定时器T0的高低位初值,g_beatTime为对应的节拍时间
char musicNum = 0; //g_musicNum为歌曲编号,musicNum=0表示刚开机时的状态,g_noteCnt是查找歌曲数据表的地址
unsigned int noteCnt;
signed int g_fre; //对应频率数据表的地址
bit playEnFlag = 1; //歌曲播放的使能标志位,用于播放\暂停
unsigned char keyValue;
unsigned char dispRow0[] = " / / ";
unsigned char dispRow1[] = " : ";
bit dispSongFlag = 1;
bit dispTimeFlag = 1;
bit setTimeFlag = 0;
unsigned char setLocation = 0;
void SetTime();
void DispTime();
void KeyScan(); //按键处理
void DelayOfBeat(unsigned char t); //延时子函数,控制发音的时间长度
void PlayOneNote(void); //演奏一个音符
void PlayMusic(void); //播放歌曲
void DispMusic(void);
void Timer0_Init();
void Timer1_Init();
//
//每三个数字,代表一个音符
//第一个数字是音符的数值1234567之一(第几个音),代表哆来咪发...
//第二个数字是0123之一,代表低音\中音\高音\超高音(第几个八度)
//第三个数字是时间长度,以半拍为单位,乐曲数据表的结尾是三个0
//
//《烟花易冷》
unsigned char code song1[]={
5,2,1, 3,2,1, 2,2,2, 2,2,4, 3,2,1, 1,2,1, 2,2,1, 3,2,4,
5,2,1, 3,2,1, 2,2,2, 2,2,2, 5,1,1, 3,2,1, 4,2,1, 3,2,4,
3,2,1, 3,2,1, 7,2,1, 3,2,1, 2,2,2, 1,2,1, 7,1,1, 1,2,1,
2,2,1, 3,2,1, 6,2,3, 6,1,1, 1,2,1, 3,2,1, 2,2,1, 6,1,1,
1,2,1, 7,1,1, 5,1,1, 6,1,6, 5,2,1, 3,2,1, 2,2,2, 2,2,1,
2,2,1, 3,2,1, 1,2,1, 2,2,1, 3,2,4, 5,2,1, 3,2,1, 2,2,2,
2,2,1, 2,2,1, 5,1,1, 3,2,1, 4,2,1, 3,2,4, 3,2,1, 3,2,1,
7,2,3, 3,2,1, 2,2,2, 1,2,1, 7,1,1, 1,2,1, 2,2,1, 3,2,1,
6,2,3, 6,1,1, 1,2,1, 3,2,1, 2,2,1, 6,1,1, 1,2,1, 7,1,2,
5,1,2, 6,1,6, 0,0,0 };
//《发如雪》
unsigned char code song2[]={
5,1,1, 2,2,1, 3,2,2, 2,2,1, 3,2,1, 5,2,1, 6,2,1, 5,2,3, 1,2,1, 2,2,1,
3,2,1, 6,2,1, 5,2,1, 3,2,1, 5,2,3, 5,2,1, 6,2,1, 1,3,2, 6,2,1, 5,2,1,
3,2,1, 5,2,1, 3,2,2, 1,2,1, 2,2,1, 3,2,1, 1,2,1, 6,1,1, 3,2,1, 2,2,1,
5,1,1, 2,2,1, 3,2,2, 2,2,1, 3,2,1, 5,2,1, 6,2,1, 5,2,3, 1,2,1, 2,2,1,
3,2,1, 6,2,1, 5,2,3, 5,2,1, 6,2,1, 1,3,2, 6,2,1,
5,2,1, 3,2,1, 5,2,1, 3,2,2, 1,2,1, 6,1,1, 3,2,1, 2,2,1, 1,2,1, 6,1,1,
1,2,1, 2,2,1, 2,2,1, 1,2,4, 0,0,0 };
//《简单爱》
unsigned char code song3[]={
5,1,1, 1,2,1, 2,2,1, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1,
4,2,1, 3,2,1, 2,2,3, 5,1,1, 1,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1,
5,2,1, 6,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 1,2,1, 6,1,1, 2,2,1, 2,2,1,
3,2,1, 3,2,1, 1,2,1, 5,2,1, 1,2,1, 5,2,1, 1,2,1, 7,1,1, 1,2,1, 1,2,1, 6,1,1,
2,2,1, 2,2,1, 3,2,1, 3,2,1, 5,2,1, 5,2,1,
5,2,1, 6,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2,
5,1,1, 1,2,1, 2,1,2, 3,2,1, 2,2,1, 3,2,1, 4,2,1, 5,2,1, 5,2,1, 5,2,1,
4,2,1, 3,2,1, 2,2,3, 5,1,1, 1,2,1, 2,2,1, 3,2,1, 2,2,1, 3,2,1, 4,2,1,
5,2,1, 5,2,1, 5,2,2, 2,2,1, 3,2,1, 1,2,2, 1,2,1, 6,1,1, 2,2,1, 2,2,1,
3,2,1, 3,2,1, 1,2,2, 5,2,1, 1,2,1, 5,2,1, 5,2,1, 7,1,1, 1,2,1, 0,0,0 };
//《世上只有妈妈好》
unsigned char code song4[]={
6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1,
//6,2,3代表6,中音,3个半拍;
//5,2,1代表5,中音,1个半拍;
//3,2,2代表3,中音,2个半拍;
//5,2,2代表5,中音,2个半拍;
//1,3,2代表1,高音,2个半拍;
//...
5,2,1,6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,6,1,1, 5,2,1,
3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2, 5,2,1, 6,2,1, 3,2,2, 2,2,2,
1,2,4, 5,2,3, 3,2,1,2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0};
//《当你孤单你会想起谁》
unsigned char code song5[]={
3,2,2, 3,2,1, 4,2,1, 3,2,2, 2,2,1, 1,2,1, 2,2,2, 5,2,2, 2,2,2, 2,2,3,
1,2,2, 1,2,1, 2,2,1, 1,2,2, 7,1,1, 6,1,1, 7,1,2, 3,2,2, 7,1,2, 7,1,3,
6,1,2, 2,2,1, 3,2,1, 2,2,1, 1,2,1, 6,1,2, 5,1,2, 2,2,1, 3,2,1, 2,2,1,
1,2,1, 6,1,2, 6,1,2, 2,2,1, 3,2,1, 2,2,1, 1,2,1, 6,1,1, 7,1,1, 1,2,6, 0,0,0 };
//《乡间小路》
unsigned char code song6[]={
3,1,2, 3,1,1, 3,1,1, 6,0,1, 6,0,1, 1,1,2,
6,0,1, 5,0,1, 6,0,4, 6,0,2, 6,0,1 ,6,0,1, 6,0,2, 6,0,1, 1,1,1,
2,1,2, 2,1,1, 3,1,1, 2,1,4, 3,1,1, 3,1,1, 3,1,1, 2,1,1, 4,1,2,
4,1,2, 3,1,2, 2,1,1, 1,1,1, 2,1,4, 7,0,1, 7,0,1, 7,0,1, 6,0,1,
5,0,1, 5,0,1, 6,0,1, 7,0,1, 7,0,1, 6,0,1, 5,0,1, 6,0,4, 6,1,2,
3,1,1, 6,1,1, 7,1,1, 6,1,1, 5,1,1, 5,1,2, 5,1,1, 2,1,1, 5,1,1,
6,1,1, 5,1,1, 4,1,1, 4,1,2, 4,1,1, 3,1,1, 2,1,2, 1,1,1, 2,1,1,
3,1,1, 2,1,1, 1,1,1, 2,1,1, 3,1,4, 6,1,2, 3,1,1, 6,1,1, 7,1,1,
6,1,1, 5,1,1, 5,1,2, 2,1,1, 5,1,1, 6,1,1, 5,1,1, 4,1,1, 0,0,0};
//《送别》
unsigned char code song7[]={
5,1,2, 3,1,3, 5,1,1, 1,2,3, 6,1,2, 1,2,2,
5,1,4, 5,1,2, 1,1,1, 2,1,1, 3,1,2, 2,1,1, 1,1,1, 2,1,4, 5,1,2,
3,1,1, 5,1,1, 1,2,2, 7,1,1, 6,1,2, 1,2,2, 5,1,4, 5,1,2, 2,1,1,
3,1,1, 4,1,2, 7,0,1, 1,1,4, 6,1,2, 1,2,2, 1,2,4, 7,1,2, 6,1,1,
7,1,1, 1,2,4, 6,1,1, 7,1,1, 1,2,1, 6,1,1, 6,1,1, 5,1,1, 3,1,1,
1,1,1, 2,1,8, 5,1,2, 3,1,1, 5,1,1, 1,2,2, 7,1,1, 6,1,2, 1,2,2,
5,1,4, 5,1,2, 2,1,1, 3,1,1, 4,1,2, 7,0,2, 1,1,4, 0,0,0};
//《最浪漫的事》
unsigned char code song8[]={
5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 3,1,1, 5,1,5,
5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1, 6,1,1, 1,1,5,
1,1,1, 2,1,1, 3,1,1, 2,1,1, 2,1,1, 2,1,1, 1,1,1, 2,1,1, 1,1,1, 6,1,1,
3,1,2, 2,1,3, 5,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 5,1,1, 6,1,1, 5,1,1,
6,1,1, 1,1,5, 1,1,1, 2,1,1, 3,1,1, 4,1,2, 4,1,1, 5,1,1, 6,1,1, 6,1,1,
5,1,1, 6,1,2, 1,2,1, 6,1,3, 1,2,1, 6,1,1, 5,1,1, 5,1,4, 1,1,1, 6,1,1,
5,1,5, 5,1,1, 6,1,1, 1,2,1, 3,1,1, 2,1,1, 3,1,1, 1,1,6, 0,0,0};
// 频率-半周期数据表 高八位 共保存了四个八度的28个频率数据
unsigned char code FREQH[]={
0xF2, 0xF3, 0xF5, 0xF5, 0xF6, 0xF7, 0xF8, //低音1234567
0xF9, 0xF9, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFC,//1,2,3,4,5,6,7,i
0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, //高音 234567
0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF}; //超高音 1234567
// 频率-半周期数据表 低八位
unsigned char code FREQL[]={
0x42, 0xC1, 0x17, 0xB6, 0xD0, 0xD1, 0xB6, //低音1234567
0x21, 0xE1, 0x8C, 0xD8, 0x68, 0xE9, 0x5B, 0x8F, //1,2,3,4,5,6,7,i
0xEE, 0x44, 0x6B, 0xB4, 0xF4, 0x2D, //高音 234567
0x47, 0x77, 0xA2, 0xB6, 0xDA, 0xFA, 0x16}; //超高音 1234567
void main(void)
{
Timer0_Init();
Timer1_Init();
DS1302_Init();
// DS1302_Write_Time();
LCD_Init();
DelayMs(10);
LCD_Clear();
LCD_DispStr(0, 0, " MusicBox ");
DelayS(2);
LCD_Clear();
while (1)
{
if (setTimeFlag == 1)
{
SetTime();
}
else
{
DS1302_Read_Time();
PlayMusic(); //根据当前状态播放相应歌曲的某个音符
if (dispSongFlag == 1)
{
DispMusic();
dispSongFlag = 0;
}
}
if (dispTimeFlag == 1) //每200ms刷新一次屏幕
{
DispTime();
dispTimeFlag = 0;
}
KeyScan();
}
}
void DelayOfBeat(unsigned char t) //延时子函数,控制发音的时间长度,每个节拍0.4S
{
unsigned char t1;
unsigned long t2;
for (t1 = 0; t1 < t; t1++) //嵌套循环, 共延时t个半拍
{
for (t2 = 0; t2 < 8000; t2++) //延时期间, 可进入T0中断去发音
{
;
}
}
TR0 = 0; //关闭T0, 停止发音
}
void PlayOneNote(void) //演奏一个音符
{
TH0 = FREQH[g_fre]; //下次的中断时间,这个时间控制音调高低
TL0 = FREQL[g_fre];
TR0 = 1; //启动T0, 由T0输出方波发音
DelayOfBeat(beatTime); //每个音符的演奏时间
}
void PlayMusic(void) //播放相应歌曲的某个音符
{
if (musicNum == 0)
{
beatTime = 0;
PlayOneNote(); //发出一个音符
}
if ((musicNum == 1) && (playEnFlag == 1))
{
g_fre = song1[noteCnt] + 7 * song1[noteCnt + 1] - 1; //第i个是音符,第i+1个是第几个八度
beatTime = song1[noteCnt + 2]; //读出时间长度数值
noteCnt += 3;
if (g_fre < 0) //判断歌曲的结束位,结束后转到下一首
{
noteCnt = 0; //下一首从头播放
musicNum = 2;
}
PlayOneNote(); //发出一个音符
}
if ((musicNum == 2) && (playEnFlag == 1))
{
g_fre = song2[noteCnt] + 7 * song2[noteCnt + 1] - 1;
beatTime = song2[noteCnt + 2];
noteCnt += 3;
if (g_fre < 0)
{
noteCnt = 0;
musicNum = 3;
}
PlayOneNote();
}
if ((musicNum == 3) && (playEnFlag == 1))
{
g_fre = song3[noteCnt] + 7 * song3[noteCnt + 1] - 1;
beatTime = song3[noteCnt + 2];
noteCnt += 3;
if (g_fre < 0)
{
noteCnt = 0;
musicNum = 4;
}
PlayOneNote();
}
if ((musicNum == 4) && (playEnFlag == 1))
{
g_fre = song4[noteCnt] + 7 * song4[noteCnt + 1] - 1;
beatTime = song4[noteCnt + 2];
noteCnt += 3;
if (g_fre < 0)
{
noteCnt = 0;
musicNum = 5;
}
PlayOneNote();
}
if ((musicNum == 5) && (playEnFlag == 1))
{
g_fre = song5[noteCnt] + 7 * song5[noteCnt + 1] - 1;
beatTime = song5[noteCnt + 2];
noteCnt += 3;
if (g_fre < 0)
{
noteCnt = 0;
musicNum = 6;
}
PlayOneNote();
}
if ((musicNum == 6) && (playEnFlag == 1))
{
g_fre = song6[noteCnt] + 7 * song6[noteCnt + 1] - 1;
beatTime = song6[noteCnt + 2];
noteCnt += 3;
if (g_fre < 0)
{
noteCnt = 0;
musicNum = 7;
}
PlayOneNote();
}
if ((musicNum == 7) && (playEnFlag == 1))
{
g_fre = song7[noteCnt] + 7 * song7[noteCnt + 1] - 1;
beatTime = song7[noteCnt + 2];
noteCnt += 3;
if (g_fre < 0)
{
noteCnt = 0;
musicNum = 8;
}
PlayOneNote();
}
if ((musicNum == 8) && (playEnFlag == 1))
{
g_fre = song8[noteCnt] + 7 * song8[noteCnt + 1] - 1;
beatTime = song8[noteCnt + 2];
noteCnt += 3;
if (g_fre < 0)
{
noteCnt = 0;
musicNum = 1;
}
PlayOneNote();
}
}
void KeyScan() //矩阵按键程序
{
static unsigned char keyIdle = 0;
static unsigned char keyBuf;
static unsigned char cnt = 0;
keyValue = 20; //按键值还原
P2 = 0x0f;
if ((P2 & 0x0f) != 0x0f) //按键按下
{
DelayMs(1); //按键消抖动
if (((P2 & 0x0f) != 0x0f) && (keyIdle == 1))
{ //确认是按键按下
keyIdle = 0;
keyBuf = (P2 | 0xf0); //矩阵键盘扫描
P2 = keyBuf;
if (setTimeFlag == 1)
{
switch (P2)
{
case 0xee:
switch (setLocation)
{
case 1:
{
if (timeBufDec[1] == 0)
{
timeBufDec[1] = 100;
}
timeBufDec[1]--;
break;
}
case 2:
{
timeBufDec[2]--;
if (timeBufDec[2] < 1)
{
timeBufDec[2] = 12;
}
break;
}
case 3:
{
timeBufDec[3]--;
if (timeBufDec[3] < 1)
{
timeBufDec[3] = YDay(timeBufDec[1], timeBufDec[2]);
}
break;
}
case 4:
{
if (timeBufDec[4] == 0)
{
timeBufDec[4] = 24;
}
timeBufDec[4]--;
break;
}
case 5:
{
if (timeBufDec[5] == 0)
{
timeBufDec[5] = 60;
}
timeBufDec[5]--;
break;
}
case 6:
{
timeBufDec[7]--;
if (timeBufDec[7] < 1)
{
timeBufDec[7] = 7;
}
break;
}
default:;
}
break;
case 0xde:
switch (setLocation)
{
case 1:
{
timeBufDec[1]++;
if (timeBufDec[1] >= 100)
{
timeBufDec[1] = 0;
}
break;
}
case 2:
{
timeBufDec[2]++;
if (timeBufDec[2] >= 13)
{
timeBufDec[2] = 1;
}
break;
}
case 3:
{
timeBufDec[3]++;
if (timeBufDec[3] >= YDay(timeBufDec[1], timeBufDec[2]) + 1)
{
timeBufDec[3] = 1;
}
break;
}
case 4:
{
timeBufDec[4]++;
if (timeBufDec[4] >= 24)
{
timeBufDec[4] = 0;
}
break;
}
case 5:
{
timeBufDec[5]++;
if (timeBufDec[5] >= 60)
{
timeBufDec[5] = 0;
}
break;
}
case 6:
{
timeBufDec[7]++;
if (timeBufDec[7] > 7)
{
timeBufDec[7] = 1;
}
break;
}
default:;
}
break;
case 0xbe:
setLocation = 7; //确定键
break;
default:;
}
}
else
{
if (musicNum == 0)
{
dispTimeFlag = 0;
switch (P2)
{
case 0xee:
keyValue = 0;
g_fre = 8;
TR0 = 1;
break; //得到按键值 //打开定时器
case 0xde:
keyValue = 1;
g_fre = 9;
TR0 = 1;
break; //得到按键值
case 0xbe:
keyValue = 2;
g_fre = 10;
TR0 = 1;
break; //得到按键值
case 0x7e:
keyValue = 3;
g_fre = 11;
TR0 = 1;
break; //得到按键值
case 0xed:
keyValue = 4;
g_fre = 12;
TR0 = 1;
break; //得到按键值
case 0xdd:
keyValue = 5;
g_fre = 13;
TR0 = 1;
break; //得到按键值
case 0xbd:
keyValue = 6;
g_fre = 14;
TR0 = 1;
break; //得到按键值
case 0x7d:
keyValue = 7;
g_fre = 15;
TR0 = 1;
break; //得到按键值
case 0xeb:
keyValue = 8;
g_fre = 16;
TR0 = 1;
break; //得到按键值
case 0xdb:
keyValue = 9;
g_fre = 17;
TR0 = 1;
break; //得到按键值
case 0xbb:
keyValue = 10;
g_fre = 18;
TR0 = 1;
break; //得到按键值
case 0x7b:
keyValue = 11;
g_fre = 19;
TR0 = 1;
break; //得到按键值
case 0xe7:
keyValue = 12;
g_fre = 20;
TR0 = 1;
break; //得到按键值
case 0xd7:
keyValue = 13;
g_fre = 21;
TR0 = 1;
break; //得到按键值
case 0xb7:
keyValue = 14;
g_fre = 22;
TR0 = 1;
break; //得到按键值
case 0x77:
keyValue = 15;
g_fre = 23;
TR0 = 1;
break; //得到按键值
}
}
else
{
switch (P2)
{
case 0xee:
dispSongFlag = 1;
noteCnt = 0;
if (musicNum <= 1) //上一曲
{
musicNum = MUSIC_AMOUNT;
}
else
{
musicNum--;
}
break;
case 0xde:
dispSongFlag = 1;
noteCnt = 0;
if (musicNum >= MUSIC_AMOUNT) //下一曲
{
musicNum = 1;
}
else
{
musicNum++;
}
break;
case 0xbe:
playEnFlag = 1; //播放
break;
case 0x7e:
playEnFlag = 0; //暂停
TR0 = 0;
break;
}
}
}
while (P2 != 0x0f)
P2 = 0x0f;
TR0 = 0; //关闭定时器
}
}
else //按键松开
{
keyIdle = 1;
}
/*********************歌曲播放*********************/
KEY_SET = 1;
if (!KEY_SET)
{
DelayMs(10); //按键去抖动
while (!KEY_SET)
{
DelayMs(20);
cnt++;
if (cnt >= 75)
{
break;
}
}
if (cnt >= 50) //长按键处理
{
TR0 = 0;
setTimeFlag = 1;
setLocation++;
}
else
{
if (setTimeFlag)
{
setLocation++;
}
else
{
if (musicNum != 0)
{
dispSongFlag = 1;
musicNum = 0;
noteCnt = 0;
TR0 = 0;
}
else
{
dispSongFlag = 1;
musicNum = 1;
noteCnt = 0;
}
}
}
cnt = 0;
while (!KEY_SET);
}
}
void SetTime()
{
TR1 = 0;
LCD_WriteCommand(0x0F, 0); //打开闪烁
// LCD_WriteCommand(0x0C, 0);
switch (setLocation)
{
case 1: LCD_WriteCommand(0x80 + 1, 0); break;
case 2: LCD_WriteCommand(0x80 + 4, 0); break;
case 3: LCD_WriteCommand(0x80 + 7, 0); break;
case 4: LCD_WriteCommand(0x80 + 0x40 + 1, 0); break;
case 5: LCD_WriteCommand(0x80 + 0x40 + 4, 0); break;
case 6: LCD_WriteCommand(0x80 + 14, 0); break;
case 7:
{
LCD_WriteCommand(0x0C, 0);
LCD_WriteCommand(0x0C, 0);
DS1302_Write_Time();
setLocation = 0;
setTimeFlag = 0;
TR0 = 1;
break;
}
default: ;
}
TR1 = 1;
}
void DispTime()
{
dispRow0[0] = timeBufDec[1] / 10 +'0';
dispRow0[1] = timeBufDec[1] % 10 +'0';
dispRow0[3] = timeBufDec[2] / 10 +'0';
dispRow0[4] = timeBufDec[2] % 10 +'0';
dispRow0[6] = timeBufDec[3] / 10 +'0';
dispRow0[7] = timeBufDec[3] % 10 +'0';
dispRow1[0] = timeBufDec[4] / 10 +'0';
dispRow1[1] = timeBufDec[4] % 10 +'0';
dispRow1[3] = timeBufDec[5] / 10 +'0';
dispRow1[4] = timeBufDec[5] % 10 +'0';
// dispRow1[6] = timeBufDec[6] / 10 +'0';
// dispRow1[7] = timeBufDec[6] % 10 +'0';
LCD_DispStr(0, 0, dispRow0);
LCD_DispStr(0, 1, dispRow1);
switch (timeBufDec[7])
{
case 1: LCD_DispStr(10, 0, " Sun."); break;
case 2: LCD_DispStr(10, 0, " Mon."); break;
case 3: LCD_DispStr(10, 0, " Tue."); break;
case 4: LCD_DispStr(10, 0, " Wed."); break;
case 5: LCD_DispStr(10, 0, "Thur."); break;
case 6: LCD_DispStr(10, 0, " Fri."); break;
case 7: LCD_DispStr(10, 0, " Sat."); break;
default: LCD_DispStr(10, 0, " Sun.");;
}
}
void DispMusic()
{
unsigned char table[] = "Music ";
if (musicNum == 0)
{
LCD_DispStr(7, 1, "KeyBoard");
}
else
{
table[6] = musicNum / 10 + '0';
table[7] = musicNum % 10 + '0';
LCD_DispStr(7, 1, table);
}
}
void Timer0_Init()
{
TMOD &= 0xF0;
TMOD |= 0x01; //T0 T1 均在工作方式1
TR0 = 0;
ET0 = 1; //T0开中断
EA = 1; //CPU开中断
}
void Timer1_Init()
{
TMOD &= 0x0F;
TMOD |= 0x10; //T0 T1 均在工作方式1
TH1 = (65536 - 18432) / 256; //定时20ms
TL1 = (65536 - 18432) % 256;
TR1 = 1;
ET1 = 1; //T0开中断
EA = 1; //CPU开中断
}
void Timer0(void) interrupt 1 //T0中断程序,控制发音的音调
{
SPEAKER = !SPEAKER; //输出方波, 发音
TH0 = FREQH[g_fre]; //下次的中断时间,这个时间控制音调高低
TL0 = FREQL[g_fre];
}
void Timer1(void) interrupt 3 //T1中断程序
{
static unsigned char cnt = 0;
TH1 = (65536 - 18432) / 256; //定时20ms
TL1 = (65536 - 18432) % 256;
cnt++;
if (cnt >= 10)
{
dispTimeFlag = 1;
cnt = 0;
}
}
//程序结束
仿真演示视频:
https://www.bilibili.com/video/BV1Be4y1p7w4/文章来源:https://www.toymoban.com/news/detail-519869.html
实物演示视频:
https://www.bilibili.com/video/BV17P411u7MA/文章来源地址https://www.toymoban.com/news/detail-519869.html
到了这里,关于基于51单片机的16键电子琴音乐盒设计proteus仿真原理图程序的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!