工业控制 | 能源技术 | 汽车电子 | 通信网络 | 安防监控 | 智能电网 | 移动手持 | 无线技术 | 家用电器 | 数字广播 | 消费电子 | 应用软件 | 其他方案

电路设计->综合电路图->综合电路图->MAX5581接口: MAX5581快速建立DAC与PIC微

MAX5581接口: MAX5581快速建立DAC与PIC微

作者:fanxiaoxi 时间:2022-12-08

摘要:本应用笔记介绍MAX5581DACPIC®微控制器的配合使用,给出了详细的电路图和源代码。

MAX5581简介

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

硬件说明

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


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


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

模拟与数字地平面

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


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


图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接口的汇编程序

下载: P18F442.INC

列表1.asm

;******************************************************************************; ; Filename: LisTIng 1 (Absolute Code Version) ; Date: 2/25/05 ; File Version: 1.0; ; Author: Ted Salazar ; Company: Maxim; ;******************************************************************************; ; 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 HEXLIST 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 0x080WREG_TEMP ;variable used for context savingSTATUS_TEMP ;variable used for context savingBSR_TEMP ;variable used for context saving;ENDCCBLOCK 0x000EXAMPLE ;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 0x0000goto 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 0x0008bra 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 0x0018movff STATUS,STATUS_TEMP ;save STATUS registermovff WREG,WREG_TEMP ;save working registermovff BSR,BSR_TEMP ;save BSR register ; *** low priority interrupt code goes here ***movff BSR_TEMP ,BSR ;restore BSR registermovff WREG_TEMP,WREG ;restore working registermovff STATUS_TEMP,STATUS ;restore STATUS registerretfie ;****************************************************************************** ;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 0x0FFmovwf PORTBclrf PORTAmovlw 0x06 ;T Configure PortA as Digitalmovwf ADCON1movlw 0x00FB ;T A2 OUTPUT, ALL OTHERS INPUTmovwf TRISAmovlw 0x0001 ;T B0 INPUT, ALL OTHERS OUTPUTmovwf TRISBmovlw 0x0093 ;T C7-C0 => bit7-0;T OUTPUTs: C6(TX), C5(MOSI), C3(SCLK), C2(CS) ;T INPUTs:C4 (MISO) and all othersmovwf TRISC ;T TRISC bit3 Master = 0bsf 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,1call 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\ Lowmovlw 0xEC ;T byte0 of settling time configcall HWSPI_W_spidata_W ;T HW SPI WriteRead Operationmovlw 0x0F ;T byte1 of settling time configcall HWSPI_W_spidata_W ;T HW SPI WriteRead Operationbsf 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\ Lowmovlw 0xD0 ;T byte0 of load all input/output to zeroscall HWSPI_W_spidata_W ;T HW SPI WriteRead Operationmovlw 0x00 ;T byte1 of load all input/output to zeroscall HWSPI_W_spidata_W ;T HW SPI WriteRead Operationbsf PORTC,RC2 ;T RC2 = CS\ Make CS\ high ; *** MAX5581 Load All DAC Outputs to Full Scale ***bcf PORTC,RC2 ;T RC2 = CS\ Make CS\ Lowmovlw 0xDF ;T byte0 of load all input/output to zeroscall HWSPI_W_spidata_W ;T HW SPI WriteRead Operationmovlw 0xFF ;T byte1 of load all input/output to zeroscall HWSPI_W_spidata_W ;T HW SPI WriteRead Operationbsf 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 ;******************************************************************************errsrvmovlw 0x65 ; load w with 'e' = 0x65movwf xmtreg ; move w to xmtregcall asyxmtc ; call UART routinedead goto dead ; goto endless loop ;******************************************************************************set_cf_errormovlw 0x00 ; 0x00 into Wsublw 0x00 ; Subtract W-0x00: If WN C clear.return ; error=> cf=set ;******************************************************************************clear_cf_okmovlw 0x01 ; 0x00 into Wsublw 0x00 ; Subtract W-0x00: If WN C clear.return ; success=> cf=clear ;******************************************************************************HWSPI_init ;T SPI MSSP Initialization for M2EAM schematic ;T CPOL,CPHA = 0,0 => CKP = 0 & CKE = 1bcf SSPCON1,SSPEN ;T Disable the MSSP, SSPCON-5 ;bcf TRISC,SDO ;T TRISC bit5 RC5/SDO = 0 MOSI Outputbcf TRISC,SCK ;T TRISC bit3 RC3/SCK = 0 SCLK Outputbsf TRISC,SDI ;T TRISC bit4 RC4/SDI = 1 MISO Inputmovlw 0x0040 ;T SSPSTAT bit8 = 0 sampled in middle ;T SSPSTAT bit6 = CKE = 1movwf SSPSTAT ;T Used to be sspstat on older PICsmovlw 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 = Mastermovwf SSPCON1 ;T Used to be sspcon on older PICsbsf INTCON,PEIE ;T INTCON bit6 = PEIE = 1 = Enable periph interruptbsf PIE1,SSPIE ;T PIE1 bit3 = SSPIE = 1 = interrupt enablemovlw 0x00 ;T load 0x00 into Wmovwf 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-5movwf temp ;T move the confDATA byte to tempbtfsc SSPCON1,SSPM3 ;T In SPI Mode?, skip if yescall HWSPI_init ;T MSSP is in wrong mode, Init for SPI ;btfsc temp,1 ;T Is bit1 of confDATA byte clear? if so skip nextgoto CPOL_1 ;T goto CPOL = 1 label => CPOL = 1btfsc 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 = 0bcf SSPCON1,CKP ;T SSPCON1 bit4 = CKP = 0bsf SSPSTAT,CKE ;T SSPSTAT bit6 = CKE = 1btfsc SSPCON1,CKP ;T Is SSPCON1 bit4 = CKP = 0 ?goto badjump ;T CKP bit test errorbtfss SSPSTAT,CKE ;T Is SSPSTAT bit6 = CKE = 1 ?goto badjump ;T CKE bit test errorgoto 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 = 0bsf SSPCON1,CKP ;T SSPCON1 bit4 = CKP = 1bsf SSPSTAT,CKE ;T SSPSTAT bit6 = CKE = 1btfss SSPCON1,CKP ;T Is SSPCON1 bit4 = CKP = 1 ?goto badjump ;T CKP bit test errorbtfss SSPSTAT,CKE ;T Is SSPSTAT bit6 = CKE = 1 ?goto badjump ;T CKE bit test errorgoto okjump2 ;OK configured!;CPOLCPHA_01 ;configure for CPOL = 0, CPHA = 1bcf SSPCON1,CKP ;T SSPCON1 bit4 = CKP = 0bcf SSPSTAT,CKE ;T SSPSTAT bit6 = CKE = 0btfsc SSPCON1,CKP ;T Is SSPCON1 bit4 = CKP = 0 ?goto badjump ;T CKP bit test errorbtfsc SSPSTAT,CKE ;T Is SSPSTAT bit6 = CKE = 0 ?goto badjump ;T CKE bit test errorgoto okjump2 ;OK configured! ;CPOLCPHA_11 ;configure for CPOL = 1, CPHA = 1bsf SSPCON1,CKP ;T SSPCON1 bit4 = CKP = 1bcf SSPSTAT,CKE ;T SSPSTAT bit6 = CKE = 0btfss SSPCON1,CKP ;T Is SSPCON1 bit4 = CKP = 1 ?goto badjump ;T CKP bit test errorbtfsc SSPSTAT,CKE ;T Is SSPSTAT bit6 = CKE = 0 ?goto badjump ;T CKE bit test errorgoto okjump2 ;OK configured! ;okjump2 bsf SSPCON1,SSPEN ;T Re-enable MSSPgoto clear_cf_okreturnbadjump bsf SSPCON1,SSPEN ;T Re-enable MSSPgoto set_cf_error ;T configuration errorreturn ;******************************************************************************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 MSSPmovwf speedLbyte ;T move speedDATA stored in W to speedLbytebtfsc SSPCON1,SSPM3 ;T In SPI Mode?, skip if yescall HWSPI_init ;T MSSP is in wrong mode, Init for SPI; ;Test if speedLbyte = 0x00. If yes, SPI clock speed = Fosc/4movlw 0x00 ;T load 0x00 into Wsubwf speedLbyte,W ;T subtract 0x00 from tcount result in wbtfss STATUS,Z ;T test zero flag, skip next instr if z setgoto fdiv16 ;T goto Fosc/16 sectionbcf SSPCON1,SSPM1 ;T SSPCON1-1 = 0bcf SSPCON1,SSPM0 ;T SSPCON1-0 = 0goto okjump3 ;T Fosc/4 was selected ;Test if speedLbyte = 0x01. If yes, SPI clock speed = Fosc/16fdiv16 movlw 0x01 ;T load 0x01 into Wsubwf speedLbyte,W ;T subtract 0x01 from tcount result in wbtfss STATUS,Z ;T test zero flag, skip next instr if z setgoto fdiv64 ;T goto Fosc/64 sectionbcf SSPCON1,SSPM1 ;T SSPCON1-1 = 0bsf SSPCON1,SSPM0 ;T SSPCON1-0 = 1goto okjump3 ;T Fosc/16 was selected ;Test if speedLbyte = 0x02. If yes, SPI clock speed = Fosc/64fdiv64 movlw 0x02 ;T load 0x02 into Wsubwf speedLbyte,W ;T subtract 0x02 from tcount result in wbtfss STATUS,Z ;T test zero flag, skip next instr if z setgoto timer ;T goto Timer sectionbsf SSPCON1,SSPM1 ;T SSPCON1-1 = 1bcf SSPCON1,SSPM0 ;T SSPCON1-0 = 0goto 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 d Implement the TIMER sectiontimer movlw 0x03 ;T load 0x02 into Wsubwf speedLbyte,W ;T subtract 0x02 from tcount result in wbtfss STATUS,Z ;T test zero flag, skip next instr if z setgoto badjmp2 ;T goto error section to return failuregoto 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 selectedokjump3 bsf SSPCON1,SSPEN ;T Re-enable MSSPbcf STATUS,C ;T clear c flag on successreturnbadjmp2 bsf SSPCON1,SSPEN ;T Re-enable MSSPbsf STATUS,C ;T set c flag on failurereturn ;******************************************************************************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_TEMPbtfsc SSPCON1,SSPM3 ;T In SPI Mode?, skip if yescall HWSPI_init ;T MSSP is in wrong mode, Init for SPImovf 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 Wmovwf tcount ;T initialize tcount to zero (0x00)again1 btfsc SSPSTAT,BF ;T receive completed? if no, skip nextgoto okjump1 ;T no. goto againincf tcount,F ;T increment tcountmovlw 0xFF ;T load w with literalsubwf tcount,W ;T subtract 0xFF from tcount result in wbtfss STATUS,Z ;T test zero flag, skip next instr if z setgoto again1 ;T loop until timeoutgoto set_cf_error ;T receive timeout errorreturnokjump1 movf SSPBUF,W ;T put received data in Wgoto clear_cf_okreturn ;****************************************************************************** ; UART routineasyxmtc bcf PORTC,xmit ;T used to be portc,xmitcall fullmovlw 0x08 ;TEST_T "08"movwf bitctrasyxmt1 rrcf xmtreg,fbtfsc STATUS,Cgoto asyxmt2bcf PORTC,xmit ;T used to be portc,xmitgoto asyxmt3asyxmt2 bsf PORTC,xmit ;T used to be portc,xmit ;asyxmt3 call fulldecfsz bitctr,fgoto asyxmt1 ;bsf PORTC,xmit ;T used to be portc,xmitcall fullretlw 0 ;****************************************************************************** ; UART baud rate of 115.2kbps using a 40MHz System Clockfull movlw d'3'movwf cntrbvdly0 movlw d'6' ; d'43' with 4MHz => 2400 baudmovwf cntravdly1 decfsz cntra,fgoto vdly1decfsz cntrb,fgoto vdly0retlw 0 ;****************************************************************************** ;End of programEND



表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设置为满量程输出。



关键词:控制器MAX55

评论

技术专区