访问手机版页面
你的位置:老古开发网 > 其他 > 正文  
MAX5581接口: MAX5581快速建立DAC与PIC微控制器的接口
内容导读:

       MAX5581简介

       MAX5581是一款12位、快速建立DAC,采用3线SPI串行接口。MAX5581的接口支持高达20MHz的SPI,最快建立时间为3µs。本应用笔记给出了连接高速PIC微控制器(PIC18F核)和MAX5581 DAC的应用电路以及所需要的全部固件。汇编程序利用MPLAB IDE、6.10.0.0版本中免费提供的编译器编写,用于PIC18F442。

       硬件说明

      
这里讨论的应用电路采用了MAX5581评估板,包括:MAX5581、超高精度电压基准(MAX6126)、两个按键开关、增益设置电阻和PC板。PIC18F442没有安装在MAX5581EVKIT板上,但已添加到系统中,图1所示是一个完整的应用电路。MAX5581EVKIT上的/CS、SCLK、DIN和DOUT焊盘便于SPI串行接口的连接。

点击看原图



                                图1. MAX5581应用电路第一部分

                             
                                  图1. MAX5581应用电路第二部分

       模拟与数字地平面

      
将模拟地与数字地分离开(如图2所示)可以得到较好的实际效果,利用铁氧体磁珠,如TDK MMZ1608B601C,连接两个地平面。这种布局可以避免微控制器系统时钟及其谐波成份馈入模拟地。已知PIC18F442的系统时钟为40MHz,考虑到MMZ1608B601C特殊的阻抗与频率特性,我们选择了这款铁氧体磁珠。图3给出了MMZ1608B601C阻抗随频率的变化曲线。

                   
                                                图2. 分离的模拟地和数字地

                            
    &nb

sp;                      图3. TDK MMZ1608B601C铁氧体磁珠阻抗随频率的变化曲线

       固件说明

       列表1给出的汇编程序通过PIC18F442的内部MSSP SPI接口对MAX5581进行初始化,PIC18F442的40MHz系统时钟允许MSSP提供高达10MHz的SPI时钟(SCLK)。表1所示为上电后的配置字。一旦完成了对MAX5581的初始化,程序便将DAC输出寄存器装载为零,然后装载满量程输出,如表2所示。该固定循环程序可产生方波输出,如图4所示,可以用来演示MAX5581的快速建立时间。

                            
                                    图4. 一个输出为80kHz方波的实际示波器测试图

       列表1. 用于连接MAX5581和PIC18F442内部MSSP SPI接口的汇编程序

       列表1.asm

;******************************************************************************
;                                                                            
;    Filename:  Listing 1 (Absolute Code Version)
;    Date:      2/25/05
;    File Version:   1.0
;
;    Author:         Ted Salazar
;    Company:        Maxim
;                     &nb

sp;            
;******************************************************************************
;
; Program Description:
;
; This program interfaces the internal SPI MSSP
; (Peripheral) of the PIC18F442 to the MAX5581 SPI
; Quad DAC. The program initializes the MAX5581
; and dynamically generates a 50% duty cycle square
; wave with a frequency of 80KHz.
;
;
;******************************************************************************
;
; History:
; 2/25/05: Tested SPI DAC format
; 2/25/05: Initialized MAX5591
; 12/14/04: Cleared tcount timer in HWSPI_W_spidata_W
;******************************************************************************
;******************************************************************************


;
;******************************************************************************
;                                                                            
;    Files required:         P18F442.INC                                     
;                                                                            
;******************************************************************************
 radix hex               ;Default to HEX
 LIST P=18F442, F=INHX32 ;Directive to define processor and file format
 #include  ;Microchip''s Include File
;******************************************************************************
;******************************************************************************
xmit    equ  06   ; Asynchronous TX is at C6
;
;******************************************************************************
;Configuration bits
; The __CONFIG directive defines configuration data within the .ASM file.
; The labels following the directive are defined in the P18F442.INC file.
; The PIC18FXX2 Data Sheet explains the functions of the configuration bits.
; Change the following lines to suit your application.

;T __CONFIG _CONFIG1H, _OSCS_OFF_1H & _RCIO_OSC_1H
;T __CONFIG _CONFIG2L, _BOR_ON_2L & _BORV_20_2L & _PWRT_OFF_2L
;T __CONFIG _CONFIG2H, _WDT_ON_2H & _WDTPS_128_2H
;T __CONFIG _CONFIG3H, _CCP2MX_ON_3H
;T __CONFIG _CONFIG4L, _STVR_ON_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
;T __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L & _CP2_OFF_5L & _CP3_OFF_5L
;T __CONFIG _CONFIG5H, _CPB_ON_5H & _CPD_OFF_5H
;T __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L & _WRT2_OFF_6L & _WRT3_OFF_6L
;T __CONFIG _CONFIG6H, _WRTC_OFF_6H & _WRTB_OFF_6H & _WRTD_OFF_6H
;T __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L & _EBTR2_OFF_7L & _EBTR3_OFF_7L
;T __CONFIG _CONFIG7H, _EBTRB_OFF_7H

;******************************************************************************
;Variable definitions
; These variables are only needed if low priority interrupts are used.
; More variables may be needed to store other special function registers used
; in the interrupt routines.

  CBLOCK 0x080
  WREG_TEMP ;variable used for context saving
  STATUS_TEMP ;variable used for context saving
  BSR_TEMP ;variable used for context saving
  ;
  ENDC

  CBLOCK 0x000
  EXAMPLE ;example of a variable in access RAM
  ;
  temp     ;
  temp2 
  ;
  xmtreg   ;
  cntrb    ;
  cntra    ;
  bitctr   ;

  tcount ;
  speedLbyte ;T Being used in HWSPI_speed
  ;
  ENDC
;******************************************************************************
;Reset vector
; This code will start executing when a reset occurs.

  ORG 0x0000

  goto Main ;go to start of main code

;******************************************************************************
;High priority interrupt vector
; This code will start executing when a high priority interrupt occurs or
; when any interrupt occurs if interrupt priorities are not enabled.

  ORG 0x0008

  bra HighInt ;go to high priority interrupt routine

;******************************************************************************
;Low priority interrupt vector and routine
; This code will start executing when a low priority interrupt occurs.
; This code can be removed if low priority interrupts are not used.

  ORG 0x0018

  movff STATUS,STATUS_TEMP ;save STATUS register
  movff WREG,WREG_TEMP  ;save working register
  movff BSR,BSR_TEMP  ;save BSR register

; *** low priority interrupt code goes here ***


  movff BSR_TEMP,BSR  ;restore BSR register
  movff WREG_TEMP,WREG  ;restore working register
  movff STATUS_TEMP,STATUS ;restore STATUS register
  retfie

;******************************************************************************
;High priority interrupt routine
; The high priority interrupt code is placed here to avoid conflicting with
; the low priority interrupt vector.

HighInt:

; *** high priority interrupt code goes here ***


  retfie FAST

;******************************************************************************
;Start of main program
; The main program code is placed here.

Main:

; *** main code goes here ***
start   
; *** Port Initialization ***
    movlw 0x0FF  
         movwf PORTB
         clrf PORTA
         movlw 0x06         ;T Configure PortA as Digital   
         movwf  ADCON1
         movlw  0x00FB   ;T A2 OUTPUT, ALL OTHERS INPUT
         movwf  TRISA
         movlw 0x0001     ;T B0 INPUT, ALL OTHERS OUTPUT
         movwf TRISB

         movlw 0x0093     ;T C7-C0 => bit7-0
            ;T OUTPUTs: C6(TX), C5(MOSI), C3(SCLK), C2(CS)
            ;T INPUTs:C4 (MISO) and all others
    movwf TRISC       ;T TRISC bit3 Master = 0  
    bsf PORTC,RC2 ;T RC2 = CS\ Make CS\ high

;     *** SPI Initialization ***
  call HWSPI_init      ;T Initialize the MSSP for SPI
;     *** SPI Configuration ***
         movlw b''00000000''  ;T load W with test byte for CPOLCPHA 0,0
     ;T b''00000000'' => CPOLCPHA 0,0
     ;T b''00000001'' => CPOLCPHA 0,1
     ;T b''00000010'' => CPOLCPHA 1,0
     ;T b''00000011'' => CPOLCPHA 1,1
         call HWSPI_W_configure
;     *** SPI Speed  ***
         movlw b''00000000''  ;T load W with test byte for SPI Freq
     ;T b''00000000'' => Fosc/4  = 10MHz
     ;T b''00000001'' => Fosc/16 = 2.5Mhz
     ;T b''00000010'' => Fosc/64 = 625kHz
     ;T b''00000011'' => Reserved.
  call  HWSPI_W_speed
;****************************************************************************** 
;     *** MAX5581 Initialization ***
   bcf PORTC,RC2  ;T RC2 = CS\ Make CS\ Low
  movlw 0xEC   ;T byte0 of settling time config
  call HWSPI_W_spidata_W ;T HW SPI WriteRead Operation  
  movlw 0x0F   ;T byte1 of settling time config
  call HWSPI_W_spidata_W ;T HW SPI WriteRead Operation
  bsf PORTC,RC2  ;T RC2 = CS\ Make CS\ high
;     *** MAX5581 Load All DAC Outputs to Zero Scale ***
Loopforever  bcf PORTC,RC2  ;T RC2 = CS\ Make CS\ Low
  movlw 0xD0   ;T byte0 of load all input/output to zeros
  call HWSPI_W_spidata_W ;T HW SPI WriteRead Operation  
  movlw 0x00   ;T byte1 of load all input/output to zeros
  call HWSPI_W_spidata_W ;T HW SPI WriteRead Operation
  bsf PORTC,RC2  ;T RC2 = CS\ Make CS\ high
;     *** MAX5581 Load All DAC Outputs to Full Scale ***  
   bcf PORTC,RC2  ;T RC2 = CS\ Make CS\ Low
  movlw 0xDF   ;T byte0 of load all input/output to zeros
  call HWSPI_W_spidata_W ;T HW SPI WriteRead Operation  
  movlw 0xFF   ;T byte1 of load all input/output to zeros
  call HWSPI_W_spidata_W ;T HW SPI WriteRead Operation
  bsf PORTC,RC2  ;T RC2 = CS\ Make CS\ high 
;        movwf   xmtreg    ;T move w to xmtreg
;        call    asyxmtc   ;T call UART routine
;
      goto Loopforever        ;T loop forever
;******************************************************************************
errsrv 
  movlw 0x65  ; load w with ''e'' = 0x65
         movwf xmtreg          ; move w to xmtreg
         call asyxmtc  ; call UART routine
dead     goto   dead              ; goto endless loop
;******************************************************************************
set_cf_error
  movlw  0x00   ; 0x00 into W
  sublw  0x00      ; Subtract W-0x00: If W<=N C set; If W>N C clear.
  return            ; error=> cf=set
;******************************************************************************
clear_cf_ok
  movlw  0x01   ; 0x00 into W
  sublw  0x00      ; Subtract W-0x00: If W<=N C set; If W>N C clear.
  return            ; success=> cf=clear
;******************************************************************************
HWSPI_init    ;T SPI MSSP Initialization for M2EAM schematic
     ;T CPOL,CPHA = 0,0  => CKP = 0 & CKE = 1

  bcf SSPCON1,SSPEN ;T Disable the MSSP, SSPCON-5
;     
  bcf TRISC,SDO ;T TRISC bit5 RC5/SDO = 0 MOSI Output
  bcf TRISC,SCK ;T TRISC bit3 RC3/SCK = 0 SCLK Output
  bsf TRISC,SDI ;T TRISC bit4 RC4/SDI = 1 MISO Input
  movlw  0x0040     ;T SSPSTAT bit8 = 0 sampled in middle
     ;T SSPSTAT bit6 = CKE = 1
        movwf  SSPSTAT  ;T Used to be sspstat on older PICs
  movlw  0x0020  ;T SSPCON1 bit5 SSPEN = 1 Enables sycn serial port
            ;T SSPCON1 bit4 = CKP = 0
            ;T SSPCON1 bit3= 0 = Turn MSSP ON for SPI
            ;T SSPCON1 bit2-0 = 000b = SCLK = Fosc/4
            ;T SSPCON1 bit2 = 0 = Master
      movwf  SSPCON1  ;T Used to be sspcon on older PICs
  bsf INTCON,PEIE ;T INTCON bit6 = PEIE = 1 = Enable periph interrupt
  bsf PIE1,SSPIE   ;T PIE1 bit3 = SSPIE = 1 = interrupt enable
  movlw 0x00  ;T load 0x00 into W
  movwf tcount  ;T initialize tcount to zero (0x00)
;******************************************************************************
HWSPI_W_configure
;Configure SPI Mode
;
;On Entry: WREG = confDATA
;On Exit: 
;On Success: return with C flag clear
;On Failure: return with C flag set
;
  bcf SSPCON1,SSPEN ;T Disable the MSSP, SSPCON1-5
  movwf temp      ;T move the confDATA byte to temp
  btfsc SSPCON1,SSPM3  ;T In SPI Mode?, skip if yes
         call  HWSPI_init ;T MSSP is in wrong mode, Init for SPI
;
  btfsc temp,1  ;T Is bit1 of confDATA byte clear? if so skip next
  goto  CPOL_1  ;T goto CPOL = 1 label => CPOL = 1
  btfsc temp,0  ;T Is bit0 of confDATA byte clear? if so skip next
     ;T => CPOL = 0 , CPHA = ?
  goto  CPOLCPHA_01 ;T goto => CPOL = 0 CPHA = 1
;Configure for CPOL = 0, CPHA = 0
  bcf SSPCON1,CKP ;T SSPCON1 bit4 = CKP = 0
  bsf SSPSTAT,CKE ;T SSPSTAT bit6 = CKE = 1
  btfsc  SSPCON1,CKP ;T Is SSPCON1 bit4 = CKP = 0 ?
  goto badjump  ;T CKP bit test error
  btfss SSPSTAT,CKE ;T Is SSPSTAT bit6 = CKE = 1 ?
  goto badjump  ;T CKE bit test error
  goto  okjump2  ;OK configured!
;
CPOL_1  btfsc temp,0  ;T Is bit0 of confDATA byte clear? if so skip next
     ;T CPOL = 1 , CPHA = ?
  goto CPOLCPHA_11 ;T goto => CPOL = 1, CPHA = 1
;Configure for CPOL = 1, CPHA = 0
  bsf SSPCON1,CKP ;T SSPCON1 bit4 = CKP = 1
  bsf SSPSTAT,CKE ;T SSPSTAT bit6 = CKE = 1
  btfss  SSPCON1,CKP ;T Is SSPCON1 bit4 = CKP = 1 ?
  goto badjump  ;T CKP bit test error
  btfss SSPSTAT,CKE ;T Is SSPSTAT bit6 = CKE = 1 ?
  goto badjump  ;T CKE bit test error
  goto  okjump2  ;OK configured!
;  
CPOLCPHA_01
;configure for CPOL = 0, CPHA = 1
  bcf SSPCON1,CKP ;T SSPCON1 bit4 = CKP = 0
  bcf SSPSTAT,CKE ;T SSPSTAT bit6 = CKE = 0
  btfsc  SSPCON1,CKP ;T Is SSPCON1 bit4 = CKP = 0 ?
  goto badjump  ;T CKP bit test error
  btfsc SSPSTAT,CKE ;T Is SSPSTAT bit6 = CKE = 0 ?
  goto badjump  ;T CKE bit test error
  goto  okjump2  ;OK configured!
;  
CPOLCPHA_11
;configure for CPOL = 1, CPHA = 1
  bsf SSPCON1,CKP ;T SSPCON1 bit4 = CKP = 1
  bcf SSPSTAT,CKE ;T SSPSTAT bit6 = CKE = 0
  btfss  SSPCON1,CKP ;T Is SSPCON1 bit4 = CKP = 1 ?
  goto badjump  ;T CKP bit test error
  btfsc SSPSTAT,CKE ;T Is SSPSTAT bit6 = CKE = 0 ?
  goto badjump  ;T CKE bit test error
  goto  okjump2  ;OK configured!
;  
okjump2  bsf SSPCON1,SSPEN ;T Re-enable MSSP
  goto clear_cf_ok
  return   
badjump bsf SSPCON1,SSPEN  ;T Re-enable MSSP
  goto  set_cf_error ;T configuration error
  return
;******************************************************************************
HWSPI_W_speed
;On Entry: WREG = speedDATA & checks SSPCON1-3 for SPI mode
;                  speedDATA = 0x00 => Fosc/4
;                  speedDATA = 0x01 => Fosc/16
;                  speedDATA = 0x02 => Fosc/64
;                  speedDATA = 0x03 => Timer Divisor (Not working yet)
;
;On Exit:
;On Success: return with C flag clear
;On Failure: return with C flag set
;
  bcf SSPCON1,SSPEN  ;T Disable MSSP
  movwf  speedLbyte ;T move speedDATA stored in W to speedLbyte
  btfsc SSPCON1,SSPM3  ;T In SPI Mode?, skip if yes
         call  HWSPI_init ;T MSSP is in wrong mode, Init for SPI
;
;Test if speedLbyte = 0x00. If yes, SPI clock speed = Fosc/4
  movlw 0x00  ;T load 0x00 into W
  subwf speedLbyte,W ;T subtract 0x00 from tcount result in w
  btfss STATUS,Z ;T test zero flag, skip next instr if z set
  goto fdiv16  ;T goto Fosc/16 section
  bcf SSPCON1,SSPM1 ;T SSPCON1-1 = 0
  bcf SSPCON1,SSPM0 ;T SSPCON1-0 = 0
  goto  okjump3  ;T Fosc/4 was selected
;Test if speedLbyte = 0x01. If yes, SPI clock speed = Fosc/16
fdiv16  movlw 0x01  ;T load 0x01 into W
  subwf speedLbyte,W ;T subtract 0x01 from tcount result in w
  btfss STATUS,Z ;T test zero flag, skip next instr if z set
  goto fdiv64  ;T goto Fosc/64 section
  bcf SSPCON1,SSPM1 ;T SSPCON1-1 = 0
  bsf SSPCON1,SSPM0 ;T SSPCON1-0 = 1
  goto  okjump3  ;T Fosc/16 was selected
;Test if speedLbyte = 0x02. If yes, SPI clock speed = Fosc/64
fdiv64  movlw 0x02  ;T load 0x02 into W
  subwf speedLbyte,W ;T subtract 0x02 from tcount result in w
  btfss STATUS,Z ;T test zero flag, skip next instr if z set
  goto timer  ;T goto Timer section
  bsf SSPCON1,SSPM1 ;T SSPCON1-1 = 1
  bcf SSPCON1,SSPM0 ;T SSPCON1-0 = 0
  goto  okjump3  ;T Fosc/64 was selected
;Test if speedLbyte >= 0x03. If yes, SPI clock speed will be set by the timer
;SETTING THE SPI CLOCK WITH THE TIMER WILL RETURN A FAILURE AT THIS TIME.
;Future To do: Implement the TIMER section 
timer  movlw 0x03  ;T load 0x02 into W
  subwf speedLbyte,W ;T subtract 0x02 from tcount result in w
  btfss STATUS,Z ;T test zero flag, skip next instr if z set
  goto badjmp2  ;T goto error section to return failure
  goto badjmp2  ;T goto error section to return failure
;  bsf SSPCON1,SSPM1 ;T SSPCON1-1 = 1
;  bsf SSPCON1,SSPM0 ;T SSPCON1-0 = 1
;  goto  okjump3  ;T Fosc/64 was selected
     
okjump3  bsf SSPCON1,SSPEN ;T Re-enable MSSP
  bcf STATUS,C ;T clear c flag on success
  return   

badjmp2  bsf SSPCON1,SSPEN ;T Re-enable MSSP
  bsf STATUS,C ;T set c flag on failure
  return 
;******************************************************************************
HWSPI_W_spidata_W
;Simultaneously write SPI data on MOSI and read SPI data on MISO
;
;on Entry: WREG = mosiDATA & checks bit3 of SSPCON1 for SPI mode
;On Exit: WREG = misoDATA
;On Success: return with C flag clear
;On Failure: return with C flag set
;
  movwf  temp2  ;T move mosiDATA stored in W to WREG_TEMP
  btfsc SSPCON1,SSPM3  ;T In SPI Mode?, skip if yes
         call  HWSPI_init ;T MSSP is in wrong mode, Init for SPI
  movf temp2,W  ;T load W with original mosiDATA
;
  movwf SSPBUF  ;T move byte to transmit to SSPBUF (transmit buffer)
  movlw 0x00  ;T load 0x00 into W
  movwf tcount  ;T initialize tcount to zero (0x00)
again1  btfsc SSPSTAT,BF ;T receive completed? if no, skip next
  goto okjump1  ;T no. goto again
  incf  tcount,F ;T increment tcount
  movlw 0xFF  ;T load w with literal
  subwf tcount,W ;T subtract 0xFF from tcount result in w
  btfss STATUS,Z ;T test zero flag, skip next instr if z set
         goto   again1         ;T loop until timeout
  goto  set_cf_error ;T receive timeout error
  return
okjump1  movf  SSPBUF,W ;T put received data in W
  goto clear_cf_ok
  return   
;******************************************************************************
; UART routine
asyxmtc  bcf PORTC,xmit   ;T used to be portc,xmit
         call full           
         movlw 0x08         ;TEST_T "08"     
         movwf bitctr         
asyxmt1  rrcf  xmtreg,f       
         btfsc  STATUS,C       
         goto   asyxmt2        
         bcf  PORTC,xmit  ;T used to be portc,xmit
         goto  asyxmt3        
asyxmt2  bsf  PORTC,xmit  ;T used to be portc,xmit
;
asyxmt3  call full           
         decfsz  bitctr,f       
         goto   asyxmt1        
;
         bsf  PORTC,xmit  ;T used to be portc,xmit
         call full           
         retlw 0              
;******************************************************************************
; UART baud rate of 115.2kbps using a 40MHz System Clock
full     movlw d''3''           
         movwf cntrb
vdly0    movlw d''6''             ; d''43'' with 4MHz => 2400 baud
         movwf cntra
vdly1    decfsz  cntra,f        
         goto  vdly1          
         decfsz  cntrb,f        
         goto  vdly0          
         retlw 0              
;******************************************************************************
;End of program

  END

 


表1. 配置写命令,将所有四路DAC的建立时间设置为3µs

SPI Line C7  C6  C5  C4  C3  C2  C1  C0  D7  D6  D5  D4  D3  D2  D1  D0
DIN           1   1    1     0      1    1    0    0    0    0     0     0    1     1    1     1

表2. 装载全部DAC输出命令

SPI Line C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
DIN (1st) 1    1   0    1    0     0      0    0    0   0   0   0    0   0   0    0
DIN (2nd) 1   1   0    1    1     1      1    1    1   1   1   1    1   1   1    1

表2中,第一个命令将所有DAC输出设置为零,第二个命令将所有DAC设置为满量程输出。

标签:
来源:无忧电子开发网 作者:Maxim中文网站-应用笔记 时间:2006/5/17 0:00:00
相关阅读
推荐阅读
阅读排行
最近更新
商品推荐