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
快速傅里叶变换 要用C++ 才行吧 你可以用MATLAB来实现更方便点啊此FFT 是用VC6.0编写,由FFT.CPP;STDAFX.H和STDAFX.CPP三个文件组成,编译成功。程序可以用文件输入和输出为文件。文件格式为TXT文件。测试结果如下:
输入文件:8.TXT 或手动输入
8 //N
1
2
3
4
5
6
7
8
输出结果为:或保存为TXT文件。(8OUT.TXT)
8
(36,0)
(-4,9.65685)
(-4,4)
(-4,1.65685)
(-4,0)
(-4,-1.65685)
(-4,-4)
(-4,-9.65685)
下面为FFT.CPP文件:
// FFT.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include <iostream>
#include <complex>
#include <bitset>
#include <vector>
#include <conio.h>
#include <string>
#include <fstream>
using namespace std
bool inputData(unsigned long &, vector<complex<double>>&) //手工输入数据
void FFT(unsigned long &, vector<complex<double>>&) //FFT变换
void display(unsigned long &, vector<complex<double>>&) //显示结果
bool readDataFromFile(unsigned long &, vector<complex<double>>&) //从文件中读取数据
bool saveResultToFile(unsigned long &, vector<complex<double>>&) //保存结果至文件中
const double PI = 3.1415926
int _tmain(int argc, _TCHAR* argv[])
{
vector<complex<double>>vecList //有限长序列
unsigned long ulN = 0 //N
char chChoose = ' ' //功能选择
//功能循环
while(chChoose != 'Q' &&chChoose != 'q')
{
//显示选择项
cout <<"\nPlease chose a function" <<endl
cout <<"\t1.Input data manually, press 'M':" <<endl
cout <<"\t2.Read data from file, press 'F':" <<endl
cout <<"\t3.Quit, press 'Q'" <<endl
cout <<"Please chose:"
//输入选择
chChoose = getch()
//判断
switch(chChoose)
{
case 'm': //手工输入数据
case 'M':
if(inputData(ulN, vecList))
{
FFT(ulN, vecList)
display(ulN, vecList)
saveResultToFile(ulN, vecList)
}
break
case 'f'://从文档读取数据
case 'F':
if(readDataFromFile(ulN, vecList))
{
FFT(ulN, vecList)
display(ulN, vecList)
saveResultToFile(ulN, vecList)
}
break
}
}
return 0
}
bool Is2Power(unsigned long ul) //判断是否是2的整数次幂
{
if(ul <2)
return false
while( ul >1 )
{
if( ul % 2 )
return false
ul /= 2
}
return true
}
bool inputData(unsigned long &ulN, vector<complex<double>>&vecList)
{
//题目
cout<<"\n\n\n==============================Input Data===============================" <<endl
//输入N
cout<<"\nInput N:"
cin>>ulN
if(!Is2Power(ulN)) //验证N的有效性
{
cout<<"N is invalid (N must like 2, 4, 8, .....), please retry." <<endl
return false
}
//输入各元素
vecList.clear() //清空原有序列
complex<double>c
for(unsigned long i = 0i <ulNi++)
{
cout <<"Input x(" <<i <<"):"
cin >> c
vecList.push_back(c)
}
return true
}
bool readDataFromFile(unsigned long &ulN, vector<complex<double>>&vecList) //从文件中读取数据
{
//题目
cout<<"\n\n\n===============Read Data From File==============" <<endl
//输入文件名
string strfilename
cout <<"Input filename:"
cin >>strfilename
//打开文件
cout <<"open file " <<strfilename <<"......." <<endl
ifstream loadfile
loadfile.open(strfilename.c_str())
if(!loadfile)
{
cout <<"\tfailed" <<endl
return false
}
else
{
cout <<"\tsucceed" <<endl
}
vecList.clear()
//读取N
loadfile >>ulN
if(!loadfile)
{
cout <<"can't get N" <<endl
return false
}
else
{
cout <<"N = " <<ulN <<endl
}
//读取元素
complex<double>c
for(unsigned long i = 0i <ulNi++)
{
loadfile >>c
if(!loadfile)
{
cout <<"can't get enough infomation" <<endl
return false
}
else
cout <<"x(" <<i <<") = " <<c <<endl
vecList.push_back(c)
}
//关闭文件
loadfile.close()
return true
}
bool saveResultToFile(unsigned long &ulN, vector<complex<double>>&vecList) //保存结果至文件中
{
//询问是否需要将结果保存至文件
char chChoose = ' '
cout <<"Do you want to save the result to file? (y/n):"
chChoose = _getch()
if(chChoose != 'y' &&chChoose != 'Y')
{
return true
}
//输入文件名
string strfilename
cout <<"\nInput file name:"
cin >>strfilename
cout <<"Save result to file " <<strfilename <<"......" <<endl
//打开文件
ofstream savefile(strfilename.c_str())
if(!savefile)
{
cout <<"can't open file" <<endl
return false
}
//写入N
savefile <<ulN <<endl
//写入元素
for(vector<complex<double>>::iterator i = vecList.begin()i <vecList.end()i++)
{
savefile <<*i <<endl
}
//写入完毕
cout <<"save succeed." <<endl
//关闭文件
savefile.close()
return true
}
void FFT(unsigned long &ulN, vector<complex<double>>&vecList)
{
//得到幂数
unsigned long ulPower = 0 //幂数
unsigned long ulN1 = ulN - 1
while(ulN1 >0)
{
ulPower++
ulN1 /= 2
}
//反序
bitset<sizeof(unsigned long) * 8>bsIndex //二进制容器
unsigned long ulIndex//反转后的序号
unsigned long ulK
for(unsigned long p = 0p <ulNp++)
{
ulIndex = 0
ulK = 1
bsIndex = bitset<sizeof(unsigned long) * 8>(p)
for(unsigned long j = 0j <ulPowerj++)
{
ulIndex += bsIndex.test(ulPower - j - 1) ? ulK : 0
ulK *= 2
}
if(ulIndex >p)
{
complex<double>c = vecList[p]
vecList[p] = vecList[ulIndex]
vecList[ulIndex] = c
}
}
//计算旋转因子
vector<complex<double>>vecW
for(unsigned long i = 0i <ulN / 2i++)
{
vecW.push_back(complex<double>(cos(2 * i * PI / ulN) , -1 * sin(2 * i * PI / ulN)))
}
for(unsigned long m = 0m <ulN / 2m++)
{
cout<<"\nvW[" <<m <<"]=" <<vecW[m]
}
//计算FFT
unsigned long ulGroupLength = 1 //段的长度
unsigned long ulHalfLength = 0 //段长度的一半
unsigned long ulGroupCount = 0//段的数量
complex<double>cw //WH(x)
complex<double>c1 //G(x) + WH(x)
complex<double>c2 //G(x) - WH(x)
for(unsigned long b = 0b <ulPowerb++)
{
ulHalfLength = ulGroupLength
ulGroupLength *= 2
for(unsigned long j = 0j <ulNj += ulGroupLength)
{
for(unsigned long k = 0k <ulHalfLengthk++)
{
cw = vecW[k * ulN / ulGroupLength] * vecList[j + k + ulHalfLength]
c1 = vecList[j + k] + cw
c2 = vecList[j + k] - cw
vecList[j + k] = c1
vecList[j + k + ulHalfLength] = c2
}
}
}
}
void display(unsigned long &ulN, vector<complex<double>>&vecList)
{
cout <<"\n\n===========================Display The Result=========================" <<endl
for(unsigned long d = 0d <ulNd++)
{
cout <<"X(" <<d <<")\t\t\t = " <<vecList[d] <<endl
}
}
下面为STDAFX.H文件:
// stdafx.h : 标准系统包含文件的包含文件,
// 或是常用但不常更改的项目特定的包含文件
#pragma once
#include <iostream>
#include <tchar.h>
// TODO: 在此处引用程序要求的附加头文件
下面为STDAFX.CPP文件:
// stdafx.cpp : 只包括标准包含文件的源文件
// FFT.pch 将成为预编译头
// stdafx.obj 将包含预编译类型信息
#include "stdafx.h"
// TODO: 在 STDAFX.H 中
//引用任何所需的附加头文件,而不是在此文件中引用
#include "stdafx.h"#include <iostream>
using namespace std
NN(int)
int main(int argc, char* argv[])
{
int i
cout<<"请输入1-9之间的一个整数:"
cin>>i
cout<<endl
NN(i)
return 0
}
int NN(int x)
{
for(int i=1i<x+1i++)
{
for(int j=1j<i+1j++)
{
cout<<j<<"*"<<i<<"="<<j*i<<" "
}
cout<<endl
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)