跪求一个51单片机开发板的电子琴程序

跪求一个51单片机开发板的电子琴程序,第1张

电子琴程序

信号发生器设计报告

电子琴程序

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

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/11819385.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-18
下一篇 2023-05-18

发表评论

登录后才能评论

评论列表(0条)

保存