给51黑电子论坛的朋友们分享一个51单片机做的简易波形发生器,包含完整的汇编语言源程序.用的DAC0832芯片
源码:
- ORG 0000H
- ;定义存储标志位的地址
- SEL EQU 30H ;存波形的地址 00:方波 01:三角波 02:正弦波
- RANGE EQU 31H ;存幅值的地址
- FREQ EQU 32H ;存频率的地址
- INC_F1 EQU 35H ;三角波自加或自减标识,=幅值/255
- INC_F2 EQU 36H ;三角波自加或自减标识,=幅值/255
- RAN_SIN EQU 37H ;正弦波幅值
- ;定义按键的地址
- AN_COM EQU P2.1 ;发出低电平,用于检测按键
- AN_FREQ EQU P2.2 ;调节频率按键
- AN_RANGE EQU P2.3 ;调节幅度按键
- AN_SEL EQU P2.4 ;变换波形按键
- AN_RST EQU P3.1
- ;定义12864的控制端
- E EQU P2.0 ;数据或命令读写驱动信号,操作时应拉高,操作完拉低即可
- RW EQU P2.6 ;读写控制端
- RS EQU P2.5 ;选择写控制命令或数据命令
- CS1 EQU P2.7 ;选屏幕
- CS2 EQU P3.0
-
- ;12864存取命令的地址
- L_COM EQU 33H ;
- Y EQU 34H ;存列地址
- X EQU 38H ;存页地址
- PG EQU 39H ;存操作页数
- LINE EQU 40H ;存操作列数
- NUM EQU 41H ;循环次数
- SNUM EQU 42H ;待显示的数字
- TEMP EQU 43H ;临时数据
- LJMP MAIN
- ORG 0003H ;外部中断0中断入口地址
- LJMP COUNT_SER ;外部中断中断服务程序
- ORG 0100H
- MAIN: ;数据初始化
- MOV SP,#60H
- CLR A
- CLR C
- CLR AN_COM
- MOV SEL,#00H ;默认方波
- MOV RANGE,#7FH ;默认中间幅值
- MOV FREQ,#00 ;默认最大频率
- LCALL CLEAN
- MOV P1,#00H
- MOV Y,#00H
- MOV INC_F1,#00H
- MOV INC_F2,#00H
- MOV RAN_SIN,#01H
- LCALL LCD_INIT
- LCALL SHOW_MSG
- LCALL SHOW_VH
- LCALL SHOW_SQR
- MOV X,#0BAH
- MOV Y,#5FH
- MOV SNUM,#05H
- LCALL SHOW_NUM
-
- ;外部中断0初始化
- SETB IT0
- SETB EX0 ;允许外部中断0
- SETB EA ;开总中断
- ;停机等待中断,到后期可以改为一些一直执行的程序,如显示,输出等
- MAIN_L: MOV A,SEL
- MOV DPTR,#WAVE
- JMP @A+DPTR
- SJMP MAIN_L
-
- ;方波,不可调频
- SQUARE: MOV R5,SEL
- CJNE R5,#00H,WAVE_BACK
- MOV P1,RANGE ;幅值
- LCALL DELAY_Xus
- LCALL DELAY_100us
- MOV P1,#00H
- LCALL DELAY_Xus
- LCALL DELAY_100us
- SJMP SQUARE
- ;三角波,调幅,频率也会变,改 默认最大幅值,最小频率
- R_SEL: MOV R5,SEL
- CJNE R5,#01H,WAVE_BACK
- LCALL JINC_F
- RECT: DJNZ INC_F1,RECT
- INC P1
- MOV A,P1
- ; LCALL DELAY_10us
- CJNE A,RANGE,RECT
- MOV INC_F1,INC_F2
- DOWN: DJNZ INC_F2,DOWN
- DEC P1
- MOV R0,P1
- CJNE R0,#00H,DOWN
- MOV INC_F2,INC_F1
- ; LCALL DELAY_10us
- LJMP R_SEL
- RET
-
- ;判断三角波中是一个循环加多少
- JINC_F: MOV A,#0FFH
- MOV B,RANGE
- DIV AB
- MOV INC_F1,A
- MOV INC_F2,A
- RET
- ;正弦波,用查表法,不可调频,不可调幅
- SIN: MOV DPTR,#TABLE_SIN
- S_SEL: MOV R5,SEL
- CJNE R5,#02H,WAVE_BACK
- SL: CLR A
- MOVC A,@A+DPTR
- MOV B,RAN_SIN
- DIV AB
- MOV P1,A
- LCALL DELAY_10us
- INC DPTR
- MOV A,#01H
- MOVC A,@A+DPTR
- CJNE A,#21H,S_SEL
- LJMP SIN
- ;调用波形返回函数
- WAVE_BACK: RET
- ;中断服务程序
- ;外部中断0中断服务程序 ,判断是哪个按键被按下
- COUNT_SER: CPL P3.5
- JNB AN_FREQ,FREQ_FUNC
- JNB AN_RANGE,RANGE_FUNC
- JNB AN_SEL,SEL_FUNC
- JNB AN_RST,SEL_RST
- RETI
- ;调节频率按钮
- FREQ_FUNC: INC FREQ
- RETI
- ;调节幅值按钮
- RANGE_FUNC: INC RANGE
- INC RAN_SIN
- MOV R6,RAN_SIN
- CJNE R6,#00H,FUNC_RET
- MOV RAN_SIN,#01H
- RETI
- ;选择波形标志位加一
- SEL_FUNC: INC SEL
- MOV R6,SEL
- CJNE R6,#03H,FUNC_RET
- MOV SEL,#00H
- RETI
- FUNC_RET: RETI
- ;复位部分
- SEL_RST: CLR A
- CLR C
- CLR AN_COM
- MOV SEL,#00H ;默认方波
- MOV RANGE,#7FH ;默认中间幅值
- MOV FREQ,#00 ;默认最大频率
- MOV P1,#00H
- MOV Y,#00H
- MOV INC_F1,#00H
- MOV INC_F2,#00H
- MOV RAN_SIN,#01H
- RETI
- ;LCD显示部分:
- ;1、查看LCD是否处于空闲
- CHK_BUSY: MOV P0,#0FH ;必须让p0.7为低,不然一直卡在死循环
- CLR RS
- SETB RW
- SETB E
- JB P0.7,$
- CLR E
- RET
- ;2、写命令
- ;写左命令
- WR_L_COM: CLR CS1
- SETB CS2
- LCALL CHK_BUSY ;判断LCD是否处于空闲
- NOP
- CLR RS
- CLR RW
- NOP
- SETB E
- MOV P0,L_COM
- NOP
- CLR E
- NOP
- RET
- ;写右命令
- WR_R_COM: SETB CS1
- CLR CS2
- LCALL CHK_BUSY ;判断LCD是否处于空闲
- NOP
- CLR RS
- CLR RW
- NOP
- SETB E
- MOV P0,L_COM
- NOP
- CLR E
- NOP
- RET
- ;全屏写命令
- WR_A_COM: CLR CS1
- CLR CS2
- LCALL CHK_BUSY ;判断LCD是否处于空闲
- NOP
- CLR RS
- CLR RW
- NOP
- SETB E
- MOV P0,L_COM
- NOP
- CLR E
- NOP
- RET
- ;3、写数据
- ;写左半屏数据
- WR_L_B: CLR CS1
- SETB CS2
- LCALL CHK_BUSY
- NOP
- SETB RS
- CLR RW
- SETB E
- MOV P0,L_COM
- NOP
- CLR E
- NOP
- RET
- ;写右半屏数据
- WR_R_B: SETB CS1
- CLR CS2
- LCALL CHK_BUSY
- NOP
- SETB RS
- CLR RW
- SETB E
- MOV P0,L_COM
- NOP
- CLR E
- NOP
- RET
- ;全屏写数据
- WR_A_B: CLR CS1
- CLR CS2
- LCALL CHK_BUSY
- NOP
- SETB RS
- CLR RW
- SETB E
- MOV P0,L_COM
- NOP
- CLR E
- NOP
- RET
- ;4、初始化部分:
- LCD_INIT: MOV L_COM,#3EH
- LCALL WR_A_COM ;关显示
- MOV L_COM,#3FH
- LCALL WR_A_COM ;开显示
- ; 清屏指令
- CLEAN: MOV PG,#08H
- MOV X,#0B8H
- MOV Y,#40H
- CL1: MOV LINE,#128
- MOV L_COM,X
- LCALL WR_A_COM
- MOV L_COM,Y
- LCALL WR_A_COM
- CL2: MOV L_COM,#00H
- LCALL WR_A_B
- DJNZ LINE,CL2
- MOV LINE,#128
- INC X
- DJNZ PG,CL1
- RET
- ;左半屏显示数字 可以用了
- SHOW_NUM: MOV A,SNUM
- MOV B,#10H
- MUL AB ;没有溢出,结果完全存在A中
- MOV TEMP,A
- MOV DPTR,#NUM_TAB
- MOV PG,#02H ;要显示的页数
- SN2: MOV LINE,#08H ;要显示的列数
- MOV L_COM,X ;设置页
- LCALL WR_L_COM
- MOV L_COM,Y ;设置列
- LCALL WR_L_COM
- SN1: MOV A,TEMP
- MOVC A,@A+DPTR
- MOV L_COM,A
- LCALL WR_L_B ;写数据
- INC DPTR
- DJNZ LINE,SN1
- INC X
- DJNZ PG,SN2
- RET
-
- ;显示提示子程序 显示 Vpp FRQ (峰-峰值,频率)
- SHOW_MSG: MOV NUM,#02H
- MOV PG,#02H
- MOV LINE,#32 ;写32列,构成循环
- MOV Y,#40H
- MOV X,#0B8H
- MOV DPTR,#VppFRQ
- NUM2: MOV L_COM,Y
- MOV Y,#40H
- LCALL WR_L_COM
- MOV L_COM,X
- LCALL WR_L_COM
- WR1: CLR A
- MOVC A,@A+DPTR
- MOV L_COM,A
- LCALL WR_L_B
- INC DPTR
- DJNZ LINE,WR1
- INC X
- MOV LINE,#32
- DJNZ PG,NUM2
- MOV X,#0BCH
- MOV PG,#02H
- MOV LINE,#32
- DJNZ NUM,NUM2
- RET
- ;显示单位
- SHOW_VH: MOV NUM,#02H
- MOV PG,#02H
- MOV LINE,#08H ;V字母要写8列,构成循环
- MOV Y,#76H
- MOV X,#0BAH
- MOV DPTR,#VH
- VH2: MOV L_COM,Y
- LCALL WR_L_COM
- MOV L_COM,X
- LCALL WR_L_COM
- VH1: CLR A
- MOVC A,@A+DPTR
- MOV L_COM,A
- LCALL WR_L_B
- INC DPTR
- DJNZ LINE,VH1
- INC X
- MOV LINE,#08H
- DJNZ PG,VH2
- MOV X,#0BEH
- MOV Y,#70H
- MOV PG,#02H
- MOV LINE,#16
- DJNZ NUM,VH2
- RET
- ;右半屏显示波形
- ;显示方波 借鉴LCD清屏程序
- SHOW_SQR: MOV PG,#02H
- MOV X,#0B8H
- MOV Y,#40H
- SQR1: MOV LINE,#32
- MOV L_COM,X
- LCALL WR_R_COM
- MOV L_COM,Y
- LCALL WR_R_COM
- SQR2: MOV L_COM,#0C0H
- LCALL WR_R_B
- DJNZ LINE,SQR2
- MOV Y,#5FH
- MOV L_COM,Y
- LCALL WR_R_COM
- MOV X,#0BFH
- MOV L_COM,X
- LCALL WR_R_COM
- MOV LINE,#32
- SQR3: MOV L_COM,#03H
- LCALL WR_R_B
- DJNZ LINE,SQR3
- LCALL SHOW_L
- RET
- ;显示方波一纵列
- SHOW_L: MOV PG,#07H
- MOV LINE,#02H
- MOV Y,#5FH
- LCALL WR_R_COM
- SL2: MOV X,#0B8H
- LCALL WR_R_COM
- SL1: MOV L_COM,#0FFH
- LCALL WR_R_B
- MOV L_COM,Y
- LCALL WR_R_COM
- INC X
- MOV L_COM,X
- LCALL WR_R_COM
- DJNZ PG,SL1
- RET
- ;延时函数部分:
- ;1、100us延时函数
- DELAY_100us: NOP
- MOV R6,#04H
- L1: MOV R7,#0AH
- L2: DJNZ R7,L2
- DJNZ R6,L1
- RET ;小伙子,记得子函数要加返回!!!!!
- ;
- DELAY_Xus: MOV A,FREQ
- JZ DE_BACK
- NOP
- MOV R6,FREQ
- L11: MOV R7,#0AH
- L22: DJNZ R7,L22
- DJNZ R6,L11
- RET ;小伙子,记得子函数要加返回!!!!!
- ;3、10us延时函数
- DELAY_10us: MOV A,FREQ
- JZ DE_BACK
- MOV R3,FREQ
- DJNZ R3,$
- DE_BACK: RET
-
- ;散转指令 里面除了可以用AJMP指令外,还能用LCALL指令
- WAVE: LCALL SQUARE
- LCALL R_SEL
- LCALL SIN
- ;正弦函数值表 128
- TABLE_SIN: DB 80H,83H,86H,89H,8DH,90H,93H,96H
- DB 99H,9CH,9FH,0A2H,0A5H,0A8H,0ABH,0AEH
- DB 0B1H,0B4H,0B7H,0BAH,0BCH,0BFH,0C2H,0C5H
- DB 0C7H,0CAH,0CCH,0CFH,0D1H,0D4H,0D6H,0D8H
- DB 0DAH,0DDH,0DFH,0E1H,0E3H,0E5H,0E7H,0E9H
- DB 0EAH,0ECH,0EEH,0EFH,0F1H,0F2H,0F4H,0F5H
- DB 0F6H,0F7H,0F8H,0F9H,0FAH,0FBH,0FCH,0FDH
- DB 0FDH,0FEH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
- DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FEH,0FDH
- DB 0FDH,0FCH,0FBH,0FAH,0F9H,0F8H,0F7H,0F6H
- DB 0F5H,0F4H,0F2H,0F1H,0EFH,0EEH,0ECH,0EAH
- DB 0E9H,0E7H,0E5H,0E3H,0E1H,0DEH,0DDH,0DAH
- DB 0D8H,0D6H,0D4H,0D1H,0CFH,0CCH,0CAH,0C7H
- DB 0C5H,0C2H,0BFH,0BCH,0BAH,0B7H,0B4H,0B1H
- DB 0AEH,0ABH,0A8H,0A5H,0A2H,9FH,9CH,99H
- DB 96H,93H,90H,8DH,89H,86H,83H,80H
- DB 80H,7CH,79H,78H,72H,6FH,6CH,69H
- DB 66H,63H,60H,5DH,5AH,57H,55H,51H
- DB 4EH,4CH,48H,45H,43H,40H,3DH,3AH
- DB 38H,35H,33H,30H,2EH,2BH,29H,27H
- DB 25H,22H,20H,1EH,1CH,1AH,18H,16H
- DB 15H,13H,11H,10H,0EH,0DH,0BH,0AH
- DB 09H,08H,07H,06H,05H,04H,03H,02H
- DB 02H,01H,00H,00H,00H,00H,00H,00H
- DB 00H,00H,00H,00H,00H,00H,01H,02H
- DB 02H,03H,04H,05H,06H,07H,08H,09H
- DB 0AH,0BH,0DH,0EH,10H,11H,13H,15H
- DB 16H,18H,1AH,1CH,1EH,20H,22H,25H
- DB 27H,29H,2BH,2EH,30H,33H,35H,38H
- DB 3AH,3DH,40H,43H,45H,48H,4CH,4EH
- DB 51H,55H,57H,5AH,5DH,60H,63H,66H
- DB 69H,6CH,6FH,72H,76H,79H,7CH,80H ,21H ;21H为结束标志位,这里偷懒了
- ;12864汉字库
- VppFRQ: DB 0FCH,0FCH, 00H, 00H, 00H,0FCH,0FCH, 00H
- DB 20H,0E0H,0C0H, 20H, 20H,0E0H,0C0H, 00H
- DB 20H,0E0H,0C0H, 20H, 20H,0E0H,0C0H, 00H
- DB 00H, 00H, 00H, 30H, 30H, 00H, 00H, 00H ; -Vpp:上部-
- DB 01H, 03H, 06H, 0CH, 06H, 03H, 01H, 00H ; -Vpp:下部- 峰峰值提示信息
- DB 40H, 7FH, 7FH, 48H, 08H, 0FH, 07H, 00H
- DB 40H, 7FH, 7FH, 48H, 08H, 0FH, 07H, 00H
- DB 00H, 00H, 00H, 06H, 06H, 00H, 00H, 00H
- DB 04H,0FCH,0FCH, 44H,0E4H, 0CH, 1CH, 00H
- DB 04H,0FCH,0FCH, 44H,0C4H,0FCH, 38H, 00H
- DB 0F8H,0FCH, 04H, 04H, 04H,0FCH,0F8H, 00H
- DB 00H, 00H, 00H, 30H, 30H, 00H, 00H, 00H ; FRQ上半部
- DB 08H, 0FH, 0FH, 08H, 00H, 00H, 00H, 00H ; FRQ下半部
- DB 08H, 0FH, 0FH, 00H, 00H, 0FH, 0FH, 00H
- DB 07H, 0FH, 08H, 0EH, 3CH, 3FH, 27H, 00H
- DB 00H, 00H, 00H, 06H, 06H, 00H, 00H, 00H
- VH: DB 0FCH,0FCH, 00H, 00H, 00H,0FCH,0FCH, 00H
- DB 01H, 03H, 06H, 0CH, 06H, 03H, 01H, 00H ; V
-
- DB 0FCH,0FCH, 40H, 40H, 40H,0FCH,0FCH, 00H
- DB 44h, 64h, 54h, 4Ch, 44h, 00H, 00H, 00H ;Hz的下半部
- DB 0FH, 0FH, 00H, 00H, 00H, 0FH, 0FH, 00H ;Hz的上半部
-
- NUM_TAB: DB 0F8H,0FCH, 04H,0C4H, 24H,0FCH,0F8H, 00H ; -0-
- DB 07H, 0FH, 09H, 08H, 08H, 0FH, 07H, 00H
-
- DB 00H, 10H, 18H,0FCH,0FCH, 00H, 00H, 00H ; -1-
- DB 00H, 08H, 08H, 0FH, 0FH, 08H, 08H, 00H
-
- DB 08H, 0CH, 84H,0C4H, 64H, 3CH, 18H, 00H ; -2-
- DB 0EH, 0FH, 09H, 08H, 08H, 0CH, 0CH, 00H
-
- DB 08H, 0CH, 44H, 44H, 44H,0FCH,0B8H, 00H ; -3-
- DB 04H, 0CH, 08H, 08H, 08H, 0FH, 07H, 00H
-
- DB 0C0H,0E0H,0B0H, 98H,0FCH,0FCH, 80H, 00H ; -4-
- DB 00H, 00H, 00H, 08H, 0FH, 0FH, 08H, 00H
-
- DB 7CH, 7CH, 44H, 44H,0C4H,0C4H, 84H, 00H ; -5-
- DB 04H, 0CH, 08H, 08H, 08H, 0FH, 07H, 00H
-
- DB 0F0H,0F8H, 4CH, 44H, 44H,0C0H, 80H, 00H ; -6-
- DB 07H, 0FH, 08H, 08H, 08H, 0FH, 07H, 00H
-
- DB 0CH, 0CH, 04H, 84H,0C4H, 7CH, 3CH, 00H ; -7-
- DB 00H, 00H, 0FH, 0FH, 00H, 00H, 00H, 00H
-
- DB 0B8H,0FCH, 44H, 44H, 44H,0FCH,0B8H, 00H ; -8-
- DB 07H, 0FH, 08H, 08H, 08H, 0FH, 07H, 00H
-
- DB 38H, 7CH, 44H, 44H, 44H,0FCH,0F8H, 00H ; -9-
- DB 00H, 08H, 08H, 08H, 0CH, 07H, 03H, 00H
- END
复制代码
仿真工程文件和单片机汇编源程序下载:
简易波形发生器proteus仿真及源码.zip
(31.33 KB, 下载次数: 229)
|