波形发生器汇编语言程序
- 格式:doc
- 大小:36.00 KB
- 文档页数:4
正弦波信号发生器一、实验目的1.了解用泰勒级数展开法计算角度正弦值和余弦值;2.了解产生正弦信号的方法;3.熟悉使用汇编语言编写较复杂的程序;4.熟悉在CCS 环境下计算角度正弦值和余弦值及产生正弦波的方法;二、实验原理泰勒级数展开法是根据泰勒展开式进行计算来实现正弦信号,它能精确地计算出一个角度的正弦和余弦值,且只需要较小的存储空间。
正弦函数和余弦函数可以展开成泰勒级数,其表达式:递推公式: sin()2cos()sin[(1)]sin[(2)]cos()2cos()sin[(1)]cos[(2)]nx x n x n x nx x n x n x =---=--- 由递推公式可以看出,在计算正弦和余弦值时,需要已知cos(x )、sin(n -1)x 、sin(n -2)x 和cos(n -2)x 。
用这种方法求少数点还可以,如产生连续正弦波、余弦波,则积累误差太大,不可取。
下面主要用泰勒级数展开法求正弦和余弦值,以及产生正弦波的方法。
三、实验内容与步骤1.用泰勒级数展开法计算sin(x)的值;(1)在 CCS 中新建项目:sinx.pjt ,建立文件sinx.asm 、vectors.asm 和sinx.cmd 。
并将此三个文件加入到项目中。
******************************************************* 用泰勒级数开展开式计算一个角度的正弦值 **sin(x)=x(1-x*x/2*3(1-x*x/4*5(1-x*x/6*7(1-x*x/8*9))))*******************************************************.title "sinx.asm".mmregs .def startSTACK: .usect "STACK",10start: STM #STACK+10,SPLD #d_x,DPST #6487H,d_x ;x-->d_x CALLsin_start end:B end sin_start:35792222sin()3!5!7!9! 111123456789(((())))x x x x x x x x x x x =-+-+=----⨯⨯⨯⨯24682222cos()12!4!6!8! 11112345678((()))x x x x x x x x x =-+-+=----⨯⨯⨯.def sin_startd_coeff .usect "coeff",4.datatable: .word 01C7H ;c1=1/(8*9).word 030BH ;c2=1/(6*7).word 0666H ;c3=1/(4*5).word 1556H ;c4=1/(2*3)d_x .usect "sin_vars",1d_squr_x .usect "sin_vars",1d_temp .usect "sin_vars",1d_sinx .usect "sin_vars",1c_1 .usect "sin_vars",1.textSSBX FRCTSTM #d_coeff,AR5RPT #3MVPD #table,*AR5+STM #d_coeff,AR3STM #d_x,AR2STM #c_1,AR4ST #7FFFH,c_1SQUR *AR2+,A ;A=x^2ST A,*AR2 ;(AR2)=x^2||LD *AR4,B ;B=1MASR *AR2+,*AR3+,B,A ;A=1-x^2/72,T=x^2MPYA A ;A=T*A=x^2(1-x^2/72)STH A,*AR2 ;(d_temp)=x^2(1-x^2/72)MASR *AR2-,*AR3+,B,A ;A=1-x^2/42(1-x^2/72),T=x^2(1-x^2/72)MPYA *AR2+ ;B=x^2(1-x^2/42(1-x^2/72))ST B,*AR2 ;(d_temp)=x^2(1-x^2/42(1-x^2/72))||LD *AR4,B ;B=1MASR *AR2-,*AR3+,B,A ;A=1-x^2/20(1-x^2/42(1-x^2/72))MPYA *AR2+ ;B=x^2(1-x^2/20(1-x^2/42(1-x^2/72)))ST B,*AR2 ;(d_temp)=B||LD *AR4,B ;B=1MASR *AR2-,*AR3+,B,A ;A=1-x^2/6(1-x^2/20(1-x^2/42(1-x^2/72)))MPYA d_x ;B=x(1-x^2/6(1-x^2/20(1-x^2/42(1-x^2/72))))STH B,d_sinx ;sin(theta)RET.end*******************************************************中断向量文件vectors.asm******************************************************.title "vectors.asm".ref start.sect ".vectors"B start.end*******************************************************链接命令文件******************************************************vectors.objsinx.obj-O sinx.out-m sinx.map-estartMEMORY{PAGE 0:EPROM: org=0090H,len=0F70HVECS: org=0080H,len=0010HPAGE 1:SPRAM: org=1000H,len=1000HDARAM: org=2000H,len=2000H}SECTIONS{.text :>EPROM PAGE 0.data :>EPROM PAGE 0STACK :>SPRAM PAGE 1sin_vars :>DARAM PAGE 1coeff :>DARAM PAGE 1.vectors :>VECS PAGE 0}(2)编译、链接项目文件sinx.pjt。
波形发生器程序清单:ORG 0000HAJMP MAINORG 0000BHLJMP TOINTORG 0030HMAIN:MOV A,#30HMOV SP, AMOV 40H, #00H ;波形显初值MOV 41H,#00H ;频率显示初值MOV 42H,#00HMOV 43H,#00HMOV 44H,#00HMOV 45H,#00H ;参考电压显示初值MOV 46H,#00H ;设置标志初值MOV DPTR,#7FFCH ;初始化8255MOV A, #90HMOVX @DPTR,A;…………………LED显示子程序……………………………………………………;DISPLAY:MOV R2,H06H ;显示子程序MOV R1,#80HMOV R0,#40HDIS1:MOV DPTR,#7FFEH ;指向B口MOV A,R1MOVX @DPTR, ARR A ;形成下一次位选信号MOV R1 AMOV A,@R0 ;取显示数字MOV DPTR,#DISPLAYTABMOVC A,@A+DPTR ;由数字转换成显示段码MOV DPTR,#7EFFH ;指向A口MOV @DPTR, A ;送段码到A口LCALL DELAY ;显示延时INC R0DJNZ R2, DIS1 ;判断是否显示6次MOV A, #00HMOV P1, A ;熄灭波形指示灯AJMP KEYSPAN ;转到键盘管理子程序DELAY:MOV R3,#80H ;延时LOOP1:MOV R4,#0A0HDJNZ R4,$DJNZ R3,LOOP1RETDISPLAYTAB:DB 3FH,06H,5BH,4FH,66H ;0 1 2 3 4DB 6DH,7DH,07H,7FH,6FH ;5 6 7 8 9DB 40H ;—;…………………键盘管理子程序……………………………………………………;KEY SPAN:MOV A,#F0HCLR P2.7MOV R0, #FDH ;指向C口MOVX @R0, A ;输出列扫描查询码MOV A,@R0 ;读入行状态CJNE A,F0H,KEY1 ;有键闭合、转KEY1LJMP KEYSPANEND ;无键闭合、退出KEY1:LCALL DELAY10ms ;延时、去抖动CLR IE ;关闭定时中断MOV R1,#FEHKEY2:MOV A,R1CLR P2.7MOVX @R0, A ;输出列扫描码MOVX A,@R0 ;读入行状态和列状态ANL A,#F0H ;保留行状态CJNE A,#F0H,KEY3 ;有键闭合、转KEY3,无键闭合形成下一次列扫描码,并判断是否扫描四次MOV A,R1RL AMOV R1, AJB ACC.3,KEY2LJMP KEYSPANEND ;四次列扫描完毕,退出KEY3:MOV R2, A ;行码送R2中保存MOV A,R1 ;扫描码送A中ANL A,#0FH ;保留列码(低4位)ORL A,R2 ;列码在低4位,行码在高4位MOV R2, A ;列行码值保存在R2MOV DPTR,#KEYTAB ;指向键特征值表MOV R1,#00H ;从键值0开始比对KEY4:CLR AMOVC A,@A+DPTR ;取特征值XRL A,R2 ;列行码值与特征值比对JZ KEY5 ;A=0找到键特征值,转KEY5INC R1 ;形成下一个键值INC DPTR ;形成下一个特征值地址CJNE R1,#10H,KEY4 ;判断是否比对了16次,R1≠10H,转KEY4,否则,顺序执行LJMP KEYSPANEND ;退出KEY5:MOV A,#F0HCLR P2.7MOVC @R0, A ;输出查询码MOVC A,@R0 ;读入状态SETB P2.7CJNE A, #F0H, KEY5 ;等待键释放LCALL KEYPROCESS ;调用键功能子程序KEYSPANEND:LJMP DISPLAY ;返回到LED显示子程序开始处DELAY10ms:MOV R3,#0C8HLOOP2:MOV R4,#0A0HDJNZ R4,$DJNZ R3,LOOP2RET;…………………………键特征值表…………………………………………………………;KEYTAB:DB EEH,EDH,EBH,E7H ;0 1 2 3 DB DEH,DDH,DBH,D7H ;4 5 6 7DB CEH,CDH,CBH,C7H ;8 9 EN CLDB 7EH,7DH,7BH,77H ;W F V .;………………………键功能散转………………………………………………………;KWYREOCESS:MOV A,R1RL AMOV DPTR,#KEYPROTABJMP @A+DPTRKEYPROTAB: AJMP KEY_0_PROAJMP KEY_1_PROAJMP KEY_2_PROAJMP KEY_3_PROAJMP KEY_4_PROAJMP KEY_5_PROAJMP KEY_6_PROAJMP KEY_7_PROAJMP KEY_8_PROAJMP KEY_9_PROAJMP KEY_EN_PROAJMP KEY_CL_PROAJMP KEY_W_PROAJMP KEY_F_PROAJMP KEY_V_PROAJMP KEY_·_PRO;………………………………键功能处理子程序………………………………………………;KEY_0_PRO:MOV A,46H ;“0”键处理子程序CJNE A,#00H,D01SJMP D0ENDD01:CJNE A,#01H,D0ENDCJNE R5,#43H,D02SJMP D0ENDD02:MOV @R5,#0HINC R5D0END:RETKEY_1_PRO:MOV A,#46H ;“1”键处理子程序CJNE A,#00H,D11AJMP D1ENDD11:CJNE A,#01H,D12CJNE R5,#43H,F1AJMP D1ENDF1:MOV @R5,#01HINC R5AJMP D1ENDD12:CJNE A,#02H,D13MOV 45H,#01HSJMP D1ENDD13:MOV 40H,#01HD1END:RETKEY_2_PRO:MOV A,#46H ;“2”键处理子程序CJNE A,#00H,D21AJMP D2ENDD21:CJNE A,#01H,D22CJNE R5,#43H,F2AJMP D2ENDF2:MOV @R5,#02HINC R5AJMP D2ENDD22:CJNE A,#02H,D23MOV 45H,#02HSJMP D2ENDD23:MOV 40H,#02HD2END:RETKEY_3_PRO:MOV A,#46H ;“3”键处理子程序CJNE A,#00H,D31AJMP D3ENDD31:CJNE A,#01H,D32CJNE R5,#43H,F3AJMP D3ENDF3:MOV @R5,#03HINC R5AJMP D3ENDD32:CJNE A,#02H,D33MOV 45H,#03HSJMP D3ENDD33:MOV 40H,#03HD3END:RETKEY_4_PRO:MOV A,#46H :“4”键处理子程序CJNE A,#00H,D41AJMP D4ENDD41:CJNE A,#01H,D42CJNE R5,#43H,F4AJMP D4ENDF4:MOV @R5,#04HINC R5AJMP D4ENDD42:CJNE A,#02H,D43MOV 45H,#04HSJMP D4ENDD43:MOV 40H,#04HD4END:RETKEY_5_PRO:MOV A,46H ;“5”键处理子程序CJNE A,#00H,D51AJMP D5ENDD51: CJNE A, #01H, D52CJNE R7, #44H, F5AJMP D5ENDF5:MOV @R5, #00HINC R5AJMP D5ENDD52:CJNE A,#02H,D53MOV 45,#05HD53:RETKEY_6_PRO:RET ;“6”键处理子程序KEY_7_PRO:RET ;“7”键处理子程序KEY_8_PRO:RET ;“8”键处理子程序KEY_9_PRO:RET ;“9”键处理子程序KEY_EN_PRO:MOV A,40HCJNE A,#00H,EN1AJMP ENENDEN1:MOV A,45HCJNE A,#00H,VREFAJMP ENENDVREF:DPTR,#VREFTABMOVC A,@A+DPTRMOV R0, #FFHCLR P2.5 ;选中0832(1)MOCX @R0, A ;向0832(1)送参考电压编码MOV A,41HORL A,42HORL A,43HCJNE A,#00H,1KHZAJMP ENEND1KHZ:MOV A,41H ;1KHZ设置定时初值CJNE A,#01H,500HZMOV TMOD,#00HMOV TLO,#01HMOV THO,#0FFHAJMP OPEN_TI0500HZ:MOV A,42H ;500HZ设置定时初值CJNE A,#05H,200HZMOV TMOD,#00HMOV TLO,#01HMOV THO,#0FEHAJMP OPEN_TI0200HZ:CJNE A,#02H,100HZ ;200HZ设置定时初值MOV TMOD,#00HMOV TLO,#03HMOV THO,#0FBHAJMP OPEN_TI0100HZ:CJNE A,#01H,50HZ ;100HZ设置定时初值MOV TMOD,#00HMOV TLO,#08HMOV THO,#0F6HAJMP OPEN_TI050HZ:MOV A,43H ;50HZ设置定时初值CJNE A,#05H,20HZMOV TMOD,#00HMOV TLO,#0FHMOV THO,#0ECHAJMP OPEN_TI020HZ:CJNE A,#02H,10HZ ;20HZ设置定时初值MOV TMOD,#00HMOV TLO,#16HMOV THO,#90HAJMP OPEN_TI010HZ:CJNE A,#01H,ENEND ;10HZ设置定时初值MOV TMOD,#00HMOV TLO,#0BHMOV THO,#9EHAJMP OPEN_TI0OPEN_TI0:MOV TCON,#10H ;定时器0工作,运行位TR控制MOV IE,82H ;中断允许总控制,定时器0中断允许MOV R6,#00H ;样值初始编号ENEND:RETVREFTAB:DB 32H,68H,A2H,CDH,FFH ;1V 2V 3V 4V 5VKEY_CL_PRO:MOV A,#00H ;“CL”键处理子程序MOV R0,#40HCL1:MOV @R0, #40HINC R0CJNE R0, #46H, CL1MOV R5, AMOV TL0, #00HMOV TH0, #00HCLR TR0RETKEY_F_PRO:MOV A, #01H;“F”处理子程序MOV 46H, A ;(46H)=01H表示频率设置MOV R5, 42HMOV 41H #0AH ;频率LED位显示“- - - 0”MOV 42H #0AHMOV 43H #0AHRETKEY_V_PRO:MOV A, #02H ;“V”处理子程序MOV 46H, A ;(46H)=02H表示参考电压设置MOV 45H #0AH ;电压LED位显示“—”RETKEY_W_PRO:MOV A, #03H ;“W”处理子程序MOV 46H, A ;(46H)=03H表示波形选择MOV 40H #0AH ;波形LED位显示“—”RETKEY_·_PRO:RET ;“·”处理子程序;…………………………定时中断服务程序……………………………………………………;TOINT:PUSH PSWPUSH ACCPUSH DPHPUSH DPLPUSH R0PUSH R1PUSH R2PUSH R3PUSH R4 ;保护现场MOV R7, 40HLCALL WA VE1;调用波形产生子程序POP R4POP R3POP R2POP R1POP R0POP DPLPOP DPHPOP ACCPOP PSW;恢复现场RETI;返回断点处,执行主程序;…………………………波形产生子程序……………………………………………………;WA VE1:CJNE R7, #01H, W A VE2CLR P1.0MOV DPTR, #W_TAB1 ;指向方波表首址MOV A, R6MOVC A, @A+DPTRMOV DPTR, #0AFFFH ;指向DAC0832(2)MOVX @DPTR, AMOV A, R6INC AMOV R6, A ;指向下一个样值CJNE A, #32, W_ENDMOV R6, #00HAJMP W_ENDWA VE2:CJNE R7, #02H, W A VE3CLR P1.1MOV DPTR, #W_TAB2 ;指向正弦波表首址MOV A, R6MOVC A, @A+DPTRMOV DPTR, #0AFFFH ;指向DAC0832(2)MOVX @DPTR, AMOV A, R6INC AMOV R6, A ;指向下一个样值CJNE A, #32, W_ENDMOV R6, #00HAJMP W_ENDWA VE3:CJNE R7, #03H, W A VE4CLR P1.2MOV DPTR, #W_TAB3 ;指向三角波表首址MOV A, R6MOVC A, @A+DPTRMOV DPTR, #0AFFFH ;指向DAC0832(2)MOVX @DPTR, AMOV A, R6INC AMOV R6, A ;指向下一个样值CJNE A, #32, W_ENDMOV R6, #00HAJMP W_ENDWA VE4:CJNE R7, #04H, W_ENDCLR P1.3MOV DPTR, #W_TAB4 ;指向锯齿波表首址MOV A, R6MOVC A, @A+DPTRMOV DPTR, #0AFFFH ;指向DAC0832(2)MOVX @DPTR, AMOV A, R6INC AMOV R6, A ;指向下一个样值CJNE A, #32, W_ENDMOV R6, #00HW_END :RET ;返回中断服务程序执行;……………………………波形样值表……………………………………………………;W_TAB1:DB 0FFH, FFH, FFH, FFH, FFH, FFH, FFH, FFHDB 0FFH, FFH, FFH, FFH, FFH, FFH, FFH, FFHDB 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00HDB 00H, 00H, 00H, 00H, 00H, 00H, 00H, 00HW_TAB2:DB 98H, B0H, C6H, D9H, E9H, F5H, FCH, FFHDB FCH, F5H, E9H, D9H, C6H, B0H, 98H, 7FHDB 66H, 4EH, 38H, 25H, 15H, 0AH, 02H, 00HDB 02H, 0AH, 15H, 25H, 38H, 4EH, 66H, 7FHW_TAB3:DB 8FH, 9FH, 0AFH, BFH, CFH, DFH, EFH, FFHDB EFH, DFH, CFH, BFH, AFH, 9FH, 8FH, 7FHDB 6FH, 5FH, 4FH, 3FH, 2FH, 1FH, 0FH, 00HDB 0FH, 1FH, 2FH, 3FH, 4FH, 5FH, 6FH, 7FHW_TAB4:DB 0FH, 17H, 1FH, 27H, 2FH, 37H, 3FH, 47HDB 4FH, 57H, 5FH, 67H, 6FH, 77H, 7FH, 87HDB 8FH, 97H, 9FH, A7H, AFH, B7H, BFH, C7HDB CFH, D7H, DFH, E7H, EFH, F7H, FFH, 07HEND。
单片机实训报告(波形发生器)一、设计方案(1)、硬件基本设计思路本设计方案采用8051单片机和DAC0832将数字信号转化成模拟信号,并通过LM324运算放大器将信号进行处理,最终得到各种波形。
其中,波形的切换采用矩阵键盘通过外部中断0来实现。
(2)、软件基本设计思路首先,将基本波形通过程序进行编写,并调试成功;其次,再编写按键扫描子程序;最后,将按键程序放入中断中,并进行整体调试,直到调通为止。
(3)、程序说明略二、原理图波形发生器原理图三、程序JUCHI E QU 50HSANJI EQU 51HFANGB EQU 52HTIXIN EQU 53HKU EQU 55HORG 0000H ;程序入口AJMP MAIN ;指向主程序ORG 0003H ;主程序入口地址AJMP INTT0 ;指向按键中断程序ORG 0030H ;中断程序入口地址MAIN: ;主程序MOV P2,#00H ;将P2口初始化为0SETB EA ;开总中断SETB EX0 ;开启外部中断0SETB IT0 ;将外部中断0设置为下降沿有效MOV DPTR,#00FFH ;设置输入寄存器地址MOV JUCHI,#00H ;初始化MOV SANJI,#00HMOV FANGB,#00H;***************************************************START:MOV A,KU ;将键码送累加器ACJNE A,#00H,W1 ;将累加器A和00H比较,如果相等,则00键按下顺序执行,否则跳到W1再判断01键是否按下MOV SANJI,#00H ;屏蔽其他波形MOV FANGB,#00HMOV TIXIN,#00HAJMP JCB ;跳转到锯齿波形W1: CJNE A,#01H,W2 ;判断01键是否按下MOV JUCHI,#00H ;屏蔽其他波形MOV FANGB,#00HMOV TIXIN,#00HAJMP SJB ;跳转到三角波形W2: CJNE A,#02H,W3 ;判断02键是否按下MOV TIXIN,#00HMOV JUCHI,#00H ;屏蔽其他波形MOV SANJI,#00HAJMP FB ;跳转到方波W3: CJNE A,#03H,W4 ;判断03键是否按下,没有按下,跳转回去继续循环扫描MOV JUCHI,#00H ;屏蔽其他波形MOV FANGB,#00HAJMP TXB ;跳转到梯形波W4: AJMP START;**********************************************INTT0: ;中断程序;***********键盘扫描子程序KEY*****************KEY: ACALL KS ;调按键查询子程序,判断是否有键按下JNZ K1 ;有键按下,转移 WEI1跳转ACALL DELAY ;无键按下,调延时程序去抖AJMP K4 ;继续查询按键;***********键盘逐列扫描程序***********************************K1: ACALL DELAYACALL KS ;再次判别是否有键按下JNZ K2 ;有键按下,转移AJMP K4K2: MOV R3,#0FEH ;首列扫描字送R3MOV R4,#00H ;首列号送R4K3: MOV A,R3MOV P2,A ;列扫描字送P2口MOV P1,#0FFH ;初始化P1口MOV A,P1 ;读取行扫描值JB ACC.0,L1 ;第零行无键按下转查第一行为1跳转MOV A,#00H ;第零行有键按下,行首键号送AAJMP LK ;转求键号L1: JB ACC.1,NEXT ;第一行无键按下,转查下一列MOV A,#03HAJMP LK ;键扫描结束,返回;************************************************************NEXT:INC R4 ;修改列号MOV A,R3JNB ACC.2,KEY ;三列扫描完返回按键查询状态RL A ;未扫描完,改为下列扫描字MOV R3,A ;扫描字暂存R3AJMP K3 ;转列扫描程序LK: ADD A,R4 ;形成键码送AMOV KU,APUSH ACC ;键码入栈保护;**********************************************K4:ACALL KS ;等待键释放JNZ K4POP ACC ;键释放,弹栈送ARETI ;中断返回;**********按键查询子程序**************************************KS: ;MOV A,#00HMOV P2,#00H ;全扫描字送p2口MOV P1,#0FFHMOV A,P1 ;读入P1口状态CPL A ;变正逻辑,高电平表示有键按下ANL A,#0FH ;屏蔽高四位RET ;子程序返回;****************锯齿波***********************JCB:MOV A,JUCHI ;转换初值WW: MOVX @DPTR,A ;D/A转换INC A ;A自加1NOP ;延时CJNE A,#255,WW ;判断A是否加到255,若没有返回到WW继续加MOV JUCHI,AAJMP START;******************三角波********************SJB:MOV A,SANJI ;转换初值EE: MOVX @DPTR,A ;D/A转换INC ANOPCJNE A,#255,EEDEC AQQ: MOVX @DPTR,ADEC ANOPCJNE A,#00,QQMOV SANJI,AAJMP START;******************方波********************* FB:MOV A,FANGBMOVX @DPTR,AACALL DELAY3ACALL DELAY3CPL AMOVX @DPTR,AACALL DELAY3ACALL DELAY3MOV FANGB,APOP ACCAJMP START;***************梯形波**********************TXB:MOV A,TIXINSS: MOVX @DPTR,AINC AACALL DELAY3CJNE A,#255,SSACALL DELAY3ACALL DELAY3DEC AZZ: MOVX @DPTR,ADEC AACALL DELAY3CJNE A,#00,ZZACALL DELAY3ACALL DELAY3MOV TIXIN,AAJMP START;*******************************************************1ms DELAY3: MOV R0,#7DHDEL7: NOPNOPDJNZ R0,DEL7RET;*******************************************50毫秒延时子程序DELAY2: MOV R0,#05DEL5: MOV R1,#10DEL4: MOV R2,7DHDEL3: NOPNOPDJNZ R2,DEL3DJNZ R1,DEL4DJNZ R0,DEL5RET;******************************************END四、实训总结通过两周的实训,我们对单片机有了一个基本的认识和了解,我们学到了怎样从一个设计课题入手去编写相关程序,并通过硬件实现。
华南理工大学广州学院数字系统设计(VHDL)课程报告题目:波形发生器姓名:学号:序号:学院:班级:指导老师:完成时间: 2014-1-1 __题目:波形发生器一、 功能及原理介绍1、功能介绍此波形发生器,通过选择“00”、“01”、“10”、“11”,这四种模式来选择相应的波形输出,除此之外,它还可以产生一些其它的波形,利用MIF 文件生成器产生波形的MIF 文件,由此产生各种波形。
这个波形发生器可以用作信号发生器,产生一些自己所需要的信号。
2、原理介绍正弦信号发生器的结构由 3 部分组成:数据计数器或地址发生器、数据 ROM 和 D/A 。
性能良好的正弦信 号发生器的设计要求此 3 部分具有高速性能,且数据 ROM 在高速条件下,占用最少的逻辑资源,设计流程最便捷,波 形数据获最方便。
顶层文件any_bo.VHD 在FPGA 中实现,包含2 个部分:ROM 的地址 信号发生器由7 位计数器担任,和正弦数据ROM ,拒此,ROM 由LPM_ROM 模块构成能达到最优设计,LPM_ROM 底层是FPGA 中的EAB 或ESB 等。
地址发生器的时钟CLK 的输入频率 f0 与每周期的波形数据点数(在此选择 128 点)。
2.1.MIF 文件生成器的使用方法mif 文件就是存储器初始化文件,即memory initialization file ,用来配置RAM 或ROM 中的数据。
而产生MIF 文件的在这里有三种方法:(1)利用Quartus 自带的mif 编辑器、(2)利用mif 软件来生成、(3)用C 语言或者matlab 语言等来生成,而我就利用MIF 文件生成器MIF_Maker 2010来产生MIF 文件。
① 双击打开MIF_Maker 2010,如图选择模式00 0110 117位计数器(地址发生器)7位计数器(地址发生器)7位计数器(地址发生器)7位计数器(地址发生器)正弦波数据 存储ROM三角波数据 存储ROM方波数据 存储ROM锯齿波数据 存储ROM正弦波输出 三角波输出 方波输出 锯齿波输出首先我们对所需要的MIF文件对应的波形参数进行设置,如上图,在“查看”,并于此下拉菜单中选择“全局参数设置”,如选择波形参数:数据长度128,输出数据位宽8,数据格式十六进制(有的情况下需要选择符号类型),初始相位0度,按“确定”后,将会出现一波形编辑窗。
#include <reg52.h>#define uchar unsigned char#define uint unsigned intuchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88}; uchar code sin_tab[256]={0x80,0x86,0x8D,0x93,0x99,0x9F,0xA5,0xAB,0xB1,0xB7,0xBC,0xC2,0xC7,0xCC,0xD1,0xD6,0xDA,0xDF,0xE3,0xE7,0xEA,0xEE,0xF1,0xF4,0xF6,0xF8,0xFA,0xFC,0xFD,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFD,0xFB,0xF9,0xF7,0xF5,0xF2,0xEF,0xEC,0xE9,0xE5,0xE1,0xDD,0xD8,0xD4,0xCF,0xCA,0xC5,0xBF,0xBA,0xB4,0xAE,0xA8,0xA2,0x9C,0x96,0x90,0x89,0x83,0x80,0x79,0x72,0x6C,0x66,0x60,0x5A,0x55,0x4E,0x48,0x43,0x3D,0x38,0x33,0x2E,0x29,0x25,0x20,0x1C,0x18,0x15,0x11,0x0E,0x0B,0x09,0x07,0x05,0x03,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x04,0x06,0x08,0x0A,0x0D,0x10,0x13,0x16,0x1A,0x1E,0x22,0x27,0x2B,0x30,0x35,0x3A,0x40,0x45,0x4C,0x51,0x57,0x5D,0x63,0x69,0x6F,0x76,0x7C,};sbit fd =P1^0;sbit sind=P1^1;sbit sand=P1^2;sbit fang=P1^3;sbit sin=P1^4;sbit san=P1^5;sbit pl_jia=P3^2;sbit pl_jian=P3^3;sbit led1=P3^4;sbit led2=P3^5;sbit led3=P3^6;sbit led4=P3^7;sbit dacs=P3^0;sbit dawr=P3^1;uchar ledplay0,ledplay1,ledplay2,ledplay3;uint waveth,wavetl,frecount=500; //频率计数uint k,key;void timeinit(); //定义子函数void led();void dalayms(int xms) //延时程序{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void main() //主程序{timeinit(); /* 定时、中断初始化 */while(1) // 循环等待{led();}}void timeinit(){TMOD = 0x01; // T0使用定时模式,工作模式0,无门控位TH0 =waveth=(65536-57600/frecount)/256; // 为T0填入初值,定时时间TL0 =wavetl=(65536-57600/frecount)%256; // (65536-初值)*12/f=定时时长 EA = 1; // CPU开放中断ET0 = 1; // 允许定时器0中断TR0 = 1; // 启动T0}void led() //显示电路{ledplay0=frecount/1000; //千位ledplay1=frecount%1000/100; //百位ledplay2=frecount%100/10; //十位ledplay3=frecount%10;led1=1;P0=tab[ledplay0];dalayms(5);led1=0;led2=1;P0=tab[ledplay1];dalayms(5);led2=0;led3=1;P0=tab[ledplay2];dalayms(5);led3=0;led4=1;P0=tab[ledplay3];dalayms(5);led4=0;}void timer0_int () interrupt 1 // T0中断{bit flag;TH0 =(65536-57600/frecount)/256;TL0 =(65536-57600/frecount)%256; // 初值=晶振f/12/频率dacs=0;dawr=0;if(fang==0){ dalayms(10);if(fang==0) //方波{fd=0;sind=1;sand=1;k+=8;if(k<=128) P2=0;if(k>128&&k<256) P2=255;if(k>=256) k=0;}}if(sin==0){dalayms(10);if(sin==0) //正弦波{sind=0;fd=1;sand=1;k+=8;if(k>=256)k=0;P2=sin_tab[k];}}if(san==0){dalayms(10);if(san==0) //三角波{sand=0;fd=1;sind=1;if(flag==0){k=k+8;if(k<=128)flag=1;P2=k;}if (flag==1){k=256-k;if(k==0)flag=0;P2=k;}}}if(pl_jia==0) //频率减小{frecount-=10;if(frecount==0)frecount=1000;waveth=(65536-57600/frecount)/256;wavetl=(65536-57600/frecount)%256;}if(pl_jian==0) //频率增加{frecount+=10;if(frecount==1000)frecount=0;waveth=(65536-57600/frecount)/256; wavetl=(65536-57600/frecount)%256;。
说明计算机控制技术实验说明自控/计控原理下册包括计算机控制技术实验、控制系统实验和综合控制实验。
较多涉及到的是计算机控制的部分。
AEDK-labACT自控/计控原理教学实验系统的计控有以下几个特点:一.计算机控制的一些控制参数可在界面上直接修改。
由于自控/计控实验主要注重的是对系统原理的理解掌握和对系统参数的研究分析,而并不是对系统控制程序的具体研究编写上,因此AEDK-LabACT自控/计控原理教学实验系统的计控,设计了较为友好的实验界面,对于不同的被控对象,可以在界面上直接设定和修改各项控制参数,而不用在程序上进行复杂的修改设定,以免破坏原有的控制程序。
这种直接在界面上修改控制参数的方法既直观又方便,免去了修改编写程序时所花的大量精力。
1、在采样/保持控制系统分析实验中,采样周期可在显示界面的右上角进行修改。
2、PID控制中的P、Ti、Td参数及采样周期T;温度控制的PID参数、积分控制量和温度设置;电机调速控制中的PID参数、转速设置等,以便随时获得不同的控制要求。
3、最少拍控制和大林算法中控制参数Ki和Pi及采样周期T可直接修改获得不同的设计要求。
二.各个控制实验大项中分别列举了多种实验算法和设计方法1、在采样/保持器控制系统分析中,列举了不同控制系统的算法举例,供用户进行实验验证。
2、PID控制实验中,列举了标准PID控制算法、积分分离PID控制算法、非线性PID控制算法和积分分离——砰砰复式PID控制算法四种典型的PID控制算法;3、最少拍控制实验中,列举了两种不同控制系统的有纹波和无纹波控制算法和参数,都能够使系统达到稳定所需要的采样周期最少,而且在采样点的输出值能准确地跟踪输入信号,不存在静差。
4、大林算法实验中,列举了三种不同控制参数情况下的算法和控制效果,有严重振铃现象的大林算法、有微弱振铃现象的大林算法和无振铃现象的大林算法。
5、多变量解耦控制提供了二种不同的解耦控制装置设计算法,有采用微分方程直接建立差分方程设计解耦装置D(S) 和采用Z传递函数建立差分方程设计解耦装置D(S),每种算法还提供了四种不同的系统,有一阶开环、一阶闭环和两个不同系统的二阶闭环系统。
单片机定时器波形发生器是一种利用单片机的定时器功能来产生各种波形的设备。
以下是使用单片机定时器制作波形发生器的基本步骤:
选择合适的单片机:例如,常见的8051单片机或AVR单片机都可用于此目的。
配置单片机的定时器:大多数单片机都有内置的定时器,这些定时器可以根据配置产生定时中断。
编写程序:程序应该根据定时器的中断来切换输出引脚的电平,从而产生波形。
波形的形状(例如正弦波、方波等)和频率可以通过改变定时器的值和切换电平的逻辑来控制。
选择合适的输出电路:单片机的输出引脚可能无法直接驱动外部电路,因此需要合适的驱动电路。
另外,根据需要的波形和负载特性,可能需要使用适当的滤波电路。
测试和调试:编写完程序并搭建好电路后,需要进行测试和调试,以确保产生的波形符合预期。
制作单片机定时器波形发生器需要一定的电子和编程知识,如果对这方面不太熟悉,建议寻求专业人士的帮助。
学号XXXX大学单片机原理及应用A课程设计设计说明书四种波形发生器起止日期:2017 年 5 月29 日至2017 年 6 月9日学生姓名班级成绩指导教师(签字)控制与机械工程学院2017年6月9 日目录绪论 (1)1、设计目的 (2)2、课程设计题目和实现目标 (3)3、设计方案 (4)4、主要芯片介绍 (5)4.程序流程图 (9)5、Proteus仿真原理图 (10)6、设计心得体会 (11)参考文献 (12)绪论近年来,随着电子技术和微机计算机的迅速发展,单片机的档次不断提高,其应用领域也在不断的扩大,已在工业控制、尖端科学、智能仪器仪表、日用家电、汽车电子系统、办公自动化设备、个人信息终端及通信产品中得到了广泛的应用,成为现代电子系统中最重要的智能化的核心部件。
单片机即单片微型计算机。
(Single-Chip Microcomputer ),是集CPU ,RAM ,ROM ,定时,计数和多种接口于一体的微控制器。
它体积小,成本低,功能强,广泛应用于工业自动化上和智能产品。
本次基于51系列单片机实验平台开发课程设计,是根据我们所学习的单片机课程,按照大纲要求对我们进行的一次课程检验,是进行单片机课程训练的必要任务,也对我们掌握单片机应用有很大的帮助。
掌握单片机技术是一门不可或缺的技术,对我们将来的工作以及生活和学习都有很密切的联系。
实验主要包括,以STC89C52RC 单片机作为核心板,实现电路原理图设计,LCD显示模块、串口通信模块、数码管显示模块、LED流水灯、按键操作等电路的设计、焊接与仿真。
编程软件采用keil 4及proteus 7.8仿真软件进行仿真。
1、设计目的(1)利用所学单片机的理论知识进行软硬件整体设计,锻炼学生理论联系实际、提高我们的综合应用能力。
(2)我们这次的课程设计是以单片机为基础,设计并开发能输出多种波形(正弦波、三角波、锯齿波、方波、梯形波等)且频率、幅度可变的函数发生器。
波形发生器汇编语言程序:;T0832-5.asmIOY0 EQU 0DA00H ;片选IOY0对应的端口始地址DA0832 EQU IOY0+00H*4 ;DA0832的端口地址DANUM EQU 0FFHSTACK1 SEGMENT STACKDW 256 DUP(?)STACK1 ENDSDATA SEGMENTSTR1 DB '1. Triangle SQUARE Wave ',0AH,0DH,'$' ;定义显示的字符串方波STR2 DB '2. Triangle DELTA Wave ', 0AH,0DH,'$' ;定义显示的字符串三角波STR3 DB '3. Triangle SAWTOOTH Wave ', 0AH,0DH,'$' ;定义显示的字符串锯齿波STR4 DB '4. Triangle SINE Wave ', 0AH,0DH,'$' ;定义显示的字符串正弦波STR5 DB '5. EXIT ',0AH,0DH,'$' ;定义显示的字符串退出FLAG DB 0SIN DB 00H,02H,05H,09H,0FH,15H,1DH,25HDB 2EH,38H,43H,4FH,5AH,67H,73H,7FHDB 80H,8CH,98H,0A5H,0B0H,0BCH,0C7H,0D1HDB 0DAH,0E2H,0EAH,0F0H,0F6H,0FAH,0FDH,0FFHDB 0FFH,0FDH,0FAH,0F6H,0F0H,0EAH,0E2H,0DAHDB 0D1H,0C7H,0BCH,0B0H,0A5H,98H,8CH,80HDB 7FH,73H,67H,5AH,4FH,43H,38H,2EHDB 25H,1DH,15H,0Fh,09H,05H,02H,00HCODE SEGMENT USE16ASSUME CS:CODE,DS:DATA,SS:STACK1START: MOV AX,DATAMOV DS,AXMOV AX,STACK1MOV SS,AXMOV DX,OFFSET STR1 ;显示字符串1MOV AH,9INT 21HMOV DX,OFFSET STR2 ;显示字符串2MOV AH,9INT 21HMOV DX,OFFSET STR3 ;显示字符串3MOV AH,9INT 21HMOV DX,OFFSET STR4 ;显示字符串4MOV AH,9INT 21HMOV DX,OFFSET STR5 ;显示字符串5MOV AH,9INT 21HLOOP1:MOV AH,1 ;判断是否有按键按下INT 16HJZ LOOP2 ;无按键则跳回继续循环,有则退出MOV AH,0 ;读键盘INT 16HCMP AL,31HJZ SQUARECMP AL,32HJZ DELTACMP AL,33HJZ SAWTOOTHCMP AL,34HJNZ L05JMP SINEL05: CMP AL,35HJNZ LOOP2JMP QUITLOOP2:CMP FLAG,1JZ SQUARECMP FLAG,2JZ DELTACMP FLAG,3JZ SAWTOOTHCMP FLAG,4JZ SINEJMP LOOP1SQUARE:MOV FLAG,1MOV DX,DA0832 ;写00H,输出低电平MOV AL,00HOUT DX,ALMOV CX,DANUML03: CALL DALLYLOOP L03MOV DX,DA0832 ;写0FH,输出高电平 MOV AL,DANUMOUT DX,ALMOV CX,DANUML04: CALL DALLYLOOP L04JMP LOOP1DELTA:MOV FLAG,2MOV AL,00H ;D/A转换起始值UP: MOV DX,DA0832 ;启动D/A转换OUT DX,ALCALL DALLYINC ALCMP AL,DANUMJNE UPDOWN: MOV DX,DA0832OUT DX,ALCALL DALLYDEC ALCMP AL,00HJNE DOWNJMP LOOP1SAWTOOTH:MOV FLAG,3MOV AL,00H ;D/A转换起始值L01: MOV DX,DA0832 ;启动D/A转换OUT DX,ALCALL DALLYINC ALCMP AL,DANUMJNE L01JMP LOOP1SINE:MOV FLAG,4MOV SI,OFFSET SIN ;SI指向SINMOV CL,64 ;数据数为64个L02: MOV AL,[SI]MOV DX,DA0832 ;输入0832数据口 OUT DX,ALCALL DALLYINC SI ;指向下一个数据 DEC CL ;数据数减1JNZ L02JMP LOOP1QUIT: MOV AX,4C00H ;返回到DOSINT 21HDALLY PROC NEAR ;软件延时子程序 PUSH CXPUSH AXMOV CX,0010HD1: MOV AX,0100HD2: DEC AXJNZ D2LOOP D1POP AXPOP CXRETDALLY ENDPCODE ENDSEND START。
完整版基于单片机的函数信号发生器汇编语言__键盘显示..基于单片机的函数信号发生器完整版汇编__键盘显示摘要本文介绍一种用AT89C51单片机构成的波形发生器,可产生方波、三角波、正弦波、锯齿波等多种波形,波形的周期可用程序改变,并可根据需要选择单极性输出或双极性输出,具有线路简单、结构紧凑、性能优越等特点。
文章给出了源代码,通过仿真测试,其性能指标达到了设计要求。
关键词:单片机;DAC;信号发生器目录摘要............................................................... 目录............................................................... 第一章绪论..........................................................1.1单片机概述......................................................1.2信号发生器的分类................................................1.3研究内容........................................................ 第二章方案的设计与选择..............................................2.1方案的比较......................................................2.2设计原理........................................................2.3设计思想........................................................2.4设计功能........................................................ 第三章硬件设计......................................................3.1硬件原理框图....................................................3.2主控电路........................................................3.3数、模转换电路..................................................3.4按键接口电路....................................................3.5时钟电路........................................................3.6显示电路........................................................ 第四章软件设计......................................................4.1程序流程图...................................................... 第五章总结与展望.................................................... 致谢............................................................... 参考文献............................................................. 附录1电路原理图..................................................... 附录 2 源程序......................................................... 附录 3 器件清单......................................................第一章绪论1.1单片机概述随着大规模集成电路技术的发展,中央处理器(CPU)、随机存取存储器(RAM)、只读存储器(ROM)、(I/O)接口、定时器/计数器和串行通信接口,以及其他一些计算机外围电路等均可集成在一块芯片上构成单片微型计算机,简称为单片机。
关于微机原理与接口技术的波形设计课程设计任务书目录第一章微机应用系统课程设计的目的意义 (2)1.1 设计目的 (2)1.1课程在教学计划中的地位和作用 (2)第二章信号发生器系统软硬件设计任务 (3)2.1 设计内容及要求 (3)2.2 课程设计的要求 (3)第三章总体设计方案 (3)3.1 设计思想 (3)3.2 总体设计流程图 (4)第四章硬件设计 (4)4.1 硬件设计概要 (4)4.2 所用到的芯片及其各自功能说明 (4)4.3 硬件电路设计系统原理图 (6)第五章软件设计 (7)5.1 流程图及其说明 (7)5.2 源程序及其说明 (8)第六章软件系统的使用说明 (15)第七章收获、体会 (15)附录参考文献 (15)第一章微机应用系统课程设计的目的意义1.1设计目的通过该课程的学习使学生对微机系统有一个全面的了解、掌握常规芯片的使用方法、掌握简单微型计算机应用系统软硬的设计方法,进一步锻炼同学们在微型计算机应用方面的实际工作能力。
本设计主要能够完成对制定波形的形成,可以通过输入来改变频率。
此信号发生器可以很好的运用于有需要的场合。
1.2 课程在教学计划中的地位和作用《微型计算机原理与接口计数》课程是我们测控技术专业在这个学期学的一门基础课程。
通过该课程的学习使我们对微机系统有一个基本的了解、掌握常规芯片的使用方法、掌握简单微型计算机应用系统软硬的设计方法。
《微机应用系统设计与综合实验》是结合本学期的课程开设的一门实习,它的主要目的:通过课程设计还要进一步锻炼同学们在微型计算机应用方面的实际工作能力。
计算机科学在应用上得到飞速发展,因此,学习这方面的知识必须紧密联系实际:掌握这方面的知识更要强调解决实际问题的能力。
同学们要着重学会面对一个实际问题,如何去自己收集资料,如何自己去学习新的知识,如何自己去制定解决问题的方案并通过实践不断地提高分析和解决问题的能力。
第二章设计任务2.1 设计内容及要求本设计综合应用D/A转换器、定时器/计数器电路,中断技术:通过PC机定时,产生:锯齿波、三角波、正弦波等模拟信号输出,信号频率可通过PC机键盘调节。
ORG 0000HLJMP MAINORG 0100HMAIN: ;;;主程序;;;MOV R1,#20H ;;设定R1初值,使得后面数据存放时;;按20H,21H,22H的顺序存放LPKB: CLR F0 ;;初始化,错误程序标志位MOV P1,#0FFH ;;初始化P1,P2口MOV P2,#0FFH;;;;开始扫描键盘;;;;;CLR P1.0 ;;一列为0 ;;其中一行一行为0时,JNB P1.4,KB1 ;;扫描每一列是被拉低。
JNB P1.5,KB2 ;;可确定按键被按下。
JNB P1.6,KB3JNB P1.7,KB4MOV P1,#0FFHCLR P1.1JNB P1.4,KB5JNB P1.5,KB6JNB P1.6,KB7JNB P1.7,KB8MOV P1,#0FFHCLR P1.2JNB P1.4,KB9JNB P1.5,KB0JNB P1.7,KBBCJNE R1,#23H,LPKBLJMP KBAKB1: LJMP KB11 ;;指令超出查找范围,加个跳板。
KB2: LJMP KB21KB3: LJMP KB31KB4: LJMP KB41KB5: LJMP KB51KB6: LJMP KB61KB7: LJMP KB71KB8: LJMP KB81KB9: LJMP KB91KB0: LJMP KB01KBB: LJMP KBB1;;;;键盘选波位扫描程序;;;;;;PB: MOV P1,#0FFHCLR P1.3JNB P1.4,KBCJNB P1.5,KBDJNB P1.6,KBEJNB P1.7,KBFLJMP PBKBC: LJMP SANJIAOKBD: LJMP JVCHIKBE: LJMP FANGBOKBF: LJMP ZHENGXUAN;;;键盘数字,确定,取消,读取程序;;;KB11: MOV @R1,#01LCALL DIRINC R1KK1: MOV A,P1CJNE A,#11101110B,OUT1 ;;;判断按键是否被放开SJMP KK1 ;;;否则在此死循环直到按键被松开OUT1: LJMP LPKBKB21: MOV @R1,#02LCALL DIRINC R1KK2: MOV A,P1CJNE A,#11011110B,OUT2SJMP KK2OUT2: LJMP LPKBKB31: MOV @R1,#03LCALL DIRINC R1KK3: MOV A,P1CJNE A,#10111110B,OUT3SJMP KK3OUT3: LJMP LPKBKB41: MOV @R1,#04LCALL DIRINC R1KK4: MOV A,P1CJNE A,#01111110B,OUT4SJMP KK4OUT4: LJMP LPKBKB51: MOV @R1,#05LCALL DIRINC R1KK5: MOV A,P1CJNE A,#11101101B,OUT5SJMP KK5OUT5: LJMP LPKBKB61: MOV @R1,#06LCALL DIRINC R1KK6: MOV A,P1CJNE A,#11011101B,OUT6SJMP KK6OUT6: LJMP LPKBKB71: MOV @R1,#07LCALL DIRINC R1KK7: MOV A,P1CJNE A,#10111101B,OUT7SJMP KK7OUT7: LJMP LPKBKB81: MOV @R1,#08LCALL DIRINC R1KK8: MOV A,P1CJNE A,#01111101B,OUT8SJMP KK8OUT8: LJMP LPKBKB91: MOV @R1,#09LCALL DIRINC R1KK9: MOV A,P1CJNE A,#11101011,OUT9SJMP KK9OUT9: LJMP LPKBKB01: MOV @R1,#0LCALL DIRINC R1KK0: MOV A,P1CJNE A,#11011011,OUT0SJMP KK0OUT0: LJMP LPKBKBA: MOV R1,#20HMOV 20H,#00HMOV 21H,#00HMOV 22H,#00HLJMP LPKBKBB1: MOV A,P1CJNE A,#01111011B,OUTBSJMP KBB1OUTB: LCALL SWICH1CLR P2.0 ;;;调用数据处理程序JB F0,KBA ;;;数据处理之后不符合要求则F0被置1.LJMP PB ;;;符合要求就跳到选波程序;;;;;;数据处理程序;;;;;SWICH1: CJNE R1,#21H,LOOP1 ;判断是否只输入了一位数,否则调到LOOP1 LCALL YIWEI ;调用一位数处理子程序LOOP1: CJNE R1,#22H,LOOP2 ;判断是否只输入了两位数,否则调到LOOP2 LCALL LIANGWEI ;调用两位数处理子程序LOOP2: CJNE R1,#23H,LOOP3 ;判断是否只输入了三位数,否则调到LOOP3 LCALL SANWEI ;调用三位数处理子程序LOOP3: RET;;一位数处理YIWEI: MOV R2,20HRET;;两位数处理LIANGWEI:MOV B,#10MOV A,20HMUL ABADD A,21HMOV R2,ARET;;三位数处理SANWEI: CLR CY ;清零CYMOV A,20H ;用2减去20H内容SUBB A,#2 ;百位是否大于2,大于则ERRORJC ERRORMOV A,20H ;20H扩大100倍加上MOV B,#100 ;21H扩大10倍后的数MUL AB ;CY是否为1MOV 20H,A ;为1则ERRORMOV A,21HMOV B,#10MUL ABCLR CYADD A,20HJC ERRORADD A,22H ;21H为十位20H为百位加上22H的个位JC ERROR ;看看CY是否为1,是则ERRORMOV R2,A ;处理好的数送给R2用于延迟改变周期LJMP BK;;;错误程序,置1标志位,并初始化数码管ERROR: MOV A,#0FFHMOVX @DPTR,AMOV DPTR,#0BFFFHMOVX @DPTR,AMOV DPTR,#7FFFHMOVX @DPTR,ASETB F0BK: RET;;;;;显示子程序;;;;;DIR: CJNE R1,#21H,LP ;输入第一个数时LCALL DIR1 ;调用第一个显示程序LP: CJNE R1,#22H,LP1 ;输入第二个数时LCALL DIR2 ;调用第二个显示程序LP1: CJNE R1,#23H,BACK ;输入第三个数时LCALL DIR3 ;调用第三个显示程序BACK: RET;显示程序一位数DIR1: MOV DPTR,#TABMOV A,20HMOVC A,@A+DPTRMOV DPTR,#7FFFHMOVX @DPTR,ARET;显示程序两位数DIR2: MOV DPTR,#TABMOV A,21HMOVC A,@A+DPTRMOV DPTR,#7FFFHMOVX @DPTR,AMOV DPTR,#TABMOV A,20HMOVC A,@A+DPTRMOV DPTR,#0BFFFHMOVX @DPTR,ARET;显示程序三位数DIR3: MOV DPTR,#TABMOV A,22HMOVC A,@A+DPTRMOV DPTR,#7FFFHMOVX @DPTR,AMOV DPTR,#TABMOV A,21HMOVC A,@A+DPTRMOVX @DPTR,AMOV DPTR,#TABMOV A,20HMOVC A,@A+DPTRMOV DPTR,#0DFFFHMOVX @DPTR,ARET;;;;波形显示程序;;;;;JVCHI: CLR P2.4MOV A,#00HCC: MOV P3,ALCALL DLINC ALJMP CC SANJIAO:MOV A,#00H CCUP: MOV P3,ALCALL DLINC ACJNE A,#255,CCUP CCDW: MOV P3,ALCALL DLDEC ACJNE A,#255,CCDWLJMP SANJIAO FANGBO: MOV A,#00HMOV P3,ALCALL DELAYMOV A,#0FFHMOV P3,ALCALL DELAYLJMP FANGBO ZHENGXUAN:MOV DPTR,#TAB1MOV R0,#60HSIN: CLR AMOVC A,@A+DPTRMOV @R0,AINC DPTRINC R0CJNE R0,#80H,SINMOV R0,#60HSIN1: MOV A,@R0MOV P3,AINC R0LCALL DLCJNE R0,#7FH,SIN1SIN2: MOV A,@R0MOV P3,ADEC R0LCALL DLCJNE R0,#6DH,SIN2SIN3: MOV A,@R0CPL AMOV P3,AINC R0LCALL DLCJNE R0,#7FH,SIN3SIN4: MOV A,@R0CPL AMOV P3,ADEC R0LCALL DLCJNE R0,#6DH,SIN4LJMP SIN1DELAY: MOV R7,#250DJNZ R7,$DJNZ R2,DELAYRETDL: DJNZ R2,$NOPNOPNOPRETTAB: DB 0C0H,0F9H,0A4H,0B0H,99HDB 92H,82H,0F8H,80H,90HTAB1: DB 7FH,89H,94H,9FH,0AAH,0B4H,0C8H,0D1H,0D9H DB 0E0H,0E7H,0EDH,0F2H,0F7H,0FAH,0FCH,0FEH,0FFH END。
DDS波形发生器VHDL源码下面是一个DDS(Direct Digital Synthesis,数字直接合成)波形发生器的VHDL源码示例。
该波形生成器可以产生由时钟频率和相位累加器控制的正弦波。
注意,以下的源码仅仅是一个简单的示例,实际的DDS 波形发生器可能有更复杂的实现。
```vhdllibrary ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity DDS isgenericN : integer := 10;LOG2_N : integer := 4portclk : in std_logic;reset : in std_logic;sin_wave : out std_logic_vector (N-1 downto 0)end entity DDS;architecture behavioral of DDS issignal accumulator : unsigned (N-1 downto 0);signal phase : unsigned (N-1 downto 0);signal phase_inc : unsigned (N-1 downto 0);beginprocess (clk, reset)beginif reset = '1' thenaccumulator <= (others => '0');phase <= (others => '0');elsif rising_edge(clk) thenaccumulator <= accumulator + phase_inc;phase <= phase + phase_inc;end if;end process;process (phase)beginend process;phase_inc <= unsigned(resize(unsigned(2**LOG2_N), N)); end architecture behavioral;```上述源码中,我们定义了一个名为DDS波形发生器的实体,该实体具有三个主要端口:`clk`用于接收时钟信号,`reset`用于复位信号,`sin_wave`是输出的正弦波形。
--DDS波形发生器(Synplify pro 编译通过)--输出频率Fout = Fclk*2^M/2^N--分辨率Fclk/2^N--最大输出频率Fout = Fclk*50%(理论值,抽样定理)--版本1.0 2004/9/29 by JJJlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity DDS isgeneric(ACCWidth : Integer := 16); --相位累加器的长度2^N (2^ACCWidth)port (CLK: in std_logic; --系统时钟FClkSTEP: in std_logic_vector(ACCWidth-1 downto 0); --步进,即相位累加器的累加增量,控制输出频率2^M 频率控制字CHOICE: in std_logic_vector(1 downto 0); --波形选择信号"00":正弦; "01":三角波; "1 0":方波; "11":不输出(恒为低电平)-- DAOUT : out std_logic_vector(7 downto 0); --8位DA输出模拟信号,直通方式,如需时钟控制则要修改DAOUTX: out std_logic_vector(7 downto 0);DAOUTY: out std_logic_vector(7 downto 0));end;architecture DDS of DDS issignal ACC:std_logic_vector(ACCWidth-1 downto 0):=(others =>'0'); signal DAOUT:std_logic_vector(7 downto 0);beginprocess(CLK,STEP)beginif(CLK'event and CLK='1') thenACC<=ACC+STEP;end if;end process;process(CHOICE,ACC)begincase CHOICE iswhen "00"=> --正弦case ACC(ACCWidth-1 downto ACCWidth-8) iswhen "00000000" => DAOUT <= "10000000";when "00000001" => DAOUT <= "10000011";when "00000010" => DAOUT <= "10000110";when "00000011" => DAOUT <= "10001001";when "00000100" => DAOUT <= "10001101";when "00000101" => DAOUT <= "10010000";when "00000110" => DAOUT <= "10010011";when "00000111" => DAOUT <= "10010110";when "00001000" => DAOUT <= "10011001";when "00001010" => DAOUT <= "10011111"; when "00001011" => DAOUT <= "10100010"; when "00001100" => DAOUT <= "10100101"; when "00001101" => DAOUT <= "10101000"; when "00001110" => DAOUT <= "10101011"; when "00001111" => DAOUT <= "10101110"; when "00010000" => DAOUT <= "10110001"; when "00010001" => DAOUT <= "10110100"; when "00010010" => DAOUT <= "10110111"; when "00010011" => DAOUT <= "10111010"; when "00010100" => DAOUT <= "10111100"; when "00010101" => DAOUT <= "10111111"; when "00010110" => DAOUT <= "11000010"; when "00010111" => DAOUT <= "11000100"; when "00011000" => DAOUT <= "11000111"; when "00011001" => DAOUT <= "11001010"; when "00011010" => DAOUT <= "11001100"; when "00011011" => DAOUT <= "11001111"; when "00011100" => DAOUT <= "11010001"; when "00011101" => DAOUT <= "11010100"; when "00011110" => DAOUT <= "11010110"; when "00011111" => DAOUT <= "11011000"; when "00100000" => DAOUT <= "11011011"; when "00100001" => DAOUT <= "11011101";when "00100011" => DAOUT <= "11100001"; when "00100100" => DAOUT <= "11100011"; when "00100101" => DAOUT <= "11100101"; when "00100110" => DAOUT <= "11100111"; when "00100111" => DAOUT <= "11101001"; when "00101000" => DAOUT <= "11101010"; when "00101001" => DAOUT <= "11101100"; when "00101010" => DAOUT <= "11101110"; when "00101011" => DAOUT <= "11101111"; when "00101100" => DAOUT <= "11110001"; when "00101101" => DAOUT <= "11110010"; when "00101110" => DAOUT <= "11110100"; when "00101111" => DAOUT <= "11110101"; when "00110000" => DAOUT <= "11110110"; when "00110001" => DAOUT <= "11110111"; when "00110010" => DAOUT <= "11111001"; when "00110011" => DAOUT <= "11111010"; when "00110100" => DAOUT <= "11111010"; when "00110101" => DAOUT <= "11111011"; when "00110110" => DAOUT <= "11111100"; when "00110111" => DAOUT <= "11111101"; when "00111000" => DAOUT <= "11111110"; when "00111001" => DAOUT <= "11111110"; when "00111010" => DAOUT <= "11111111";when "00111100" => DAOUT <= "11111111"; when "00111101" => DAOUT <= "11111111"; when "00111110" => DAOUT <= "11111111"; when "00111111" => DAOUT <= "11111111"; when "01000000" => DAOUT <= "11111111"; when "01000001" => DAOUT <= "11111111"; when "01000010" => DAOUT <= "11111111"; when "01000011" => DAOUT <= "11111111"; when "01000100" => DAOUT <= "11111111"; when "01000101" => DAOUT <= "11111111"; when "01000110" => DAOUT <= "11111111"; when "01000111" => DAOUT <= "11111110"; when "01001000" => DAOUT <= "11111110"; when "01001001" => DAOUT <= "11111101"; when "01001010" => DAOUT <= "11111100"; when "01001011" => DAOUT <= "11111011"; when "01001100" => DAOUT <= "11111010"; when "01001101" => DAOUT <= "11111010"; when "01001110" => DAOUT <= "11111001"; when "01001111" => DAOUT <= "11110111"; when "01010000" => DAOUT <= "11110110"; when "01010001" => DAOUT <= "11110101"; when "01010010" => DAOUT <= "11110100"; when "01010011" => DAOUT <= "11110010";when "01010101" => DAOUT <= "11101111"; when "01010110" => DAOUT <= "11101110"; when "01010111" => DAOUT <= "11101100"; when "01011000" => DAOUT <= "11101010"; when "01011001" => DAOUT <= "11101001"; when "01011010" => DAOUT <= "11100111"; when "01011011" => DAOUT <= "11100101"; when "01011100" => DAOUT <= "11100011"; when "01011101" => DAOUT <= "11100001"; when "01011110" => DAOUT <= "11011111"; when "01011111" => DAOUT <= "11011101"; when "01100000" => DAOUT <= "11011011"; when "01100001" => DAOUT <= "11011000"; when "01100010" => DAOUT <= "11010110"; when "01100011" => DAOUT <= "11010100"; when "01100100" => DAOUT <= "11010001"; when "01100101" => DAOUT <= "11001111"; when "01100110" => DAOUT <= "11001100"; when "01100111" => DAOUT <= "11001010"; when "01101000" => DAOUT <= "11000111"; when "01101001" => DAOUT <= "11000100"; when "01101010" => DAOUT <= "11000010"; when "01101011" => DAOUT <= "10111111"; when "01101100" => DAOUT <= "10111100";when "01101110" => DAOUT <= "10110111"; when "01101111" => DAOUT <= "10110100"; when "01110000" => DAOUT <= "10110001"; when "01110001" => DAOUT <= "10101110"; when "01110010" => DAOUT <= "10101011"; when "01110011" => DAOUT <= "10101000"; when "01110100" => DAOUT <= "10100101"; when "01110101" => DAOUT <= "10100010"; when "01110110" => DAOUT <= "10011111"; when "01110111" => DAOUT <= "10011100"; when "01111000" => DAOUT <= "10011001"; when "01111001" => DAOUT <= "10010110"; when "01111010" => DAOUT <= "10010011"; when "01111011" => DAOUT <= "10010000"; when "01111100" => DAOUT <= "10001101"; when "01111101" => DAOUT <= "10001001"; when "01111110" => DAOUT <= "10000110"; when "01111111" => DAOUT <= "10000011"; when "10000000" => DAOUT <= "10000000"; when "10000001" => DAOUT <= "01111101"; when "10000010" => DAOUT <= "01111010"; when "10000011" => DAOUT <= "01110111"; when "10000100" => DAOUT <= "01110011"; when "10000101" => DAOUT <= "01110000";when "10000111" => DAOUT <= "01101010"; when "10001000" => DAOUT <= "01100111"; when "10001001" => DAOUT <= "01100100"; when "10001010" => DAOUT <= "01100001"; when "10001011" => DAOUT <= "01011110"; when "10001100" => DAOUT <= "01011011"; when "10001101" => DAOUT <= "01011000"; when "10001110" => DAOUT <= "01010101"; when "10001111" => DAOUT <= "01010010"; when "10010000" => DAOUT <= "01001111"; when "10010001" => DAOUT <= "01001100"; when "10010010" => DAOUT <= "01001001"; when "10010011" => DAOUT <= "01000110"; when "10010100" => DAOUT <= "01000100"; when "10010101" => DAOUT <= "01000001"; when "10010110" => DAOUT <= "00111110"; when "10010111" => DAOUT <= "00111100"; when "10011000" => DAOUT <= "00111001"; when "10011001" => DAOUT <= "00110110"; when "10011010" => DAOUT <= "00110100"; when "10011011" => DAOUT <= "00110001"; when "10011100" => DAOUT <= "00101111"; when "10011101" => DAOUT <= "00101100"; when "10011110" => DAOUT <= "00101010";when "10100000" => DAOUT <= "00100101"; when "10100001" => DAOUT <= "00100011"; when "10100010" => DAOUT <= "00100001"; when "10100011" => DAOUT <= "00011111"; when "10100100" => DAOUT <= "00011101"; when "10100101" => DAOUT <= "00011011"; when "10100110" => DAOUT <= "00011001"; when "10100111" => DAOUT <= "00010111"; when "10101000" => DAOUT <= "00010110"; when "10101001" => DAOUT <= "00010100"; when "10101010" => DAOUT <= "00010010"; when "10101011" => DAOUT <= "00010001"; when "10101100" => DAOUT <= "00001111"; when "10101101" => DAOUT <= "00001110"; when "10101110" => DAOUT <= "00001100"; when "10101111" => DAOUT <= "00001011"; when "10110000" => DAOUT <= "00001010"; when "10110001" => DAOUT <= "00001001"; when "10110010" => DAOUT <= "00000111"; when "10110011" => DAOUT <= "00000110"; when "10110100" => DAOUT <= "00000110"; when "10110101" => DAOUT <= "00000101"; when "10110110" => DAOUT <= "00000100"; when "10110111" => DAOUT <= "00000011";when "10111001" => DAOUT <= "00000010"; when "10111010" => DAOUT <= "00000001"; when "10111011" => DAOUT <= "00000001"; when "10111100" => DAOUT <= "00000001"; when "10111101" => DAOUT <= "00000000"; when "10111110" => DAOUT <= "00000000"; when "10111111" => DAOUT <= "00000000"; when "11000000" => DAOUT <= "00000000"; when "11000001" => DAOUT <= "00000000"; when "11000010" => DAOUT <= "00000000"; when "11000011" => DAOUT <= "00000000"; when "11000100" => DAOUT <= "00000001"; when "11000101" => DAOUT <= "00000001"; when "11000110" => DAOUT <= "00000001"; when "11000111" => DAOUT <= "00000010"; when "11001000" => DAOUT <= "00000010"; when "11001001" => DAOUT <= "00000011"; when "11001010" => DAOUT <= "00000100"; when "11001011" => DAOUT <= "00000101"; when "11001100" => DAOUT <= "00000110"; when "11001101" => DAOUT <= "00000110"; when "11001110" => DAOUT <= "00000111"; when "11001111" => DAOUT <= "00001001"; when "11010000" => DAOUT <= "00001010";when "11010010" => DAOUT <= "00001100"; when "11010011" => DAOUT <= "00001110"; when "11010100" => DAOUT <= "00001111"; when "11010101" => DAOUT <= "00010001"; when "11010110" => DAOUT <= "00010010"; when "11010111" => DAOUT <= "00010100"; when "11011000" => DAOUT <= "00010110"; when "11011001" => DAOUT <= "00010111"; when "11011010" => DAOUT <= "00011001"; when "11011011" => DAOUT <= "00011011"; when "11011100" => DAOUT <= "00011101"; when "11011101" => DAOUT <= "00011111"; when "11011110" => DAOUT <= "00100001"; when "11011111" => DAOUT <= "00100011"; when "11100000" => DAOUT <= "00100101"; when "11100001" => DAOUT <= "00101000"; when "11100010" => DAOUT <= "00101010"; when "11100011" => DAOUT <= "00101100"; when "11100100" => DAOUT <= "00101111"; when "11100101" => DAOUT <= "00110001"; when "11100110" => DAOUT <= "00110100"; when "11100111" => DAOUT <= "00110110"; when "11101000" => DAOUT <= "00111001"; when "11101001" => DAOUT <= "00111100";when "11101011" => DAOUT <= "01000001";when "11101100" => DAOUT <= "01000100";when "11101101" => DAOUT <= "01000110";when "11101110" => DAOUT <= "01001001";when "11101111" => DAOUT <= "01001100";when "11110000" => DAOUT <= "01001111";when "11110001" => DAOUT <= "01010010";when "11110010" => DAOUT <= "01010101";when "11110011" => DAOUT <= "01011000";when "11110100" => DAOUT <= "01011011";when "11110101" => DAOUT <= "01011110";when "11110110" => DAOUT <= "01100001";when "11110111" => DAOUT <= "01100100";when "11111000" => DAOUT <= "01100111";when "11111001" => DAOUT <= "01101010";when "11111010" => DAOUT <= "01101101";when "11111011" => DAOUT <= "01110000";when "11111100" => DAOUT <= "01110011";when "11111101" => DAOUT <= "01110111";when "11111110" => DAOUT <= "01111010";when "11111111" => DAOUT <= "01111101"; when others => DAOUT <= (others =>'0');end case;when "01"=> --三角波case ACC(ACCWidth-1) iswhen '0' => DAOUT <= ACC(ACCWidth-2 downto ACCWidth-9); --模二加,左移一位 when '1' => DAOUT <= ("11111111" - ( ACC(ACCWidth-2 downto ACCWidth-9) )); when others => DAOUT <= (others =>'0');end case;when "10"=> --方波case ACC(ACCWidth-1) iswhen '0' => DAOUT <= (others =>'0');when '1' => DAOUT <= (others =>'1');when others => DAOUT <= (others =>'0');end case ;when "11" => DAOUT <= ACC(ACCWidth-1 downto ACCWidth-8);when others => DAOUT <= (others =>'0');end case;end process;end;component DDSport(clk: in std_logic;COSINE: out std_logic_vector(13 downto 0));end component;。
波形发生器汇编语言程序:
;T0832-5.asm
IOY0 EQU 0DA00H ;片选IOY0对应的端口始地址
DA0832 EQU IOY0+00H*4 ;DA0832的端口地址
DANUM EQU 0FFH
STACK1 SEGMENT STACK
DW 256 DUP(?)
STACK1 ENDS
DATA SEGMENT
STR1 DB '1. Triangle SQUARE Wave ',0AH,0DH,'$' ;定义显示的字符串方波STR2 DB '2. Triangle DELTA Wave ', 0AH,0DH,'$' ;定义显示的字符串三角波STR3 DB '3. Triangle SAWTOOTH Wave ', 0AH,0DH,'$' ;定义显示的字符串锯齿波STR4 DB '4. Triangle SINE Wave ', 0AH,0DH,'$' ;定义显示的字符串正弦波STR5 DB '5. EXIT ',0AH,0DH,'$' ;定义显示的字符串退出FLAG DB 0
SIN DB 00H,02H,05H,09H,0FH,15H,1DH,25H
DB 2EH,38H,43H,4FH,5AH,67H,73H,7FH
DB 80H,8CH,98H,0A5H,0B0H,0BCH,0C7H,0D1H
DB 0DAH,0E2H,0EAH,0F0H,0F6H,0FAH,0FDH,0FFH
DB 0FFH,0FDH,0FAH,0F6H,0F0H,0EAH,0E2H,0DAH
DB 0D1H,0C7H,0BCH,0B0H,0A5H,98H,8CH,80H
DB 7FH,73H,67H,5AH,4FH,43H,38H,2EH
DB 25H,1DH,15H,0Fh,09H,05H,02H,00H
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA,SS:STACK1
START: MOV AX,DATA
MOV DS,AX
MOV AX,STACK1
MOV SS,AX
MOV DX,OFFSET STR1 ;显示字符串1
MOV AH,9
INT 21H
MOV DX,OFFSET STR2 ;显示字符串2
MOV AH,9
INT 21H
MOV DX,OFFSET STR3 ;显示字符串3
MOV AH,9
INT 21H
MOV DX,OFFSET STR4 ;显示字符串4
MOV AH,9
INT 21H
MOV DX,OFFSET STR5 ;显示字符串5
MOV AH,9
INT 21H
LOOP1:
MOV AH,1 ;判断是否有按键按下
INT 16H
JZ LOOP2 ;无按键则跳回继续循环,有则退出
MOV AH,0 ;读键盘
INT 16H
CMP AL,31H
JZ SQUARE
CMP AL,32H
JZ DELTA
CMP AL,33H
JZ SAWTOOTH
CMP AL,34H
JNZ L05
JMP SINE
L05: CMP AL,35H
JNZ LOOP2
JMP QUIT
LOOP2:
CMP FLAG,1
JZ SQUARE
CMP FLAG,2
JZ DELTA
CMP FLAG,3
JZ SAWTOOTH
CMP FLAG,4
JZ SINE
JMP LOOP1
SQUARE:
MOV FLAG,1
MOV DX,DA0832 ;写00H,输出低电平
MOV AL,00H
OUT DX,AL
MOV CX,DANUM
L03: CALL DALLY
LOOP L03
MOV DX,DA0832 ;写0FH,输出高电平 MOV AL,DANUM
OUT DX,AL
MOV CX,DANUM
L04: CALL DALLY
LOOP L04
JMP LOOP1
DELTA:
MOV FLAG,2
MOV AL,00H ;D/A转换起始值UP: MOV DX,DA0832 ;启动D/A转换
OUT DX,AL
CALL DALLY
INC AL
CMP AL,DANUM
JNE UP
DOWN: MOV DX,DA0832
OUT DX,AL
CALL DALLY
DEC AL
CMP AL,00H
JNE DOWN
JMP LOOP1
SAWTOOTH:
MOV FLAG,3
MOV AL,00H ;D/A转换起始值
L01: MOV DX,DA0832 ;启动D/A转换
OUT DX,AL
CALL DALLY
INC AL
CMP AL,DANUM
JNE L01
JMP LOOP1
SINE:
MOV FLAG,4
MOV SI,OFFSET SIN ;SI指向SIN
MOV CL,64 ;数据数为64个
L02: MOV AL,[SI]
MOV DX,DA0832 ;输入0832数据口 OUT DX,AL
CALL DALLY
INC SI ;指向下一个数据 DEC CL ;数据数减1
JNZ L02
JMP LOOP1
QUIT: MOV AX,4C00H ;返回到DOS
INT 21H
DALLY PROC NEAR ;软件延时子程序 PUSH CX
PUSH AX
MOV CX,0010H
D1: MOV AX,0100H
D2: DEC AX
JNZ D2
LOOP D1
POP AX
POP CX
RET
DALLY ENDP
CODE ENDS
END START。