調的八音電子琴 24c02存儲讀寫有問題 如何在Lcd12864顯示的時候 依然能彈 求大神幫忙
/**************************************************************
程序名稱:模擬電子琴
**************************************************************/
#include<reg52.h> //定義頭文件
#include"st7565.h"
#define uchar unsigned char //宏定義
#define keyss P0 //中間變量。
sbit buzzer=P2^4; //揚聲器管腳
sbit key1=P0^0;
sbit key2=P0^1;
sbit key3=P0^2;
sbit key4=P0^3;
sbit key5=P0^4;
sbit key6=P0^5;
sbit key7=P0^6;
sbit key8=P0^7;
sbit keybofang0=P3^4; //播放音樂與彈奏歌曲轉換
sbit keybofang1=P3^5; //播放剛才彈奏的歌曲
sbit keybofang2=P3^6; //播放掉電存儲的歌曲
sbit keybofang3=P3^7; //掉電存儲按鍵
sbit sda=P2^1; //24c02數據線
sbit scl=P2^0; //24c02時鐘線
uchar keyd,i,keys,b; //定義變量
uchar tone_H; //定義變量
uchar tone_L; //定義變量
void beat_125(unsigned char); //聲明函數
uchar code beat1[]={16,8,8,8,8,4,4,16,8,4,4,8,4,4,4, //歌曲1節拍
4,4,4,16,16,8,8,4,4,12,8,16,16,8,4,4,4,4,16};
uchar code song1[]={6,5,3,5,7,6,5,6,3,5,6,5,3, //歌曲1簡譜
2,1,6,5,3,2,2,3,5,5,6,3,2,1,5,3,2,1,6,1,1,15};
uchar code beat2[]={7,7,7, 7,8,9, 1,2,3, 6,2,4, 4,4,4, 12, //歌曲二節拍
8,2,2, 4,4,4, 8,2,2, 4,4,4, 2,2,4,4, 12,};
uchar code song2[]={1,2,8, 8,5,1, 3,3,3, 5,4,3, //歌曲二簡譜
5,4,3, 2, 2,1,0, 1,2,3, 4,3,2, 3,4,5, 5,4,3, 2,1,15};
uchar code beat4[]={4,4,4, 6,2,4, 4,4,4, 6,2,4, 4,4,4, 12,
8,2,2, 4,4,4, 8,2,2, 4,4,4, 2,2,4,4, 12,};
uchar code song4[]={1,1,1, 3,2,1, 3,3,3, 5,4,3,
5,4,3, 2, 2,1,0, 1,2,3, 4,3,2, 3,4,5, 5,4,3, 2,1, 15};
uchar code tone[]={115,102,91,86,77,68,61,57}; //歌曲音調
unsigned int code tone1[]={1012,956,852,759,716,638,568,506,478,426,379,531,10}; //歌曲音調
uchar song3[43]; //定義空數組
void play(uchar*,uchar*); //演奏歌曲函數
void delay8um(uchar); //第一8um延時函數
void sound(uchar); //彈奏發聲函數
void Delay10ms(unsigned int c);
void xianshi(unsigned int q);
/*******************************************
函數功能:節拍的延時的基本單位,用于24c08簡單延時
******************************************/
void delay() //簡單延時函數
{
;;
}
/*******************************************
函數功能:節拍的延時的基本單位,延時1ms
******************************************/
void delay1ms(uchar x) //1um延時函數
{
uchar j;
while(x--)
for(j=120;j>0;j--);
}
/**************************************************************
函數功能:24c02驅動程序 用IIC總線進行傳輸
**************************************************************/
void init_c02() //24c02初始化
{
sda=1;
delay();
scl=1;
delay();
}
void start_c02() //24c02的啟動信號
{
scl=1;
delay();
sda=1;
delay();
sda=0;
delay();
}
void stop_c02() //24c02停止信號
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void response_c02() //24c02的應答信號
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
void write_c02byte(uchar date) //對24c02寫一個字節
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_c02byte() //對24c02讀一個字節
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void write_addc02(uchar address,uchar date) //對24c02寫一個數據
{
start_c02();
write_c02byte(0xa0);
response_c02();
write_c02byte(address);
response_c02();
write_c02byte(date);
response_c02();
stop_c02();
}
uchar read_addc02(uchar address) //從24c02讀一個數據
{
uchar date;
start_c02();
write_c02byte(0xa0);
response_c02();
write_c02byte(address);
response_c02();
start_c02();
write_c02byte(0xa1);
response_c02();
date=read_c02byte();
// response_c02;
stop_c02();
return date;
}
/**************************************************************
函數功能:主函數。。。。。。。。。。。。
**************************************************************/
void main() //主函數
{
uchar yd,temp,jj,tt; //定義變量
uchar t1,i; //定義變量
t1=0; //初始化 t1
yd=0; //初始化t2
buzzer=1; //初始化蜂鳴器
init_c02();
EA=1; //打開定時總中斷
TMOD=0x01; //設置定時器模式 定時器0工作在方式1
ET0=1; //打開定時器0中斷
while(1) //主循環
{
keyss=0xff;
keys=~keyss;
xianshi(0);
switch(keys) //進入鍵盤選擇
{
case 0x01:sound(0);temp=1;yd=0;break; //如果鍵盤1被按下發音do,同時設置標志temp,將數字計入yd
case 0x02:sound(1);temp=1;yd=1;break; //如果鍵盤2被按下發音ruai,同時設置標志temp,將數字計入yd
case 0x04:sound(2);temp=1;yd=2;break; //如果鍵盤3被按下發音mi,同時設置標志temp,將數字計入yd
case 0x08:sound(3);temp=1;yd=3;break; //如果鍵盤4被按下發音fa,同時設置標志temp,將數字計入yd
case 0x10:sound(4);temp=1;yd=4;break; //如果鍵盤4被按下發音so,同時設置標志temp,將數字計入yd
case 0x20:sound(5);temp=1;yd=5;break; //如果鍵盤4被按下發音la,同時設置標志temp,將數字計入yd
case 0x40:sound(6);temp=1;yd=6;break; //如果鍵盤4被按下發音xi,同時設置標志temp,將數字計入yd
case 0x80:sound(7);temp=1;yd=7;break; //如果鍵盤4被按下發音do,同時設置標志temp,將數字計入yd
}
if(temp==1) //標志位,如果標志位為1,則說明有按鍵被按下
{
temp=0; //將標識位歸零
song3[t1++]=yd; //將數據存入song3[]數組
}
if(keybofang3==0) //將數據存入24c02 ,掉電存儲按鍵
{
delay1ms(10);
if(keybofang3==0) //檢測是否key3被按下
{
while(!keybofang3); //松手檢測
song3[t1++]=30;
start_c02(); //初始化24c02
for(i=0;i<40;) //進入循環
{
write_addc02(i,song3[i++]); //將數據依次寫入24c02
delay1ms(10); //延時
}
}
}
if(keybofang2==0) //讀取24c02中的數據,掉電播放
{
delay1ms(10);
if(keybofang2==0)
{ //檢測是否有鍵被按下
while(!keybofang2); //松手檢測
start_c02(); //初始化
tt=0; //將tt初值設為0
while(read_addc02(tt)!=30) //進入while循環
{
jj=read_addc02(tt++);
tone_H=(65536-tone1[jj])/256; //設定初值
tone_L=(65536-tone1[jj])%256; //設定初值
TH0=tone_H; //賦值TH0高八位
TL0=tone_L; //賦值TL0低八位
TR0=1;
delay1ms(10); //打開定時器
beat_125(3); //延時
TR0=0;
beat_125(4); //關閉定時器
}
}
}
if(keybofang1==0)
{
while(!keybofang1); //檢測回放鍵是否被按下
song3[t1++]=30;
t1=0;
while(song3[i]!=30) //進入while循環。
{
tone_H=(65536-tone1[song3[i]])/256;
tone_L=(65536-tone1[song3[i]])%256;
TH0=tone_H;
TL0=tone_L;
TR0=1; //開啟定時器
beat_125(3);
TR0=0; //關閉定時器
i++;
beat_125(4); //將i值加一
}
}
if(keybofang0==0)
{
delay1ms(10);
if(keybofang0==0) //檢測keybofang0是否被按下
{
while(!keybofang0);
while(keybofang0) //進入循環
{
if(key1==0) //檢測key1是否被按下
{
delay1ms(10);
if(key1==0)
{
while(!key1); //等待釋放
play(song1,beat1); //演奏歌曲1
}
}
if(key2==0) //檢測是否key2鍵被按下
{
delay1ms(10);
if(key2==0)
{
while(!key1); //松手檢測
play(song2,beat2); //播放歌曲2
}
}
if(key3==0) //檢測是否key3鍵被按下
{
delay1ms(10);
if(key3==0)
{
while(!key3); //松手檢測
play(song4,beat4); //播放歌曲4
}
}
}
while(!keybofang0); //檢測key1是否被按下
P0=1;
}
}
}
}
/**************************************************************
函數功能:從數組中播放歌曲
**************************************************************/
void play(uchar*song,uchar*beat) //播放歌曲函數
{
i=0; //設置初始值
while(song[i]!=15) // 進入循環函數
{
tone_H=(65536-tone1[song[i]])/256; //定義初值
tone_L=(65536-tone1[song[i]])%256; //定義初值
TH0=tone_H; //賦值
TL0=tone_L; //賦值
TR0=1; //打開定時器0
beat_125(beat[i]); //讀取節拍函數
i++; //自加
TR0=0; //關閉led
}
}
/**************************************************************
函數功能:定時器T0的中斷服務子程序,使P2.7引腳輸出音頻方波
**************************************************************/
void tone_timer() interrupt 1 //中斷子程序
{
TH0=tone_H;
TL0=tone_L;
buzzer=~buzzer; //揚聲器開關控制
}
/**************************************************************
函數功能:產生節拍的函數
**************************************************************/
void beat_125(uchar x) //節拍。。
{
uchar i,j,k; //125ms延時函數。。
for(i=0;i<x;i++)
for(j=0;j<125;j++)
for(k=0;k<120;k++);
}
/**************************************************************
函數功能:8um簡易延時
**************************************************************/
void delay8um(uchar x) //8ms延時函數
{
uchar i,j;
for(i=0;i<x;i++)
for(j=0;j<1;j++);
}
/**************************************************************
函數功能:產生音調
**************************************************************/
void sound(uchar x) //音調函數
{
uchar i;
for(i=0;i<60;i++)
{
buzzer=0;delay8um(tone[x]); //開關頻率。。從而產生節拍
buzzer=1;delay8um(tone[x]);
}
}
/*******************************************************************************
* 函 數 名 : Delay10ms
* 函數功能 : 延時函數,延時10ms
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Delay10ms(unsigned int c)
{
unsigned char a,b;
for(;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
void xianshi(unsigned int q)
{
uchar i = 128;
Lcd12864_Init();
Lcd12864_ClearScreen();
if(q==0)
{
Lcd12864_ClearScreen();
Lcd12864_Write16CnCHAR(0, i, "彈奏");
Delay10ms(100);
}
}
|