DAC MCP4921 generation Sinus output. MCU dsPIC33FJ64GP706 Microchip.
Figure 3. top signal is pack size of 16 bits send MCP4921. Below this is the signal at the output of DAC MCP4921
Soft
/*=======================================================================
prepare values for sinus
=======================================================================*/
void Sinus_OUT(void)
{
RAD_STEP = 6.28/NUM_OUT;
RAD_ACCUM = 0;
for(i = 0; i < NUM_OUT; i++)
{
SIN_VALUE = sin(RAD_ACCUM);
if(SIN_VALUE >= 0)
{
VALUE_OUT[i] = (int)((SIN_VALUE * 2048) + 2047);
}
else
{
VALUE_OUT[i] = (int)(((SIN_VALUE * 2048) + 2048));
}
RAD_ACCUM = RAD_ACCUM + RAD_STEP;
}
}
Figure 3. top signal is pack size of 16 bits send MCP4921. Below this is the signal at the output of DAC MCP4921
Figure 1. MCP4921 Connect
Figure 2. MCP4921 CS and SCK
Figure 3. top signal is pack size of 16 bits which peredayutsya MCP4921. Below this is the signal at the output of DAC MCP4921
/*=======================================================================
prepare values for sinus
=======================================================================*/
void Sinus_OUT(void)
{
RAD_STEP = 6.28/NUM_OUT;
RAD_ACCUM = 0;
for(i = 0; i < NUM_OUT; i++)
{
SIN_VALUE = sin(RAD_ACCUM);
if(SIN_VALUE >= 0)
{
VALUE_OUT[i] = (int)((SIN_VALUE * 2048) + 2047);
}
else
{
VALUE_OUT[i] = (int)(((SIN_VALUE * 2048) + 2048));
}
RAD_ACCUM = RAD_ACCUM + RAD_STEP;
}
}
/******************************************************************************
Init SPI
******************************************************************************/
void Init_SPI1(void)
{
// setup the SPI peripheral
SPI1STAT = 0x0000; // disable the SPI module (just in case)
SPI1CON1bits.MSTEN = 1; // Master Mode
SPI1CON1bits.MODE16 = 1; // 16 bit format
SPI1CON1bits.SMP = 0;
SPI1CON1bits.SSEN = 0;
SPI1CON1bits.SPRE = 6;
SPI1CON1bits.PPRE = 3;
SPI1CON1bits.CKE = 0x01; // Clock Edge Select bit 0x01
SPI1CON1bits.CKP = 0x00; // SCK
SPI1STAT = 0x8000;// enable the SPI module
IPC2bits.SPI1IP = 2;
IFS0bits.SPI1IF = 0;
//IEC0bits.SPI1IE = 1;
}
/******************************************************************************
Send command to MCP4921 SPI (16bit)
******************************************************************************/
void Write_SPI1(int command)
{
int temp0;
SPI1_CS = 0; // CS LOW
SPI1BUF = command; // write the data out to the SPI peripheral
while(SPI1STATbits.SPITBF) ; // Cheking FLAG
while(!SPI1STATbits.SPIRBF) ; // Cheking FLAG
temp0 = SPI1BUF; // Warning! Need read SPI1BUF, else error Transmit
SPI1_CS = 1; // CS HI
Nop(); // total delay 50nS
Nop();
SPI1_LDAC = 0; // Output data MCP4921
Nop(); // total delay 100nS
Nop();
Nop();
Nop();
SPI1_LDAC = 1; // Output data MCP4921
}
/***********************************************************************
TIM2 interrupt, DAC MCP4921 generation Sinus output
***********************************************************************/
void __attribute__((interrupt, no_auto_psv)) _T2Interrupt(void)
{
IFS0bits.T2IF = 0; // Clear Timer 2 interrupt
DmaBuffer = (0x0001)&(~(DmaBuffer & 0x0001));
LATBbits.LATB0 = DmaBuffer;
if(i >= NUM_OUT)
{
Nop();
i = 0;
}
Write_SPI1(VALUE_OUT[i] | 0x3000); // Sin OUT MCP4921
i = i + 1;
}
/*=============================================================================
Timer 2 time delay for output via the SPI port for external DAC MCP4921
=============================================================================*/
void Init_TMR2(void)
{
TMR2 = 0x0000;
PR2 = TIM2_PR2; // Trigger 5 usec (value 199)
IFS0bits.T2IF = 0; // Clear Timer 2 interrupt
IPC1bits.T2IP = 2; // приоритет 2
IEC0bits.T2IE = 1; // Enable Timer 2 interrupt
T2CONbits.TON = 1; // Start Timer 3
}
/******************************************************************************
Init Ports
******************************************************************************/
void Ports_Init (void)
{
//**********************************
TRISB = 0x0000;
TRISBbits.TRISB2 = 0; // SS1 SPI1
//**********************************
TRISCbits.TRISC2 = 1; // RC2 AN17 - analog
//**********************************
TRISD = 0x0000;
//**********************************
TRISFbits.TRISF2 = 1; // SDI SPI вход
Nop();
TRISFbits.TRISF3 = 0; // MCP4921 SDO SPI
Nop();
TRISFbits.TRISF4 = 0; // MCP4921 LDAC SPI
Nop();
LATFbits.LATF4 = 1; // MCP4921 set LDAC = 1
Nop();
TRISFbits.TRISF5 = 0; // MCP4921 CS SPI
Nop();
LATFbits.LATF5 = 1; // MCP4921 set CS = 1
Nop();
TRISFbits.TRISF6 = 0; // MCP4921 SCK SPI
//**********************************
TRISG = 0x0000;
}
main.c
#include <xc.h>
//#include "GlobalVars.h" // lib varibal
#define FCY 40000000UL // определение тактовой частоты для макросов __delay_ms() и __delay_us()
#include <libpic30.h> // __delay_ms() & __delay_us()
#include <limits.h>
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_OUT 40 // out point sinus
#define SPI1_CS LATFbits.LATF5
#define SPI1_LDAC LATFbits.LATF4
_FGS(GWRP_OFF & GCP_OFF);
_FOSCSEL(FNOSC_PRIPLL);
_FOSC(FCKSM_CSECMD & OSCIOFNC_OFF & POSCMD_XT);
_FWDT(FWDTEN_OFF);
int VALUE_OUT[NUM_OUT]; // массив для выходного значения
float RAD_STEP;
float RAD_ACCUM;
float SIN_VALUE;
int i; // cycle for
unsigned int DmaBuffer;
void Init_ADC1(void);
void Ports_Init(void);
void Init_TMR2(void);
void Init_TMR3(void);
void Init_DMA0(void);
void __attribute__((interrupt, no_auto_psv)) _DMA0Interrupt(void);
void __attribute__((interrupt, no_auto_psv)) _T2Interrupt(void);
void __attribute__((interrupt, auto_psv)) _SPI1Interrupt(void);
void ProcessADCSamples(int * AdcBuffer);
void Init_SPI1(void);
void Write_SPI1(int command);
void Sinus_OUT(void);
/******************************************************************************
Основная программа
******************************************************************************/
int main(void)
{
/* Configure Oscillator to operate the device at 80MHz.
* Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
* Fosc= 8MHz*40/(2*2)=80Mhz for 8MHz input clock */
PLLFBD = 38; // M = PLLDIV + 2, умножить на 40, это биты CLKDIV
CLKDIVbits.PLLPOST = 0; // N1=2 Деление входной частоты (если 0 то на 2) (если 1 то на 4)
CLKDIVbits.PLLPRE = 0; // N2=2 Деление входной чаты на 2
OSCTUN = 0;
RCONbits.SWDTEN = 0; // Disable Watch Dog Timer
__builtin_write_OSCCONH(0x03); /* Initiate Clock Switch to Primary Oscillator with PLL (NOSC=0b011)*/
__builtin_write_OSCCONL(0x01);
while (OSCCONbits.COSC != 0b011); /* Wait for Clock switch to occur */
while (!OSCCONbits.LOCK);
//-----------------------------------------------------------------------------------------------------------
// INTCON1bits.NSTDIS = 0; // запрет всех прерываний
AD1PCFGL=0xFFFF;
AD1PCFGH=0xFFFF;
AD2PCFGL = 0xFFFF; // all digital
Ports_Init();
Init_SPI1();
Sinus_OUT();
Init_TMR2();
while(1)
{
Nop();
}
}
Комментариев нет:
Отправить комментарий