信号函数发生器.docx
《信号函数发生器.docx》由会员分享,可在线阅读,更多相关《信号函数发生器.docx(17页珍藏版)》请在冰豆网上搜索。
信号函数发生器
函数信号发生器
一、函数信号发生器的技术指标
1、波形:
方波、正弦波、锯齿波;
2、幅值电压:
1V、2V、3V、4V、5V;
3、频率:
10HZ、20HZ、50HZ、100HZ、200HZ、500HZ、1KHZ;
二、操作设计
1、上电后,系统初始化,数码显示6个‘-’,等待输入设置命令。
2、按“幅值”、“频率”、“方波”、“正弦波”、“锯齿波”键进行相应的设置,数码管显示“-”。
输入相应参数,显示参数值,全部设置完毕后,按“Enter”键,数码管显示波形的编码,电压幅值,频率。
3、要停止使用函数信号发生器,可按复位按钮,将系统复位,然后关闭电源。
4、输入频率值的时候,一定要输入四位数。
二、硬件组成
由单片机、键盘、显示接口电路,波形转换(D/A)电路和电源等四部分构成。
1、单片机电路
功能:
形成扫描码,键值识别、键处理、参数设置;形成显示段码;产生定时中断;形成波形的数字编码,并输出到D/A接口电路。
电路如图1所示。
89C51的P1口作为键盘的接口。
P2口做为数码显示管的位选择接口。
用定时/计数器作为中断源。
不同的频率值对应不同的定时初值,允许定时器溢出中断。
定时器中断的特殊功能寄存器设置如下:
定时控制寄存器TCON=20H;
工作方式选择寄存器TMOD=00H;
中断允许控制寄存器IE=82H。
2、键盘/显示电路
功能:
驱动6位数码管动态显示,扫描键盘。
由反向驱动器UNL2803A、6位共阴极数码管和4×4键盘组成。
P0口作为数码管的段选口,P2口作为位选口,与UNL2803A相连接。
P1口的低四位作为键盘的行状态的输入,高四位作为输出扫描。
3、D/A电路
功能:
将波形样值的编码转换成模拟值;完成单极性的波形输出。
由两片0832和两块LM324运放组成。
0832
(1)提供参考电压,单片机向0832
(1)送数字编码,产生不同的输出。
本函数信号发生器可输出1V、2V、3V、4V、5V五个电压。
0832
(1)输出电压作为的0832
(2)的参考电压。
也就是所本函数信号发生器的幅值是可调的。
0832
(2)产生各种波形,生成波形样值码,经D/A转换得到各种模拟样值点。
假如N个点构成波形的一个周期,则0832
(2)输出N个样值点后,样值点形成运动轨迹,即一个周期。
重复输出N个点,成为第二个周期。
地址分配如下:
0832
(1):
BFFFH,0832
(2):
7FFFH。
(1)
四、软件结构
程序由人机交互模块和波形产生模块组成,二者如图2所示。
其中(a)是主流程图,
由系统初始化和人机交互程序模块组成,(b)是定时器中断程序流程图,函数信号发
生模块作为中断服务程序,作为中断服务程序,实现系统的波形输出。
单片机的片内
RAM由128字节,30~3FH作为堆栈区,40~45H为显示缓冲区,40H存放波形编码,
42H~45H存放频率值,42H存放参考电压值,46H为设置标志区
(b)
(a)
主程序
初始化
LED显示
键盘输入处理
定时中断
判断波形
方波
正弦波
锯齿波
中断返回
2
1、人机交互模块
(1)显示子模块
片内RAM的40H~45H是显示缓冲区。
采用查表方式形成显示的段码,显示码表存于ROM中。
显示模块流程图如图(3)所示。
R1存位选信号,R2存显示次数,R0存显示缓冲区地址。
单片机先向P2口送位选信号;从显存中取数字,通过查表,得到显示段码,送P0口;延时,保持显示;修改R0;判断是否已显示6次,不满6次,转开始处执行,已执行6次,则结束显示。
显示初始化
开始
向P2口送位选信号
形成下一位选信号
查表,求段码
送P0口
延时
形成下一位显示地址
显示6次?
结束
Y
N
3
(2)键盘处理子模块
键识别作为主程序,键处理作为子程序。
流程图如图4、图5所示,键盘的工作过程:
1)扫描键盘,获得列扫描码和行状态码,确定键值;
2)根据键值,通过散转表,转到相应的键处理程序;
3)进入键处理,执行键功能。
2、功能键处理
(1)“幅值”键处理
进入PRO2子程序,将设置标志位区46H置为02H,表示设定参考电压;将46H单元置为#0AH,使相应的数码管显示“-”。
(2)“频率”键处理
进入“PRO3”子程序,将设置标志区置为01H,表示频率参数设定;42H是频率值显示缓冲区首址;向42H、43H、44H、45H单元送#0AH,使数码管显示“―――”,返回键盘主程序。
(3)“方波”键处理
进入“PRO4”程序,给40H单元送方波编码01H,使数码管显示“1”,返回键盘主程序。
(4)“正弦波”键处理
进入“PRO5”子程序,给40H单元送正弦波编码02H,使数码管显示“2”,返回键盘主程序。
(5)“锯齿波”键处理
进入“PRO6”子程序,给40H单元送锯齿波编码03H,使数码管显示“3”,返回键盘主程序。
(6)“Enter”键处理
进入“PRO6”子程序,查缓冲区,看所有参数是否已全部设置完毕,若全部设置,则按下述步骤执行:
1)从42H单元中取出参考电压值,查表获得电压的数字编码,送0832
(1),并作为0832
(2)参考电压;2)从42H~45H单元中取频率值并进入相应的程序段,实现频率与定时初值的转换,完成TMOD的设定和初值的设定;3)开启定时中断,向R6赋样值初始编码并返回主程序。
(7)“0~9”键处理
进入“PRO1”子程序,查设置标志区46H的内容,有无设置,若有设置,则进入设定操作,将数字0~9送显示缓冲区。
若无设置,则返回主程序。
散转表
开始
PRO1
PRO2
PRO3
PRO4
PRO5
PRO6
PRO7
返回键处理主程序
5
键查询
开始
闭合?
去抖动
行扫描
列0?
去键值
等待释放
调键功能处理
返回主程序
形成下一列扫描码
4次?
4次?
N
Y
形成下一行扫描码
N
Y
Y
N
Y
N
4
3、波形产生模块
(1)将一个周期T的信号分成32个点(按X轴等份),两点间的时间间隔△T由单片机的定时器产生。
(2)一个周期分成32个点,对应三种波形的32个数据存放在以FBO_TAB、XIN_TAB、JCHB_TAB为起始地址的存储器中。
中断服务流程如图6所示,波形产生流程如图7所示。
保护现场
开始
波形值送R7
调波形产生程序
恢复现场
中断返回
6
查表求样值码
开始
样值码送0832
(2)
形成下一个样值码
R6=32?
返回中断服务程序
Y
清零R6=0
调定时初值设定
N
7
五、完整程序
;-----------------------------------------------------------------------------------------
;这是一个有三种波形选择,电压幅值可调,频率可变,用键盘进行控制的函数信号发生器
;-----------------------------------------------------------------------------------------
ORG0000H
AJMPMAIN
ORG000BH
JMPINT_T
ORG0030H
MIAN:
MOVSP,#30H;主程序
MOVA,#00H;初始化主程序
MOV40H,A;给显示缓冲区送#00H
MOV41H,A
MOV42H,A
MOV43H,A
MOV44H,A
MOV45H,A
MOV46H,A
LOOP:
CALLLED_DISPLAY
CALLSCAN_KEY
JMPLOOP
;---------------------------------------------------------------------------------------
;这是定时中断服务程序,通过对40单元的内容的检测,判断调用哪个波形输出
;---------------------------------------------------------------------------------------
INT_T:
PUSHA
PUSHR1
MOVA,40H;读波形设置标志位
MOVR1,A
CJNER1,#01H,XINE
CALLFANGBO
XINE:
CJNER1,#02H,JUCHI
CALLXINEW
JUCHI:
CALLJUCHIBO
POPR1
POPA
RETI
;-----------------------------------------------------------------------------------------
;这是显示程序,对显示缓冲取的数据进行扫描显示
;-----------------------------------------------------------------------------------------
LED_DISPLAY:
PUSHR1
PUSHR2
PUSHR3
MOVR1,#FEH;存位选信号
MOVR2,#06H;存显示次数
MOVR3,#40H;存显示缓存区首址
DIS:
MOVA,R1
MOVP2,A
RLA
MOVR1,A
MOVA,@R3;取缓冲区显示数据
MOVP0,A
INCR3
LCALLDELAY1;调用延时
DJNZR2,DIS
POPR3
POPR2
POPR1
RET
DELAY1:
PUSHR1;延时程序
PUSHR2
MOVR1,#50
D1:
MOVR2,#50
DJNZR2,$
DJNZR1,D1
POPR2
POPR1
RET
;------------------------------------------------------------------------------------------
;这是对键盘的扫描程序,通过扫描获取键值,并对其进行处理
;------------------------------------------------------------------------------------------
SCAN_KEY:
ACALLKS1;判断有无键闭合
JZNS;A等于0,无键闭合,返回主程序
ACALLDELAY;延时12ms
ACALLDELAY
ACALLKS1;判断有无键闭合
JZNS;无键闭合,放回主程序
SCAN:
MOVR0,#00H;按键初始值
MOVR1,#04H;扫描行数
MOVR2,#FEH;送扫描值
MOVA,R2
MOVP1,A;扫描,并设定输入模式
JNBP1.7,NS
INCR0
JNBP1.6,NS
INCR0
JNBP1.5,NS
INCR0
JNBP1.4,NS
INCR0
MOVA,R2
RLA
MOVR2,A
DJNZR2,SCAN
WTF:
ACALLDELAY;等待按键释放
ACALLKS1
JNZWTF
CALLKEY_DEAL;调用键功能处理
NS:
RET
KS1:
MOVA,#0FH;按键闭合判断子程序
MOVP1,A;扫描,并设定输入模式
NOP
MOVXA,P1;把P1口的值读回A
CPLA
ANLA,#0FH;A不为0,有键闭合
RET
DELAY:
PUSHR6
PUSHR7
MOVR7,#40;延时约6ms
D1:
MOVR6,#36
DJNZR6,$
DJNZR7,D1
POPR7
POPR6
RET
;---------------------------------------------------------------------------------------
;按键功能处理,当按数字键,检测设置标志区,看是否是要送显示缓冲去的数,不是就返回主程序
;当按幅值键时,把设置标志区置为02H,表示设定参考电压,将42单元置为#0AH
;当按频率键时,把设置标志区置为01H,表示频率参数设定,42H时缓冲区首址,向42H,43H,44H,45H单元
;送#0AH,返回键盘主程序
;当按ENTER键,检查是否已全部设置完毕,是的话1、送从45H中取参考电压,查表获得电压的数字编码
;送0832
(1);2、从42H~45H中取频率值并进入相应的程序段,实现频率与设定初值的转换,完成TMOD的
;设定和初值设定;3、开启定时中断,向R1赋样值初始编码并返回主程序
;------------------------------------------------------------------------------------------
KEY_DEAL:
MOVDPTR,#TAB;送散转表首地址
MOVA,R0
MOVA,@A+DPTR
PRO1:
PUSHR7
PUSHR5
MOVA,46H;0~9号功能键处理
MOVR7,A
MOVR5,#42H
MOVR4,#04H
CJNER7,#01H,WAVE_V
MOVA,R0
F_SEND:
MOVB,@R5;频率存储的一个循环
MOVR6,B
CJNER6,#0AH,F_SEND1;不等于#0AH,说明已经有数字存储,转移到下一单元
MOVX@R5,A
JMPOVER
F_SEND1:
INCR5
DJNZR4,F_SEND
JMPOVER
WAVE_V:
CJNER7,#02H,OVER;不是幅值就转移
MOVB,R0
MOVX41H,B
POPR5
POPR7
JMPOVER;PRO1结束返回
PRO2:
MOVA,#02H;幅值功能键处理
MOVB,#0AH
MOVX46H,A
MOVX41H,B
JMPOVER
PRO3:
MOVA,#01H;频率功能键处理
MOVB,#0AH
MOVX46H,A
MOVX42H,B
MOVX43H,B
MOVX44H,B
MOVX45H,B
JMPOVER
PRO4:
MOVA,#01H;方波功能键处理
MOVX40H,A
JMPOVER
PRO5:
MOVA,#02H;正弦波功能键处理
MOVX40H,A
JMPOVER
PRO6:
MOVA,#03H;锯齿波功能键处理
MOVX40H,A
JMPOVER
PRO7:
MOVR2,#06H;ENTER功能键处理
MOVR1,#40H
PRO7_EN:
MOVA,@R1;检查缓冲区看是否已全部设置
CJNEA,#0AH,OVER2
INCR1
DJNZR2,PRO7_EN
MOVXA,41H;把幅值送给0832
(1)
MOVDPTR,#V_TAB;把幅值表的首地址送给DPTR
MOVXA,@A+DPTR
MOVDPTR,#0BFFFH;把0832
(1)的地址送给DPTR
MOVX@DPTR,A
MOVXA,42H;对频率和定时器初值的转换
CJNEA,#01H,NEXT;不是1K转移
MOVR7,#0CH;用R7存相应频率的查表值
JMPNEXT6
NEXT:
CJNEA,#00H,ERROR;所设频率超出所要求频率范围,跳到错误处理
MOVXA,43H
CJNEA,#05H,NEXT1
MOVR7,#0AH
JMPNEXT6
NEXT1:
CJNEA,#02H,NEXT2
MOVR7,#08H
JMPNEXT6
NEXT2:
CJNEA,#01H,NEXT3
MOVR7,#06H
JMPNEXT6
NEXT3:
CJNEA,#00H,ERROR;所设频率超出所要求频率范围,跳到错误处理
MOVXA,43H
CJNEA,#05H,NEXT4
MOVR7,#04H
JMPNEXT6
NEXT4:
CJNEA,#02H,NEXT5
MOVR7,#02H
JMPNEXT6
NEXT5:
CJNEA,#01H,ERROR
MOVR7,#00H
PUSHR7;把R7进栈,以便中断时使用
NEXT6:
MOVTMOD,#01H;设定定时器工作在方式0
MOVDPTR,#F_TAB;把频率表的首地址送给DPTR
MOVA,R7
MOVA,@A+DPTR;把频率初值的低位送给TL
MOVTL0,A
INCR7
MOVA,R7
MOVA,@A+DPTR;把频率初值的高位送给TH
MOVTH0,A
MOVIE,#82H;设置中断控制
MOVR6,#00H;给R6赋样值初值编码
SETBTR0;开启定时器0
POPR7
JMPOVER
TAB:
JMPPRO1;散转表
JMPPRO1
JMPPRO1
JMPPRO1
JMPPRO1
JMPPRO1
JMPPRO1
JMPPRO1
JMPPR01
JMPPRO1
JMPPRO2;转到幅值键处理程序
JMPPRO3;转到频率键处理程序
JMPPRO4;转到方波键处理程序
JMPPRO5;转到正弦波键处理程序
JMPPRO6;转到锯齿波键处理程序
JMPPRO7;转到ENTER键处理程序
ERROR:
JMPPRO3;跳到PRO3进行清除缓冲区处理
OVER:
RET
;=========================方波函数================================
FANGBO:
MOVDPTR,#FBO_TAB;把方波值表首地址送给DPTR
MOVA,R6
MOVA,@A+DPTR
MOVDPTR,#7FFFH
MOVX@DPTR,A
INCR6
CJNER6,#32,FB
MOVR6,#00H
FB:
CALLINIT_T;调用定时器初值初始化
RET
;=========================正弦波函数==============================
XINEW:
MOVDPTR,#XIN_TAB;把正弦波值表首地址送给DPTR
MOVA,R6
MOVA,@A+DPTR
MOVDPTR,#7FFFH
MOVX@DPTR,A
INCR6
CJNER6,#32,XW
MOVR6,#00H
XW:
CALLINIT_T;调用定时器初值初始化
RET
;==========================锯齿波函数==============================
JUCHIBO:
MOVDPTR,#JCHB_TAB
MOVA,R6
MOVA,@A+DPTR
MOVDPTR,#7FFFH
MOVX@DPTR,A
INCR6
CJNER6,#32,JCHB
MOVR6,#00H
JCHB:
RET
;==========================给TH0,TL0送初值=========================
INIT_T:
MOVDPTR,#F_TAB;把频率表的首地址送给DPTR
MOVA,R7
MOVA,@A+DPTR;把频率初值的低位送给TL
MOVTL0,A
INCR7
MOVA,R7
MOVA,@A+DPTR;把频率初值的高位送给TH
MOVTH0,A
RET
;---------------------------------------------------------------------------------------
;幅值,频率,波形表值
;---------------------------------------------------------------------------------------
V_TAB:
DB35H,6AH,9FH,0D5H,0FFH
F_TAB:
DW3CB0H,9E58H,0D8F0H,0EC78H,0F63CH,0FC18H,0FE0CH
FBO_TAB:
DB0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
DB0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH
DB00H,00H,00H,00H,00H,00H,00H,00H
DB00H,00H,00H,00H,00H,00H,00H,00H
XIN_TAB:
DB98H,0BOH,0C6H,0D9H,0E9H,0F5H,0FCH,0FFH
DB0FCH,0F5H,0E9H,0D9H,0C6H,0BOH,98H,7FH
DB66H,4EH,38H,25H,15H,0AH,02H,00H
DB02H,0AH,15H,25H,38H,4EH,66H,7FH
JCHB_TAB:
DB00H,0FH,1FH,2FH,3FH,4FH,5FH,6FH
DB7FH,8FH,9FH,0AFH,0BFH,0CFH,0DFH,0FFH
DB00H,0FH,1FH,2FH,3FH,4FH,5FH,6FH
DB7FH,8FH,9FH,0AFH,0BFH,0CFH,0DFH,0FFH
六、心得体会
开始的时候没想过要用查表方法来做波形函数,但是不知如何下手,所以就去图书管找了一些书看,之后就阶段用查表的方法来做。
本想用8255扩展端口来做的,但是觉得这样做的话有点浪费,因为如果不用8255来扩展端口的话,也是可以做的,只要不扩展存储器89C51的端口就足够用了,我认为程序应该不大,4K的ROM应该够用的,所以就没有扩展端口,硬件也很快就搭好了。
我以为这些做好了,构思也有了,写程序应该使易如反掌的拉。
谁知道,写起程序来,才知道键盘的功能键使那么的难写,那是真的有点想放弃,不写了。
因为我估计,这个设计性试验,班里是没有一两个人回去做的,他们觉得太难了,不会做。
我也有点想随波逐流,到时有得抄就抄,没得抄就算了,老师也是能够了解我们的。
但是后来我有想,既然我对这方面的东西感兴趣,我怎么能够这么想呢?
这个的话是不是有点没人