- 源代码如果需要源代码请下载
- 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