信号发生器设计报告
电子琴程序
2009-08-30 13:47:34| 分类: 默认分类
| 标签: |举报 |字号大中小 订阅
电子琴程序发送部分:
/*
本程序是用AD9851的DDS模块做的电子琴,
电子琴的音符完整,共21个按键,分别是低1--7,中1--7,高1--7。本程序为双机通信的发送部分,可以显示频率
*/
#include <REG51.H> //
单片机内部专用寄存器定义
/**************************************/
sbit K1= P1^0 //
键K1输入引脚定义
sbit K2= P1^1 // 键K2输入引脚定义
sbit K3= P1^2 //
键K3输入引脚定义
sbit K4= P1^3 // 键K4输入引脚定义
sbit K5= P1^4 //
键K5输入引脚定义
sbit K6= P1^5 // 键K6输入引脚定义
sbit K7= P1^6 //
键K7输入引脚定义
sbit K8= P1^7 //
键K15输入引脚定义
/**************************************/
sbit K9= P2^0 //
键K8输入引脚定义
sbit K10= P2^1 // 键K9输入引脚定义
sbit K11= P2^2 //
键K10输入引脚定义
sbit K12= P2^3 // 键K11输入引脚定义
sbit K13= P2^4 //
键K12输入引脚定义
sbit K14= P2^5 // 键K13输入引脚定义
sbit K15= P2^6 //
键K14输入引脚定义
sbit K16= P2^7 //
键K16输入引脚定义
/**************************************/
sbit K17= P3^2 //
键K17输入引脚定义
sbit K18= P3^3 // 键K18输入引脚定义
sbit K19= P3^4 //
键K19输入引脚定义
sbit K20= P3^5 // 键K20输入引脚定义
sbit K21= P3^7 // 键K21输入引脚定义
/******************延时程序********************/
void delay(unsigned int
k)
{
unsigned int i,j
for(i=0i<ki++){
for(j=0j<121j++)
{}}
}
/*****************串口初始化程序*****************/
void
init
(void)
{
TMOD=0x20
TH1=0xfd
TL1=0xfd
SCON=0x50
TR1=1
}
/*****************串口发送程序*****************/
void chuan(shu)
{
SBUF=shu
TI=0
}
/******************主程序********************/
void main(void)
{
init()
while(1)
{
if(K1==0) chuan(1)
else if(K2==0)
chuan(2)
else if(K3==0) chuan(3)
else if(K4==0) chuan(4)
else
if(K5==0) chuan(5)
else if(K6==0) chuan(6)
else if(K7==0)
chuan(7)
else if(K8==0) chuan(8)
else if(K9==0) chuan(9)
else
if(K10==0) chuan(10)
else if(K11==0) chuan(11)
else if(K12==0)
chuan(12)
else if(K13==0) chuan(13)
else if(K13==0)
chuan(13)
else if(K14==0) chuan(14)
else if(K15==0)
chuan(15)
else if(K16==0) chuan(16)
else if(K17==0)
chuan(17)
else if(K18==0) chuan(18)
else if(K19==0)
chuan(19)
else if(K20==0) chuan(20)
else if(K21==0)
chuan(21)
elsechuan(0)
}
}
电子琴接收部分:
/*
本程序是用AD9851的DDS模块做的电子琴,
电子琴的音符完整,共21个音符,分别是低1--7,中1--7,高1--7。本程序为双机通信的接受部分。有直接演奏方式,录音演奏方式,录音后放音方式
,可以显示频率 */
#include <STC12C5410AD.H>
#include<intrins.h>
#include <stdio.h> /* prototype
declarations for I/O functions */
#define uchar unsigned char
#define uint unsigned int
sbit
E_CLK =P2^6//clock input 同步时钟输入端
sbit RW_SID
=P2^5//data input/output 串行数据输入、输出端
sbit RS_DI
=P2^4 // 4号脚 jichunqiinput
sbit DataIn_AD9851=P2^3
//控制子串传送位
sbit DDS_CLK=P2^2//接外部晶振时钟 这里为30M
sbit
DDS_FQUD=P2^1 //更新发送频率
sbit RST_AD9851= P2^0//复位
unsigned char Control_AD9851 = 0x01// Phase0 ,power on mode and 6 REFCLK
Multiplier enable
/* T0_int 定时 时间常数 5ms=5000=1388H->EC78H f=12MH */
#define
time_5ms_H 0xC2 /* 定时时间为1/64s */
#define time_5ms_L 0xF7
charshu, bb
unsigned char p=0
unsigned char
point=0
unsigned char recode_n=0
unsigned char xdata
array[50]={0}
unsigned int xdata arrayt[50]={0}
float const
ton[]={0.00,261.63,293.67,329.63,349.23,391.99,440.00,494.00,
523.25,587.33,659.25,698.46,783.99,880.00,987.76,
1046.50,1174.66,1381.51,1396.92,1567.98,1760.00,1975.52}
unsigned int ttt,
nnn
unsigned char mode=0
sbit KEY_rec =P3^5
sbit KEY_play=P3^7
/*************************延时程序***************************/
void
delay(uint k)
{
uint i,j
for(i=0i<ki++)
{for(j=0j<121j++)
{}}
}
/*************************串行发送一字节数据***************************/
void SendByte(unsigned char dat)
{
unsigned
char i
RS_DI=1
for(i=0i<8i++)
{
E_CLK=0
if(dat&0x80)RW_SID=1
else RW_SID=0
E_CLK=1
dat=dat<<1
}
}
/*************************写控制命令***************************/
void
SendCMD(unsigned char dat)
{
SendByte(0xF8)//11111,00,0
RW=0,RS=0 同步标志
SendByte(dat&0xF0)//高四位
SendByte((dat&0x0F)<<4)//低四位
}
/************************写显示数据或单字节字符 ****************************/
void SendDat(unsigned char dat)
{
SendByte(0xFA)//11111,01,0 RW=0,RS=1
SendByte(dat&0xF0)//高四位
SendByte((dat&0x0F)<<4)//低四位
}
/************************显示字符串****************************/
void
hzkdis(unsigned char code *s)
{ while(*s>0)
{
SendDat(*s)
s++
delay(5)
}
}
/************************显示数据子程序****************************/
void
Display(unsigned char x_add,unsigned long date,unsigned char dot)
{
unsigned char date0,date1,date2,date3,date4,date5//
date5=(date%1000000)/100000
date4=(date%100000)/10000
date3=(date%10000)/1000
date2=(date%1000)/100
date1=(date%100)/10
date0=date%10
SendCMD(x_add)
if(dot==0x02) //100---9999.99
{
SendDat(0x30+date5)
SendDat(0x30+date4)
SendDat(0x30+date3)
SendDat(0x30+date2)
SendDat(0x2e)
SendDat(0x30+date1)
SendDat(0x30+date0)
SendDat(0x48)
SendDat(0x7a)
}
}
/*************************设置AD9851频率***************************/
void
SentFreq(unsigned long int freq)
{
unsigned char i=0
unsigned int
temp
DDS_FQUD=0
for(i=0i<32i++) //串口数据
输入频率控制字
{
DDS_CLK =
0
temp=((freq>>i)&1)
DataIn_AD9851 = temp
DDS_CLK =
1
}
for(i=0i<8i++)//phase-b4 ph-b3 ph-b2 ph-b1 ph-b0 Power-down
Logic0* 6*REFCLK Multiplier_En
{
DDS_CLK = 0
temp=((Control_AD9851>>i)&1)
DataIn_AD9851 = temp
DDS_CLK = 1
}
DDS_CLK = 0
DDS_FQUD = 1
DDS_FQUD =
0
}
/**************************换算频率,并输出***********************/
void
Set_Freq(float Freqency)
{unsigned long int freq_temp
freq_temp=
(unsigned long int)(23.861*Freqency)// SYSCLK = 180 MHz
2^32/180000000=23.861
SentFreq(freq_temp)
}
/*************************T0作定时器,T1作波特率发生器,初始化*************************/
void
init (void)
{
TMOD= 0x01 /* 0001$0001 T1 &T0 are 16bit
timers */
TH0 = time_5ms_H/* T0 timer 5ms */
TL0 =
time_5ms_L
/* TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 */
TCON= 0x10 /* 0 0 0 1 0 0 0 0 */
/*start T0xint1 xint0 */
IE= 0x82/* 1000 0010,
EA=ET0=1,
*/
TMOD=0x20
TH1=0xfd
TL1=0xfd
TR1=1
SCON=0x50
ES=1
EA=1
}
/*************************设置AD9851初始化*************************/
void
AD9851Init(void) //DDS初始化函数,包括DDS复位和初始化为串行发送
{
DDS_CLK=0
DDS_FQUD=0
RST_AD9851=0
RST_AD9851=1//复位AD9851
RST_AD9851=1
RST_AD9851=1
RST_AD9851=0
DDS_CLK=1
DDS_CLK=0
DDS_FQUD=1
DDS_FQUD=0
}
/**************************初始化LCM
**************************/
void initlcm(void)
{
delay(100)
SendCMD(0x30)//功能设置,一次送8位数据,基本指令集
SendCMD(0x0C)//0000,1100 整体显示,游标off,游标位置off
SendCMD(0x14)
SendCMD(0x01)//0000,0001 清DDRAM 即清屏
SendCMD(0x02)//0000,0010 DDRAM地址归位
SendCMD(0x80)//1000,0000
设定DDRAM 7位地址000,0000到地址计数器AC
//SendCMD(0xb8|page)翻页
}
/**********************主程序******************************/
void
main(void)
{
uchar t
init()
AD9851Init()
initlcm()//12864初始化程序
shu=0
bb=255
while(1)
{
switch(mode)
{
case 0: //
演奏方式
SendCMD(0x80)//第一行(如果是地址是:80H,即LCD的第一行的第一个位置显示)
hzkdis("
音乐播放频率:")
if (shu!=bb)
{
Set_Freq(ton[shu])
Display(0x93,(unsigned
long)100*ton[shu],0x02)
bb=shu
}
if
(KEY_rec==0)
{
mode=1
point=0
recode_n=0
shu=0
bb=255
nnn=0
}
else if (KEY_play==0)
{
mode=2
p=1
}
break
case
1: // 录音方式
// SendCMD(0x01)//0000,0001 清DDRAM 即清屏
//
delay(10)
SendCMD(0x80)//第一行(如果是地址是:80H,即LCD的第一行的第一个位置显示)
hzkdis("
音乐录制频率:")
if (shu!=bb)
{
arrayt[point]=nnn // 记录上一音阶时间
Set_Freq(ton[shu])
Display(0x93,(unsigned long)100*ton[shu],0x02)
nnn=0
bb=shu
recode_n++
}
if ((recode_n>=50) || (KEY_play==0))
//停止录音
{
Set_Freq(0.0)
p=0
mode=0
shu=0
bb=20
}
break
case 2: //
放音方式
SendCMD(0x80)//第一行(如果是地址是:80H,即LCD的第一行的第一个位置显示)
hzkdis("
音乐重播频率:")
for(t=0t<recode_nt++)
{
Set_Freq(ton[array[p]])
Display(0x93,(unsigned
long)*ton[array[p]],0x02)
ttt=arrayt[p]
while
(ttt)
delay(100)
p++
}
if
(p>recode_n)
{
Set_Freq(0.0)
p=0
mode=0
shu=0
bb=20
}
break
}
}
}
//*==================================*/
/* 串口中断接收
*/
/*==================================*/
void s_receive() interrupt 4
//串行中断
{
if(RI==1) //接收中断标志位
{
RI=0//中断标志清零
shu=SBUF //RXData赋值
}
else
TI=0
}
R5音调延时值R6从内存中读到的数据
9H--TABLE1~11数据20H--TL1初值21H--TH1初值22H--修正后的按键值30H--TABLE1~11地址计数器
0AH--d奏音调延时值0BH--内存地址0CH--读写到内存的数据0DH--按键值0EH--内存器件地址
PORT1 EQU P1
PORT2 EQU P2
SCK BIT P3.0
SDA BIT P3.1
ORG 0H
SJMP MAIN
ORG 0BH
LJMP TIME0
ORG 1BH
LJMP TIME1
ORG 30H
--------------------------------------------------------------------------
MAIN: CLR TR0
CLR TR1
MOV SP,#4FH
MOV R0,#100
CLR P3.4
LCALL DELAY5
MOV 9H,#0
MOV 0AH,#0
MOV 0BH,#0
MOV 0CH,#0
MOV TMOD,#11H
MOV IE,#8AH
MOV 0DH,#88H
------------扫描放歌和d奏建------------------------------------
XIAN: JB P3.2,QT1 没按下放歌建跳qt1
SETB P3.4 按下放歌建LED发光
LCALL DELAY1
LCALL DELAY1
JNB P3.2,$ 放歌建没释放原地等待
LCALL DELAY1
LCALL DELAY1
Q1: LCALL SAO
CJNE R0,#0,Q11
SJMP Q1
Q11: LCALL TRANF
JZ MAIN
MOV 0DH,A 0DH=按键值
LJMP SING0
QT1: JB P3.3,QT4 没按d奏建跳QT3
SETB P3.4
LCALL DELAY1
LCALL DELAY1
JNB P3.3,$ d奏键没释放原地等待
LCALL DELAY1
LCALL DELAY1
QT2: LCALL SAO
CJNE R0,#0,QT3
SJMP QT2
QT3: LCALL TRANF
CJNE A,#0BH,QT11 若按键值=11转(B键)MAIN!=11键转QT11
LJMP MAIN
QT11: JC MAIN 若按键值<11转MAIN>11继续
CJNE A,#0CH,M4 若按键值!=12转M1=12(C键)继续 即C键没按下转M1
MOV PORT1,#11101111B
JNB P1.3,$ 若C键没释放原地等待
MOV 0BH,#0
LJMP LOOP 输入乐曲存储并演奏
M4: LCALL DELAY1
LCALL DELAY1
LCALL RWX80 擦写内存数据全部为1
LJMP MAIN
QT4: LJMP XIAN 返回重新扫描放歌和d奏建
--------------------------------------------------------------------------
RWX80: CJNE A,#0DH,MM2 A!=13(D键)转M2若为D键继续D键没按下转M2
MOV 0EH,#0A2H 0EH=162=10100010B0EH为24c16页地址
SJMP MM
MM2: CJNE A,#0EH,MM3 A!=14(E键)转M3E键没按下转M3
MOV 0EH,#0A4H 0EH=164=10100100B
SJMP MM
MM3: MOV 0EH,#0A6H F键按下0EH=166=10100110B
MM: MOV 0BH,#0
MOV 0CH,#0H
RWX801: LCALL RKX02
LCALL WKX02
INC 0BH
INC 0BH
INC 0BH
INC 0BH
MOV A,0BH
CJNE A,#0FFH,MM4
MOV 0BH,#0
MM4: INC 0CH
INC 0CH
INC 0CH
INC 0CH
CJNE A,#0H,RWX801
RET
--------读数据------------------------------
RKX02:
LCALL START
MOV A,#0A0H 24C16寻址10100000写
LCALL WRBYT
LCALL TACK
MOV A,0BH 发送24c16子地址
LCALL WRBYT
LCALL TACK
LCALL START
MOV A,#0A1H 24C16寻址10100001读
LCALL WRBYT
LCALL TACK
LCALL WRBYT
LCALL TACK
MOV 10H,R6
LCALL RDBYT
LCALL NOTACK
LCALL WRBYT
LCALL TACK
MOV 11H,R6
LCALL RDBYT
LCALL NOTACK
LCALL WRBYT
LCALL TACK
MOV 12H,R6
LCALL RDBYT
LCALL TACK
MOV 13H,R6
LCALL NOTACK
LCALL STOP
RET
---------写数据-----------------------
WKX02:
MOV R1,#10H
LCALL START
MOV A,#0A0H
LCALL WRBYT
LCALL TACK
MOV A,0BH
LCALL WRBYT
LCALL TACK
MOV A,0CH
LCALL WRBYT
LCALL TACK
MOV R0,#4
WKX021: MOV A,@R1
LCALL WRBYT
LCALL TACK
INC R1
DJNZ R0,WKX021
LCALL STOP
LCALL DELAY5
LCALL DELAY5
RET
-------输入乐曲存储并演奏--------------------------------------------
LOOP: CLR TR0
CLR TR1
AAA: JB P3.3,LOOP4 d奏键按下 向下执行存储乐曲并演奏 否则转LOOP4继续输入乐曲
LCALL DELAY1
LCALL DELAY1
MOV 0CH,#0
LCALL WBAY 存00结束乐谱
LCALL DELAY1
MOV 0DH,#12
LJMP SING0 播放d奏的乐曲
LOOP4: LCALL SAO
CJNE R0,#0,KEYIN
LJMP LOOP
KEYIN: LCALL TRANF
SWAP A
MOV 09H,A
SWAP A
CJNE A,#0,ZZZ 非0键转ZZZ
CLR TR1
CLR TR0
LJMP ZZZZ 0键转ZZZZ
ZZZ: DEC A A为按键值因从1键值音调序号对应TABLE频率表0位置故减1
MOV 22H,A 22H存修正后(A=A-1)的按键值
CLR C
RLC A A*2因TABLE一个单元为2字节(1字),指向该单元的第1个字节
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV TH1,A TH1赋初值
MOV 21H,A TH1初值存21H
MOV A,22H
CLR C
RLC A A*2因TABLE一个单元为2字节(1字)
INC A 指向该单元的第2个字节
MOVC A,@A+DPTR
MOV TL1,A TL1赋初值
MOV 20H,A TL1初值存20H
MOV TH0,#0C2H
MOV TL0,#0F6H
SETB TR0
SETB TR1
ZZZZ: MOV A,PORT1
ORL A,#0F0H
CJNE A,#0FFH,ZZZZ
CLR TR0
CLR TR1
MOV A,0AH d奏乐谱频率延迟值赋A
CLR C
RRC A
CLR C
RRC A
CLR C
RRC A d奏乐谱频率延迟值/8
CJNE A,#0FH,NODE
SJMP DDD
NODE: JC DDD
MOV A,#0FH d奏乐谱频率延迟值/8后若>15则=15
DDD: ORL 09H,A
MOV 0AH,#0
WWW:&nbsp MOV A,09H
MOV 0CH,A
LCALL WBAY
LCALL DELAY5
INC 0BH
LJMP LOOP
-----频率延时-----------------------------------------
DELAY: MOV R7,#125
DLY2: MOV R4,#02
DLY3: MOV R3,#248
DJNZ R3,$
DJNZ R4,DLY3
DJNZ R7,DLY2
DJNZ R5,DELAY
RET
---------延时----------------------
DELAY1: MOV R7,#30
MOV R6,#0
S1: DJNZ R6,$
DJNZ R7,S1
RET
DELAY5: MOV R7,#10
MOV R6,#0
S5: DJNZ R6,$
DJNZ R7,S5
RET
-----扫描按键子程序----------
SAO: MOV R0,#4
MOV R3,#11101111B
MOV R2,#11111111B
NLINE1: MOV A,R3
MOV PORT1,A
MOV A,PORT1
ORL A,#0F0H
CJNE A,#0FFH,KEYIN1
MOV A,R3
RL A
MOV R3,A
DJNZ R0,NLINE1
RET
KEYIN1: LCALL DELAY1
LCALL DELAY1
LCALL DELAY1
LCALL NOPEN
RET
-----按键延时-------------
NOPEN: MOV A,PORT1
MOV R2,A
ORL A,#0F0H
CJNE A,#0FFH,NOPEN1
SJMP NOPEN
NOPEN1: LCALL DELAY1
LCALL DELAY1
RET
----------键盘码转换为按键值-----------------
TRANF: MOV B,#0
MOV A,R2
C1: RRC A
JNC C2 C=0跳C2
INC B
INC B
INC B
INC B B=B+4
LJMP C1
C2: MOV A,R2
RR A
RR A
RR A
RR A
C3: RRC A
JNC C4
INC B
LJMP C3
C4: MOV A,B B为按键值
RET
---------按键值散转表-------------------
SING0:
MOV 30H,#00H 30H为TABLE1~11地址计数器
NEXT: MOV A,0DH
CJNE A,#1,NN1
MOV DPTR,#TABLE1
LJMP WW
NN1: CJNE A,#2,NN2
MOV DPTR,#TABLE2
LJMP WW
NN2: CJNE A,#3,NN3
MOV DPTR,#TABLE3
LJMP WW
NN3: CJNE A,#4,NN4
MOV DPTR,#TABLE4
LJMP WW
NN4: CJNE A,#5,NN5
MOV DPTR,#TABLE5
LJMP WW
NN5: CJNE A,#6,NN6
MOV DPTR,#TABLE6
LJMP WW
NN6: CJNE A,#7,NN7
MOV DPTR,#TABLE7
LJMP WW
NN7: CJNE A,#8,NN8
MOV DPTR,#TABLE8
LJMP WW
NN8: CJNE A,#9,NN9
MOV DPTR,#TABLE9
LJMP WW
NN9: CJNE A,#10,NN10
MOV DPTR,#TABLE10
LJMP WW
NN10: CJNE A,#11,NN11
MOV DPTR,#TABLE11
LJMP WW
NN11: CJNE A,#12,NN12
MOV 0EH,#0A1H
MOV 0BH,#0
LJMP NN
NN12: CJNE A,#13,NN13
MOV 0EH,#0A3H
MOV 0BH,#0H
LJMP MAIN
NN13: CJNE A,#14,NN14
MOV 0EH,#0A5H
MOV 0BH,#0H
LJMP MAIN
NN14: CJNE A,#15,NN
MOV 0EH,#0A7H
MOV 0BH,#00H
LJMP MAIN
--------------------------------
NN: LCALL RBAY 读内存
NNT: MOV A,R6 R6为从内存中读到的数据
LJMP IIC
-----------奏乐--------------------------------------------
WW: MOV A,30H
JZ WW0
MOVC A,@A+DPTR
SJMP IIC
WW0: MOVC A,@A+DPTR
MOV 30H,#1
MOV 31H,A
SJMP WW
IIC: MOV R2,A
JZ ENDF A=00 结束标志跳ENDF程序重新开始
ANL A,#0FH 低4位为延时值
MOV R5,A R5延时值频率延时(DELAY)程序用
MOV A,R2
SWAP A
ANL A,#0FH 高4位为音调序号若
JNZ SING 为0则
CLR TR1 为休止符
SJMP DLY1
SING: DEC A 频率表从0位置开始,音调序号表从1位置开始,0位置数据是解密数据
PUSH ACC
MOV A,0DH
CJNE A,#11,BD 若>11(B)键,即为C~F键转BD0若<=11(B)键转DE,音调序号+31H
POP ACC
SJMP DE
BD: POP ACC
JNC BD0
DE: ADD A,31H
BD0: MOV 22H,A
RL A
MOV DPTR,#TABLE
MOVC A,@A+DPTR
MOV TH1,A
MOV 21H,A
MOV A,22H
RL A
INC A
MOVC A,@A+DPTR
MOV TL1,A
MOV 20H,A
SETB TR1
DLY1: INC R5
ACALL DELAY
INC 30H
INC 0BH
MOV A,0DH 取按键值判断是读内存键还是读乐谱序号键
CJNE A,#0BH,NNBD 若按键值<11取下1个乐谱若按键值为12~15(C~F)转NNBD读内存
NEXT1: LJMP NEXT
NNBD: JC NEXT1
LJMP NN 读内存
--------程序重新开始---------------------------------------
ENDF: CLR TR1
LJMP MAIN
--------T0中断服务d奏频率延迟时间---------------------------------------------
TIME0: INC 0AH d奏乐谱频率延迟值
MOV TH0,#0C2H
MOV TL0,#0F6H 定时初值 =49910 计数次数为 2^16(65536)-49910=15626=16ms
RETI
--------T1中断服务发声-----------------------
TIME1: PUSH ACC
PUSH PSW
MOV TL1,20H
MOV TH1,21H
CPL P3.7
POP PSW
POP ACC
RETI
--------读数据--------------------
RBAY: LCALL START
MOV A,#0A0H
LCALL WRBYT
LCALL TACK
MOV A,0BH
LCALL WRBYT
LCALL TACK
LCALL START
MOV A,0EH
LCALL WRBYT
LCALL TACK
LCALL RDBYT
LCALL NOTACK
LCALL STOP
RET
-------写数据-------------------
WBAY: LCALL START
MOV A,#0A0H
LCALL WRBYT
LCALL TACK
MOV A,0BH
LCALL WRBYT
LCALL TACK
MOV A,0CH
LCALL WRBYT
LCALL TACK
LCALL STOP
RET
---------写数据---------------
WKX03: MOV R1,#10H
LCALL START
MOV A,#0A2H
LCALL WRBYT
LCALL TACK
MOV A,0CH
LCALL WRBYT
LCALL TACK
MOV R0,#4
WKX031: MOV A,@R1
LCALL WRBYT
LCALL TACK
INC R1
DJNZ R0,WKX031
LCALL STOP
LCALL DELAY1
LCALL DELAY1
RET
-------启动24C16读写时序------------------
START: SETB SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SDA
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
RET
-------停止信号------------------
STOP: CLR SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
SETB SDA
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
RET
-------应答信号-----------------
TACK: SETB SDA
CLR SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
SETB SDA
NOP
NOP
NOP
NOP
RET
-------------------------
CHACK: SETB SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
MOV C,SDA
CLR SCK
NOP
NOP
NOP
NOP
RET
-----------------------------
NOTACK: NOP
SETB SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
RET
------读IIC-24C16------------------
RDBYT: MOV R7,#8
SETB SDA
NOP
NOP
NOP
NOP
RDBYT1: SETB SCK
NOP
NOP
NOP
NOP
NOP
NOP
MOV C,SDA
MOV A,R6
RLC A
MOV R6,A
CLR SCK
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,RDBYT1
RET
------写IIC-24C16---------------
WRBYT: MOV R7,#8
WRBYT1: RLC A
MOV SDA,C
JC WRBYT2
CLR SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,WRBYT1
RET
WRBYT2: SETB SDA
NOP
NOP
NOP
NOP
SETB SCK
NOP
NOP
NOP
NOP
CLR SCK
NOP
NOP
NOP
NOP
CLR SDA
NOP
NOP
NOP
NOP
DJNZ R7,WRBYT1
RET
-------TABLE为频率值 -------------------------------------
TABLE: DW 0F88CH,0F95BH,0FA15H,0FA67H,0FB04H,0FB90H,0FC0CH 低音1~7
DW 0FC44H,0FCACH,0FD09H,0FD34H,0FD82H,0FDC8H,0FE06H 中音1~7
DW 0FE22H,0FE56H,0FE85H,0FE9AH,0FEC1H,0FEE4H,0FF03H 高音1~7
--------TABLE1~11为音调序号和音调延时表调数据高4位是-----------------------------------
--------音调序号低4位是音调延时值-----------------------------------------------------------------
--------兰花草---------------------------------------
TABLE1: DB 02H,42H,82H,82H,82H,84H,02H,72H,62H,72H,62H
DB 52H,48H,0B2H,0B2H,0B2H,0B2H,0B4H,02H,0A2H
DB 12H,0A2H,0D2H,92H,88H,82H,0B2H,0B2H,0A2H,84H
DB 02H,72H,62H,72H,62H,52H,44H,02H,12H,12H,62H
DB 62H,52H,44H,02H,82H,72H,62H,52H,32H,48H,00
-------哈巴--------------------------------------------
TABLE2: DB 04H,42H,42H,42H,52H,64H,04H,62H,62H,62H,72H,84H,04H
DB 92H,92H,82H,72H,64H,04H,82H,82H,52H,62H,44H,04H
DB 42H,42H,42H,52H,64H,04H,62H,62H,62H,72H,84H,04H
DB 92H,92H,82H,72H,64H,04H,82H,82H,52H,62H,44H,04H,00H
-------生日快乐---------------------------------------
TABLE3: DB 04H,82H,01H,81H,94H,84H,0B4H,0A4H,04H
DB 82H,01H,81H,94H,84H,0C4H,0B4H,04H
DB 82H,01H,0F4H,0D4H,0B4H,0A4H,94H
DB 0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H,00H
-------不倒翁--------------------------------------------
TABLE4: DB 04H,84H,94H,88H,64H,54H,68H,84H,64H
DB 54H,44H,62H,82H,42H,62H,58H1
DB 84H,94H,88H,64H,54H,68H,84H,64H2
DB 54H,44H,52H,42H,52H,62H,48H,00
-------妹妹背着洋娃娃---------------------------------------
TABLE5: DB 04H,84H,02H,82H,64H,54H,64H,54H,48H,64H
DB 02H,52H,44H,24H,14H,24H,18H1
DB 24H,02H,22H,42H,24H,44H,54H,68H,54H2
DB 02H,52H,84H,84H,54H,64H,48H,00
-------两只老虎-------------------------------------------------
TABLE6: DB 04H,44H,54H,64H,44H,44H,54H,64H,44H,64H,74H,88H,64H,74H,88H1
DB 82H,92H,82H,72H,64H,44H,82H,92H,82H
DB 72H,64H,44H,44H,84H,48H,44H,14H,48H,00
-------三只小猫----------------------------------------------
TABLE7: DB 04H,62H,82H,82H,62H,98H,92H,0B2H,0B2H,82H,98H
DB 2H,82H,82H,52H,68H,92H,0B2H,0B2H,82H,98H
DB 62H,82H,82H,62H,92H,92H,94H
DB 92H,0B2H,0B2H,92H,84H,94H,0B8H,0B4H,04H,00
-------绿-------------------------------------------------------
TABLE8: DB 02H,42H,82H,82H,82H,84H,02H,72H,62H,72H,62H,52H,48H
DB 0B2H,0B2H,0B2H,0B2H,0B4H,02H,0A2H
DB 12H,0A2H,0D2H,92H,88H,82H,0B2H,0B2H,0A2H,84H
DB 02H,72H,62H,72H,62H,52H,44H,02H,12H
DB 12H,62H,62H,52H,44H,02H,82H,72H,62H,52H,32H,48H,00
-------绿岛小夜曲-----------------------------------------------
TABLE9: DB 00H,0C2H,0D2H,0F2H,0D2H,0C4H,0D2H,0F2H
DB 0D2H,0C2H,0A2H,92H,0A8H
DB 92H,0A2H,0C2H,0A2H,92H,82H,62H,82H,58H,58H
DB 0C4H,22H,0D2H,0C4H,0A4H,92H,0A2H,92H,82H,92H,0A4H,092H
DB 84H,82H,32H,54H,22H,62H,052H,058H
DB 64H,22H,52H,64H,84H,92H,0A2H,92H,82H,92H,0A4H,0C2H
DB 92H,94H,0A2H,0C4H,22H,0D2H,0C8H,0C8H
DB 0D2H,0D4H,0C2H,0A2H,0A2H,92H,82H,92H,0A2H,0C2H,0A8H
DB 92H,94H,82H,62H,52H,52H,82H,98H,98H
DB 0A2H,0A4H,92H,0A2H,0C2H,0A4H,92H,0A2H,92H,82H,68H
DB 52H,0C2H,0A2H,0F2H,0C2H,0D2H,0A2H,92H,88H,88H
DB 0D2H,0D2H,0D2H,0C2H,0A2H,0A2H,22H
DB 92H,94H,82H,62H,52H,62H,82H,98H,98H
DB 0C2H,0D2H,0C2H,92H,0A2H,0A4H,0A2H
DB 92H,94H,82H,64H,84H,0C8H,0D1H,0C1H,0A2H,0C2H,0D4H,0D2H,0E2H
DB 0C2H,0D2H,0C2H,0A2H,98H
DB 0A4H,92H,82H,64H,22H,82H,92H,0A1H,91H,82H,92H,0A4H,22H,0C2H
DB 0D4H,22H,0A2H,94H,0A2H,92H,88H,88H,00
---------------------------------------------------------------------------
TABLE10:DB 00H,04H,42H,52H,62H,42H,42H,52H,62H,42H,62H,72H,86H,62H,72H,86H1
DB 82H,92H,82H,72H,62H,42H,82H,92H,82H
DB 72H,62H,42H,42H,82H,46H,42H,12H,48H,00
----------------------------------------------------------------------------
TABLE11:DB 00H,23H,01H,63H,01H,51H,61H,41H,51H
DB 64H,22H,92H,51H,61H,72H,64H
DB 04H,63H,01H,93H,01H,81H,91H,0A1H,0A1H
DB 94H,53H,61H,41H,51H,41H,31H,24H,04H
DB 53H,61H,41H,51H,41H,31H,24H,04H,53H,61H,82H
DB 92H,0AAH,02H,93H,0A1H,91H,81H,98H,04H,91H
DB 81H,92H,04H,61H,51H,62H,04H,56H,42H,12H
DB 22H,32H,32,28H,08H,00
--------------------------------------------------------------------------
TABLE12:
DB 01H,00H
---------------------
END
1,数据管显示就没什么了,找几个简单的数码管驱动程序改改就可以了,一般都是先选中数码管,然后设置值,就可以显示了,不过需要注意刷新,10ms刷新一个应该就可以了,刷新频率比较低的话会闪闪的,这个你应该明白。2,蜂鸣器发do音,这个硬件实现我就不知道了,也许有硬件可以 编码控制自动生成对应频率的值。我想如果通过软件实现的话,不妨考虑一下定时器。假设do音是1000Hz的频率(没有查,不清楚,假设的),那么你可以控制定时器的触发频率为1000hz,触发一次,对应的输出到蜂鸣器的口的电平跳变一下,如果定时器的频率为1000hz的话,那么应该有500hz的频率,一个周期需要一高一低嘛!中断读取按键信号,分析按键,然后设定定时器的频率,启动定时器,设置一个响的时间,然后到时间关闭定时器,这样你按下k1就会发出一声do的声音,然后停了。
3,按键读取程序,中断或者查询方式,自己选择吧,别忘了延迟5ms左右再次读取按键,这个是消抖的。
4,建议模块化编程,先搞定按键的,然后搞定数码管的,然后搞定定时器的,然后再考虑如何把它们组合起来。好了不说了,说得有点多了,再说会我都回到大学时代了,哈哈。总之自己一点一点的做,应该不难,51熟练,c语言熟练,板子焊接的结构比较清晰的话,很快就可以搞定的。
5,还是建议你自己写一份各个模块的驱动的代码,例如按键的,数码管的,led的,温度传感器的,光敏的,蜂鸣器的,遥控器的,定时器的,中断的,等等等等模块(可以借鉴别人写的,自己一定要会),然后需要的时候,copy过来,改改就行,快而且bug少。建议keil c语言编程,用汇编编码太耗时了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)