基于单片机的信号发生器设计

    这个学期的最后一个月,我们正式进入课程设计实验。本次我选择了基于单片机的信号发生器设计的这个课程设计,因为相对比较简单,就一个89C51和D/A0832就搞定。余老师还是比较好的,像他们软件的要焊接,额,密密麻麻的一大堆线,看着就烦。呵呵,好了,以下要谈谈这次设计的过程了。          

    首先,本次设计的要求是以单片机为基础,利用D/A转换器,编程能产生锯齿波、方波、正弦波、三角波四种波形,使波形可变且频率可调的信号发生器。主要难度是波形进行变化和频率可调,好,先准备实验要求的设备, PC机一台(并安装Keil 模拟仿真器软件)实验箱一个、导线落干根,示波器一台。本来我是想用伟福来进行仿真的,可惜没下载器,一切就绪,马上开始,下面是本次报告中的一部分。   

     一、        设计思路      利用Keil C51 系列仿真系统实现。主要利用其中89C51,D/A0832,拨位开关、按键等模块。  

   1、 波形选择:利用8051分别实时地对P1.0、P1.1两口进行扫描,如果发现两口对应相应的数值,即有四种状态:00,01,10,11,根据四种状态跳到对应的波形程序。

  2、 三种波形的实现:方波:由8051对P0口不断交替输出00H和0FFH,有D/A0832转换成模拟量实现;   三角波:由8051对P0口输出00H,在每一个时钟到来时对输出值加一;当加至0FFH时,继而在时钟来临时减一,这样往复执行,最终输出近似连续的三角波;   正弦波:将00H到0FFH按照正弦波波形的变化趋势分成255个间断的点,形成一个正选波取值表,用8051在每一个时钟到来时取表值通过P0口送至D/A0832转换输出。   锯齿波:和三角波相似,当加至0FFH时,由从00H开始加,这样往复执行,最终得到连续的锯齿波。  

   3、 频率调节:利用中断方式,当-INT0接收到一个负脉冲时,使延时程序中时间常数加一,进而实现频率加;当-INT1接收到一个负脉冲时,使延时程序中时间常数减一,实现频率减。     

     下面是实验代码

 

org 0000h
ajmp start
ORG 0003H         ;中断! INT0 的入口地址
INC R7             ;频率加 1
inc r3              
RETI
ORG 0013H           ;中断! INT1 的入口地址
DEC R7              ;频率减 1
dec r3
RETI
org 0100h
START:
      setb EA             ;开 CPU 中断
SETB IE0           ;开! INT0 的中断标志
      SETB IE1           ;开! INT1 的中断标志
      SETB EX1         
      SETB IT1           ;允许! INT1 中断
SETB IT0           ;允许! INT0 中断
SETB EX0
      mov r3,#11            ;改变方波的 频率
      MOV    R7,#5; 改变数值可以改变正弦波、三角波、锯齿波的频率
loop:                    ;查询键盘
     ; anl p1,#03h         ;使 P1.0 P1.0 有效
       MOV a,p1      
 
       cjne a,#00h,l1        K1 K2 开关为都为低,则输出锯齿波。否则跳到 L1
       jmp jcb
l1:    cjne a,#01h,l2         K1 高, K2 为低,则输出方波。否则跳到 L2
      jmp fb
l2:    cjne a,#02h,l3         K1 低, K2 高,则输出三角波,否则跳到 L3
      jmp sjb
l3:    cjne a,#03h,l4         K1 K2 全为高,则输出三角波,否则跳到 L4
      jmp zxb
l4:    ajmp loop             ;实时查询键盘
 
sjb:                        ;三角波
        mov dptr,#0feffh  
        mov a,#00h
loop2: 
        movx @dptr,a
       inc a
       lcall delay2
       CJNE a,#0FFH,loop2
 loop1:
       dec a
       lcall delay2
       movx @dptr,a
       CJNE a,#00H,loop1
     
       ajmp loop
     
jcb:     mov dptr,#0feffh         ;锯齿波
        mov a,#00h
loop3: 
        movx @dptr,a
        inc a
        lcall delay2
        CJNE a,#0FFH,loop3
        sjmp loop
 
fb:     mov dptr,#0feffh           ;方波
       mov a,#00h
loop4: mov a,#00h
       movx @dptr,a
       lcall delay
       mov a,#0ffh
       movx @dptr,a
       lcall delay
       sjmp loop
 
delay: mov 31h,r3           ;延时程序
d1: nop
   nop
   nop
   nop
   nop
   nop
   nop
   nop
   nop
   nop
   nop
   nop
   djnz r3,d1
   mov r3,31h
   ret
 
 
zxb: ;MOV    SP,#80H          ;正弦波
      MOV    R0,#0     ; 定义指向正弦 DAC 数据的指针,因为有 361 个数据
      MOV    R1,#0     ; 所以用了 R0 R1 两个寄寸器
LOOP5:
      MOV    A,R0
      MOV    DPTR,#SINE_DATA
      CJNE   R1,#1,LOW_TAB
      INC    DPH       ; 判断指针的高位字节 R1 是否为 1 。如果是,则 DPH
LOW_TAB:               ; 1
      MOVC   A,@A+DPTR ; 取出正弦波 DAC 的数据
      ;dec    a
      mov dptr,#0feffh
      MOVX   @DPTR,A   ; 启动 D/A 转换
 
      INC    R0        ; 指针底八位加 1 处理
      CJNE   R1,#1,INC_LOW
      CJNE   R0,#105,INC_OK
     
      MOV    R0,#0     ; 如果已经取完数据并输出,则重新设置指针
      MOV    R1,#0
      ljmp   loop       ;SJMP   INC_OK
     
INC_LOW:
      CJNE   R0,#0,INC_OK; 判断是否要进位
      MOV    R1,#1
INC_OK:
      ACALL DELAY2
      JMP   LOOP5
 
;**********************************************
; 通过设置延时时间的长短来改变锯齿波的周期
;**********************************************
DELAY2:
         mov 30H,R7
        
    
       loop9 : DJNZ R7,loop9
        mov R7,30H
        RET
 
 
;******************************
; 正弦波数据表, 8 DAC 的数据
;******************************
SINE_DATA:
      DB 128,130,132,135,137,139,141,144,146,148
      DB 150,152,155,157,159,161,163,165,168,170
      DB 172,174,176,178,180,182,184,186,188,190
      DB 192,194,196,198,200,201,203,205,207,209
      DB 210,212,214,215,217,219,220,222,223,225
      DB 226,227,229,230,232,233,234,235,237,238
      DB 239,240,241,242,243,244,245,246,247,247
      DB 248,249,250,250,251,252,252,253,253,254
      DB 254,254,255,255,255,255,255,255,255,255
      DB 255,255,255,255,255,255,255,255,255,254
      DB 254,254,253,253,252,252,251,250,250,249
      DB 248,247,247,246,245,244,243,242,241,240
      DB 239,238,237,235,234,233,232,230,229,227
      DB 226,225,223,222,220,219,217,215,214,212
      DB 210,209,207,205,203,201,200,198,196,194
      DB 192,190,188,186,184,182,180,178,176,174
      DB 172,170,168,165,163,161,159,157,155,152
      DB 150,148,146,144,141,139,137,135,132,130
      DB 128,126,124,121,119,117,115,112,110,108
      DB 106,104,101,99,97,95,93,91,88,86
      DB 84,82,80,78,76,74,72,70,68,66
      DB 64,62,60,58,56,55,53,51,49,47
      DB 46,44,42,41,39,37,36,34,33,31
      DB 30,29,27,26,24,23,22,21,19,18
      DB 17,16,15,14,13,12,11,10,9,9
      DB 8,7,6,6,5,4,4,3,3,2
      DB 2,2,1,1,1,0,0,0,0,0
      DB 0,0,0,0,0,0,1,1,1,2
      DB 2,2,3,3,4,4,5,6,6,7
      DB 8,9,9,10,11,12,13,14,15,16
      DB 17,18,19,21,22,23,24,26,27,29
      DB 30,31,33,34,36,37,39,41,42,44
      DB 46,47,49,51,53,55,56,58,60,62
      DB 64,66,68,70,72,74,76,78,80,82
      DB 84,86,88,91,93,95,97,99,101,104
      DB 106,108,110,112,115,117,119,121,124,126
      DB 128
      END
        实验问题的解决和原因
1 . 刚开始用键盘进行选择波形时,为何只能改变两种波形?
     原因:首先理解 CJNE (不等于转移)的用法。四种波形只需要两中状态,所以选择一种状态时,要排除其他三种状态的可能性,而单单用如: CJNE A #00H SJB ,则只能是或者不是两这状态。
解决方案:程序中用了多次判断跳转:  
      cjne a,#00h,l1    
      jmp jcb
l1:    cjne a,#01h,l2            
 jmp fb
l2:    cjne a,#02h,l3        
      jmp sjb
l3:    cjne a,#03h,l4       
      jmp zxb
2 .跳到正弦波后,怎么样使跳出循环?
   原因: 正弦波是按照正弦波波形的变化趋势分成255个间断的点,形成一个正选波取值表进行读取的,所以是一个点一个点进行的,出现一个正弦波,则需要把这些点取完。
   解决方案: 如果已经取完数据并输出,然后重新设置指针,这时跳出循环。
      MOV    R0,#0     ; 如果已经取完数据并输出,则重新设置指针
      MOV    R1,#0
      ljmp   loop       ; 跳出循环,重新查询键盘
3 .跳到正弦波后,程序停止运行?
   原因:由于刚才时程序初始化的时候,设置了 setb EA SETB IE0 SETB EX1 等中断初始化,即对所有的中断进行开放,而程序本身没写中断程序,导致中断无返回,发生程序发生错误。
解决方案:当无中断程序时,则不开中断,如果有要用到中断时,则给出具体某个中断源如本实验中的:外部中断! INT0 、外部中断! INT1
ORG 0003H             ;中断! INT0 的入口地址
INC R7           
inc r3               
RETI                 ;中断结束返回
ORG 0013H           ;中断! INT1 的入口地址
DEC R7             
dec r3
RETI                  ;中断结束返回
 
4 .频率可调怎样实现?
原因:实现频率的改变,实际就是改变每个波形的延时的时间。
解决方案:用中断方式实现频率的增加和减小。并对频率进行初始化,即: START     mov r3,#11            ;改变方波的 频率
MOV    R7,#5; 改变数值可以改变正弦波、三角波、锯齿波的频率
在延时程序里对初始值的保护:    mov r3,31h
                                mov 31h,r3 
用到下降沿触发的原因: P3 接扫描键盘,当扫描键盘按下并弹起为一个下降沿。即:
SETB EX0
SETB EX1 
 
视觉效果更好的可以去我的百度空间:http://hi.baidu.com/k65777803/blog/index/1

你可能感兴趣的:(基于单片机的信号发生器设计)