1、最开始,我们先打开keil。
2、接着,我们要定义好库函数,想要实现动态数码灯,这个步骤是很重要的。
3、接着,我们加上一条循环语句。
4、最后,我们把先前定义的延时语句delayms写好。
5、最后,点击这里进行编译,生成一个hex文件。
6、如果这里无错误警告的话,就说明我们的程序写对了,那我们就可以点亮动态数码管了。
#include<reg51.h>#define uchar unsigned char
uchar code ledtab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40}//0-9
uchar sec=0,min=0,hour
uchar time
uchar disdat[6]
void delay(unsigned int x)
{
unsigned int i,j
for(i=0i<xi++)
for(j=0j<120j++)
}
void dischg()
{
disdat[0]=sec%10
disdat[1]=sec/10
disdat[2]=min%10
disdat[3]=min/10
disdat[4]=hour%10
disdat[5]=hour/10
}
void t0isr() interrupt 1 //秒计时
{
TH0=0x3c
TL0=0xb0
time++
if(time==20)
{
time=0
if(sec>0)sec--
else if(min>0){sec=99min--}
else if(hour>0){sec=99min=99hour--}
}
dischg()
}
void t1isr() interrupt 3 //显示
{
TH1=0xec
TL1=0x78
switch(scanled)
{
case 0:
P2=0x20
P0=~ledtab[disdat[5]]
break
case 1:
P2=0x10
P0=~ledtab[disdat[4]]
break
case 2:
P2=0x08
P0=~ledtab[disdat[3]]
break
case 3:
P2=0x04
P0=~ledtab[disdat[2]]
break
case 4:
P2=0x02
P0=~ledtab[disdat[1]]
break
case 5:
P2=0x01
P0=~ledtab[disdat[0]]
break
default:break
}
scanled++
scanled%=6
}
main()
{
TMOD=0x11
TH0=0x3c
TL0=0xb0
TH1=0xec
TL1=0x78
TR1=1
TR0=0
ET0=1
ET1=1
EA=1
fmq=0
scanled=0
time=0
mode=1
dischg()
while(1)
{
if(keyhu==0)
{
while(keyhu==0)
TR0=0
hour++
hour%=24
}
if(keyhd==0)
{
while(keyhd==0)
TR0=0
if(hour>0)hour--
if(hour==0)hour=23
}
if(keymu==0)
{
while(keymu==0)
TR0=0
min++
min%=60
}
if(keymd==0)
{
while(keymd==0)
TR0=0
if(min>0)min--
if(min==0)min=59
}
if(keysu==0)
{
while(keysu==0)
TR0=0
sec++
sec%=60
}
if(keysd==0)
{
while(keysd==0)
TR0=0
if(sec>0)sec--
if(sec==0)sec=59
}
if(keyst==0)
{
while(keyst==0)
TR0=~TR0
}
dischg()
}
}
电子琴程序信号发生器设计报告
电子琴程序
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
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)