信号发生器设计报告
电子琴程序
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
}
不知道有没有国际最优,但我这个算法很顶尖了:计算1亿以内的素数个数不到2秒钟!1到10000000000(10亿)共有素数50847534个,计算时间大概20多秒!程序如下:#include<iostream>using namespace std
int main()
{int CompositeNumFilterV3(int)
int m,c
cin>>m
c=CompositeNumFilterV3(m)
cout<<c<<endl
return 0
}//求素数的程序
int CompositeNumFilterV3(int n)
{
int i, j
//素数数量统计
int count = 0
// 分配素数标记空间,明白+1原因了吧,因为浪费了一个flag[0]
char* flag = (char*)malloc( n+1 )
// 干嘛用的,请仔细研究下文
int mpLen = 2*3*5*7*11*13
char magicPattern[2*3*5*7*11*13]// 奇怪的代码,why,思考无法代劳,想!
for (i=0i<mpLeni++)
{
magicPattern[i++] = 1
magicPattern[i++] = 0
magicPattern[i++] = 0
magicPattern[i++] = 0
magicPattern[i++] = 1
magicPattern[i] = 0
}
for (i=4i<=mpLeni+=5)
magicPattern[i] = 0
for (i=6i<=mpLeni+=7)
magicPattern[i] = 0
for (i=10i<=mpLeni+=11)
magicPattern[i] = 0
for (i=12i<=mpLeni+=13)
magicPattern[i] = 0 // 新的初始化方法,将2,3,5,7,11,13的倍数全干掉
// 而且采用memcpy以mpLen长的magicPattern来批量处理
int remainder = n%mpLen
char* p = flag+1
char* pstop = p+n-remainder
while (p <pstop)
{
memcpy(p, magicPattern, mpLen)
p += mpLen
}
if (remainder >0)
{
memcpy(p, magicPattern, remainder)
}
flag[2] = 1
flag[3] = 1
flag[5] = 1
flag[7] = 1
flag[11] = 1
flag[13] = 1 // 从17开始filter,因为2,3,5,7,11,13的倍数早被kill了
// 到n/13止的,哈哈,少了好多吧
int stop = n/13
for (i=17i <= stopi++)
{
// i是合数,请歇着吧,因为您的工作早有您的质因子代劳了
if (0 == flag[i]) continue
// 从i的17倍开始过滤
int step = i*2
for (j=i*17j <= nj+=step)
{
flag[j] = 0
}
}
// 统计素数个数
for (i=2i<=ni++)
{
if (flag[i]) count++
}
// 因输出费时,且和算法核心相关不大,故略
// 释放内存,别忘了传说中的内存泄漏
free(flag)
return count
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)