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

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

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

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

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

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. 分离的模拟地和数字地


图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 LineC7C6C5C4C3C2C1C0D7D6D5D4D3D2D1D0
DIN1110110000001111


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

SPI LineC3C2C1C0D11D10D9D8D7D6D5D4D3D2D1D0
DIN (1st)1101000000000000
DIN (2nd)1101111111111111


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



关键词: 控制器 MAX55

评论

技术专区