nuc123 ad5764 软件模拟spi驱动程序

  • 源代码如果需要源代码请下载
  • AD5764.c
/*
* Vout = -2 * Vrefin + 4 * Vrefin[D / 65536]
* D = ((Vout + 10) * 65536) / 20
*/
#include <stdio.h>
#include "NUC123.h"
#include "AD5764.h"
#include "delay.h"

unsigned char InputBuf[32] = {
    
    0};
unsigned char OutputBuf[32] = {
    
    0};
uint16_t  V1 = 0;		// 调制高电平A通道高电压值
uint16_t  V2 = 0;		// 调制低电平A通道高电压值
uint16_t _V1 = 0;		// 调制高电平B通道低电压值
uint16_t _V2 = 0;		// 调制低电平B通道低电压值

/**
	@brief unsigned int WriteRegister(unsigned long int WriteData)
	- Write the data to the Register
	@param WriteData :{0x000000 - 0xFFFFFF}
**/
void WriteRegister(unsigned long int WriteData)
{
    
    
	unsigned char Byte;
	for(Byte = 0; Byte < REGISTER_SIZE; Byte++)
	{
    
    
		OutputBuf[Byte] = (WriteData>> (((REGISTER_SIZE - 1) - Byte) * 8)); //Writing the data to be written to 8 bit Output Buffer Array
		InputBuf[Byte] = 0x00;
	}
	SpiReadWrite(InputBuf, OutputBuf, REGISTER_SIZE); //Writes data to the specified register
}

/**
	@brief unsigned long int ReadRegister(unsigned long int RegisterSelect,unsigned long int DacSelect)
	- Reads the values of particular register of each channel.
		@param RegisterSelect :{REG_FUNCTION,REG_DATA,REG_COARSE_GAIN,REG_FINE_GAIN,REG_OFFSET}
		- REG_FUNCTION selects the Function Register
		- REG_DATA selects the Data Register
		- REG_COARSE_GAIN selects the Coarse Gain Register
		- REG_FINE_GAIN selects the Fine Gain Register
		- REG_OFFSET selects the Offset Register
		@param DacSelect :{DAC_A,DAC_B,DAC_C,DAC_D,DAC_ALL}
		- DAC_A selects DAC A
		- DAC_B selects DAC B
		- DAC_C selects DAC C
		- DAC_D selects DAC D
		- DAC_ALL selects all DAC A,B,C,D
		@ return ReceivedData
		- ReceivedData - Read Data from the particular register from the particular Channel
**/
unsigned long int ReadRegister(unsigned long int RegisterSelect, unsigned long int DacSelect)
{
    
    
	unsigned long int ReadControl = 0x000000;
	unsigned int Byte;
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_FUNCTION + DAC_B + SDO_ENABLE; //ReadBack mode enabled
	WriteRegister(RegisterData);
	ReadControl = READ + RegisterSelect + DacSelect; // Converting the data WriteData into Read Data control
	for(Byte=0;Byte < REGISTER_SIZE; Byte++)
	{
    
    
		OutputBuf[Byte] = (ReadControl>>(((REGISTER_SIZE-1)- Byte)*8));//Register read control written to the 8 bit Output Buffer
		InputBuf[Byte] = 0x00; //Flushing the Input Buffer
	}
	SpiReadWrite(InputBuf, OutputBuf, REGISTER_SIZE); //ReadControl written and InputBuf neglected
	*OutputBuf = 0x00; //Nop condition for Reading
	SpiReadWrite(InputBuf, OutputBuf, REGISTER_SIZE); // Valid Received data will be available at InputBuf
	return *InputBuf;
}

/**
	@brief void SpiReadWrite(unsigned char* InputBuffer, unsigned char* OutputBuffer, unsigned char NoOfByte)
	- Generic SPI Read and Write
		@param InputBuffer :8 bit output data array
           OutputBuffer: 8 bit input data array
		   NoOfBytes : (0x00-0x20) Number of Bytes required to transfer
		@ no return value
**/
void SpiReadWrite(unsigned char* InputBuffer, unsigned char* OutputBuffer, unsigned char NoOfByte)
{
    
    
	unsigned char ReceivedByte=0x00;
	unsigned char Bit, Byte;
	unsigned char Register;
	unsigned char ReceivedBit = 0x00;
	SYNC = PIN_LOW; //Start Reading
	for(Byte = 0; Byte < NoOfByte; Byte++)
	{
    
    
		Register = *OutputBuffer; //Moving the Higer Byte to Register for Transfer
		for(Bit = 0; Bit < 8; Bit++)
		{
    
    
			SCLK = PIN_HIGH;
			if(0x80 == (Register & 0x80))
			{
    
    
				SDIN = PIN_HIGH;
			}
			else
			{
    
    
				SDIN = PIN_LOW;
			}
			SCLK = PIN_LOW; //Input data latched at falling edge of clock
			Register <<= 1;  //Rotate data
			ReceivedByte <<= 1;
			ReceivedBit = SDOUT; //Data read from SDOUT pin
			if(ReceivedBit > 0x0000) //Received bit is high
			{
    
    
				ReceivedByte |=1;
			}
		}
		*InputBuffer = ReceivedByte; //Writing the Received Byte to the Input Buffer
		InputBuffer++;
		OutputBuffer++;
		ReceivedByte = 0x00; //Reinitialize the Registers
	}
	SYNC = PIN_HIGH; //Write over
}

/**
	@brief void WriteCoarseGainRegister(unsigned long int DacSelect, unsigned char Range)
	- Writes the values to 2 bit Coarse Gain Register, adjust the output range of each channel.
	@param DacSelect :{DAC_A,DAC_B,DAC_C,DAC_D,DAC_ALL}
		- DAC_A selects DAC A
		- DAC_B selects DAC B
		- DAC_C selects DAC C
		- DAC_D selects DAC D
		- DAC_ALL selects all DAC A,B,C,D
	@param RANGE :{DAC_RANGE_10V/RANGE_10_2564V,RANGE_10_5263V} in 2's complement form
		- DAC_RANGE_10V selects the output range ?0 V
		- RANGE_10_2564V selects the output range ?0.2564 V
		- RANGE_10_5263V selects the output range ?0.5263 V
			@ no return value
**/
void WriteCoarseGainRegister(unsigned long int DacSelect, unsigned char Range)
{
    
    
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_COARSE_GAIN + DacSelect + Range; //Merging the data recieved into a single register
	WriteRegister(RegisterData);
}

/**
	@brief void WriteFineGainRegister(unsigned long int DacSelect, unsigned int FineGain)
	- Writes the values to 6 bit Fine Gain Register, adjust the gain of each channel by -32LSB's to +31LSB's in increment of 1 LSB.
	@param DacSelect :{DAC_A,DAC_B,DAC_C,DAC_D,DAC_ALL}
		- DAC_A selects DAC A
		- DAC_B selects DAC B
		- DAC_C selects DAC C
		- DAC_D selects DAC D
		- DAC_ALL selects all DAC A,B,C,D
	@param Offset :{0x20-0x1F} in 2's complement form
			@ no return value
**/
void WriteFineGainRegister(unsigned long int DacSelect, unsigned int FineGain)
{
    
    
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_FINE_GAIN + DacSelect + FineGain; Merging the data recieved into a single register
	WriteRegister(RegisterData);
}

/**
	@brief voidWriteOffsetRegister(unsigned long int DacSelect, unsigned int Offset)
	- Writes the values to 8 bit Offset Register, adjust the offsets of each channel by -16LSB's to +15.875LSB's in increment of 1/8 LSB.
	@param DacSelect :{DAC_A,DAC_B,DAC_C,DAC_D,DAC_ALL}
		- DAC_A selects DAC A
		- DAC_B selects DAC B
		- DAC_C selects DAC C
		- DAC_D selects DAC D
		- DAC_ALL selects all DAC A,B,C,D
	@param Offset :{0x7F-0x80} in 2's complement form
			@ no return value
**/
void WriteOffsetRegister(unsigned long int DacSelect, unsigned int Offset)
{
    
    
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_OFFSET + DacSelect + Offset; //Merging the data recieved into a single register
	WriteRegister(RegisterData);
}

//Function for writing Data Register
/**
	@brief void WriteDataRegister(unsigned long int DacSelect, unsigned int Data)
	- Writes the values to Data Register to specific DAC
	@param DacSelect :{DAC_A,DAC_B,DAC_C,DAC_D,DAC_ALL}
		- DAC_A selects DAC A
		- DAC_B selects DAC B
		- DAC_C selects DAC C
		- DAC_D selects DAC D
		- DAC_ALL selects all DAC A,B,C,D
	@param Data :{0x0000-0xFFFF}
			@ no return value
**/
void WriteDataRegister(unsigned long int DacSelect, unsigned int Data)
{
    
    
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_DATA + DacSelect + Data; //Merging the data recieved into a single register
	WriteRegister(RegisterData);
	// delay_ms(10);
}

/**
	@brief void ConfigureD0D1(unsigned long int D0direction, unsigned long int D1direction)
	- Configure the Digital I/O as output or input.
	@param D0direction :{D0_INPUT,D0_OUTPUT}
		- D0_INPUT for D0 as input
		- D0_OUTPUT for D0 as output
	@param D1direction :{D1_INPUT,D1_OUTPUT}
		- D1_INPUT for D1 as input
		- D1_OUTPUT for D1 as output
	@ no return value
**/
void ConfigureD0D1(unsigned long int D0direction, unsigned long int D1direction)
{
    
    
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_FUNCTION + DAC_B + D1direction + D0direction; //Merging the data recieved into a single register
	WriteRegister(RegisterData);
}

/**
	@brief void OutD0D1(unsigned long int D0Value, unsigned long int D1Value)
	- Sets the Digital I/O to High or LOW when D0 and D1 are configured as output.
	@param D0Value :{D0_HIGH, D0_LOW}
		- D0_HIGH for D0 logic high
		- D0_LOW for D0 logic low
	@param D1Vlaue :{D1_HIGH,D1_LOW}
		- D1_HIGH for D1 logic high
		- D1_LOW for D1 logic low
	@ no return  value
**/
void OutD0D1(unsigned long int D0Value, unsigned long int D1Value)
{
    
    
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_FUNCTION + DAC_B + D1_OUTPUT + D1Value + D0_OUTPUT + D0Value; //Merging the data recieved into a single register
	WriteRegister(RegisterData);
}

/**
	@brief ClearData(void)
	-Resets the DAC output to 0V in 2's compliment mode and negative full scale in binary mode through software instead of CLR pin.
	@ no return  value
**/
void ClearData(void)
{
    
    
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_FUNCTION + DAC_C; //Merging the data recieved into a single register
	WriteRegister(RegisterData);
}

/**
	@brief LoadData(void)
	-Updates the data to DAC Register through software instead of LDAC and gives corresponding analog voltage.

	@ no return  value
**/
void LoadData(void)
{
    
    
	int RegisterData = 0x000000;
	RegisterData = WRITE + REG_FUNCTION+ LOAD; //Merging the data recieved into a single register
	WriteRegister(RegisterData);
}

uint32_t SetDatachange(uint32_t Data)
{
    
    
	 uint32_t temp;
	 temp = 0x8000 + ((Data * 32768 + ((MAX_VOL>>1)))/MAX_VOL);
	 return temp;
}

uint32_t ReadDatachange(uint32_t Data)
{
    
    
	 uint32_t temp;
	 temp = (((Data - 0x8000)/32767 )* MAX_VOL);
	 return temp;
}

#ifdef SOFT_DAC
void AD5764_Init(void)
{
    
    
	/*RST*/
	GPIO_SetMode(PA, BIT14, GPIO_PMD_OUTPUT);
	/*LDAC*/
	GPIO_SetMode(PA, BIT15, GPIO_PMD_OUTPUT);
	/*SYNC*/
	GPIO_SetMode(PC, BIT8, GPIO_PMD_OUTPUT);
	/*SCLK*/
	GPIO_SetMode(PC, BIT9, GPIO_PMD_OUTPUT);
	/*SDOUT*/
	GPIO_SetMode(PC, BIT10, GPIO_PMD_INPUT);
	/*SDIN*/
	GPIO_SetMode(PC, BIT11, GPIO_PMD_OUTPUT);
//	RSTIN = 0;
//	Delay(100);
//	RSTIN = 1;
//	CLR = 0;
//	Delay(100);
//	CLR = 1;
//	LDAC = 0;
//	SYNC = 1;
//	SCLK = 0;
//	SDIN = 0;
	LDAC = 0;
	SYNC = 1;
	SCLK = 0;
	SDIN = 0;
	RSTIN = 0;
	Delay(100);
	RSTIN = 1;
//	CLR = 0;
	Delay(100);
	LDAC = 1;
	Delay(10);
//	CLR = 0;
	WriteCoarseGainRegister(DAC_ALL, RANGE_10V);
	WriteFineGainRegister(DAC_ALL, 0x000000);
	WriteOffsetRegister(DAC_ALL, 0x000000);
	WriteDataRegister(DAC_A, 0x8000);
	WriteDataRegister(DAC_B, 0x8000);
}
#endif

/*
* 串口输入或按键输入模拟电压值转换为写入DAC的数字值
* 形参:Testing_Equipment, 电压范围[-10.00~+10.00V]
*/
void AD5764_Analog_Digital(struct Testing_Equipment t1)
{
    
    
	if(t1.Channel == 1 && (t1.Modulation_Freq > 0 && t1.Modulation_Freq <= 300) && (t1.Base_Freq > 0 && t1.Base_Freq <= 3000))		// 设置转换条件
	{
    
    
		V1  = ((t1.High_Voltage_A  + 10.0) * 65536.0) /  20.0;
		_V1 = ((t1.High_Voltage_B + 10.0) * 65536.0) /  20.0;
		V2  = ((t1.Low_Voltage_A  + 10.0) * 65536.0) /  20.0;
		_V2 = ((t1.Low_Voltage_B + 10.0) * 65536.0) /  20.0;
	}
	if(t1.Remote == 0)
	{
    
    
		V1  = ((t1.High_Voltage_A  + 10.0) * 65536.0) /  20.0;
		_V1 = ((t1.High_Voltage_B + 10.0) * 65536.0) /  20.0;
		V2  = ((t1.Low_Voltage_A  + 10.0) * 65536.0) /  20.0;
		_V2 = ((t1.Low_Voltage_B + 10.0) * 65536.0) /  20.0;
	}
	// printf("V1 = %d\t_V1 = %d\tV2 = %d\t_V2 = %d\r\n", V1, _V1, V2, _V2);
}

  • AD5764.h
#ifndef AD5764_H
#define AD5764_H
#include <stdint.h>
#include "serial_protocol.h"
#define SOFT_DAC


//REGISTER MAP

#define REGISTER_SIZE   0x03 //Size of Register in Bytes
#define MAX_VOL         25000

#define READ            0x800000
#define WRITE           0x000000

#define REG_FUNCTION    0x000000
#define REG_DATA        0x100000
#define REG_COARSE_GAIN 0x180000
#define REG_FINE_GAIN   0x200000
#define	REG_OFFSET      0x280000

#define DAC_A           0x000000
#define DAC_B           0x010000
#define DAC_C           0x020000
#define DAC_D           0x030000
#define DAC_ALL         0x040000

#define RANGE_10V       0x000000
#define RANGE_10_2564V  0x000001
#define RANGE_10_5263V  0x000002

#define D0_OUTPUT       0x000004
#define D1_OUTPUT       0x000010
#define	D0_INPUT        0x000000
#define	D1_INPUT        0x000000

#define D0_HIGH         0x000002
#define D1_HIGH         0x000008
#define	D0_LOW          0x000000
#define	D1_LOW          0x000000

#define SDO_ENABLE      0x000000
#define SDO_DISABLE     0x000001

#define LOAD	        0x050000

#define PIN_HIGH        0x1
#define PIN_LOW         0x0

//PIN CONFIGURATION for AD5764
#define SYNC            PC8
#define SCLK	        PC9
#define SDIN	        PC11
#define SDOUT           PC10
#define LDAC            PA15
#define RSTIN           PA14


extern unsigned char InputBuf[32];
extern unsigned char OutputBuf[32];

void WriteRegister(unsigned long int WriteData);
void WriteCoarseGainRegister(unsigned long int DacSelect, unsigned char Range);
void WriteFineGainRegister(unsigned long int DacSelect, unsigned int FineGain);
void WriteOffsetRegister(unsigned long int DacSelect, unsigned int Offset);
void WriteDataRegister(unsigned long int DacSelect, unsigned int Data);
uint32_t SetDatachange(uint32_t Data);
unsigned long int ReadRegister(unsigned long int RegisterSelect,unsigned long int DacSelect);
uint32_t ReadDatachange(uint32_t Data);
void SpiReadWrite(unsigned char* InputBuffer, unsigned char* OutputBuffer, unsigned char NoOfByte);
void ConfigureD0D1(unsigned long int D0direction, unsigned long int D1direction);
void OutD0D1(unsigned long int D0Value, unsigned long int D1Value);
void ClearData(void);
void LoadData(void);
void AD5764_Init(void);
void AD5764_Analog_Digital(struct Testing_Equipment t1);      // 模拟转数字

#endif

猜你喜欢

转载自blog.csdn.net/cp_srd/article/details/106878251