📄 spi_dac_adc.c
字号:
//
// Lab7A : TMS320F2812 Teaching CD ROM
// (C) Frank Bormann
//
//###########################################################################
//
// FILE: Lab7A.c
//
// TITLE: DSP28 SPI - DAC TLV5617A, 2 sawtooth voltages
// CPU Timer0 ISR every 50 ms
// ADCINA1 and ADCINB1 to measure the DAC voltages
// Watchdog active , served in ISR and main-loop
//
//###########################################################################
#include "DSP281x_Device.h"
// Prototype statements for functions found within this file.
void Gpio_select(void);
void InitSystem(void);
void SPI_Init(void);
void DAC_Update(char channel,int value);
interrupt void cpu_timer0_isr(void); // Prototype for Timer 0 Interrupt Service Routine
interrupt void ADC_ISR(void);
void main(void)
{
int Voltage_A = 0;
int Voltage_B = 511;
InitSystem(); // Initialize the DSP's core Registers
Gpio_select(); // Setup the GPIO Multiplex Registers
InitPieCtrl(); // Function Call to init PIE-unit ( code : DSP281x_PieCtrl.c)
InitPieVectTable(); // Function call to init PIE vector table ( code : DSP281x_PieVect.c )
// re-map PIE - entry for Timer 0 Interrupt
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.TINT0 = &cpu_timer0_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
InitCpuTimers();
// Configure CPU-Timer 0 to interrupt every 50 ms:
// 150MHz CPU Freq, 50000 祍econds interrupt period
ConfigCpuTimer(&CpuTimer0, 150, 50000);
// Enable TINT0 in the PIE: Group 1 interrupt 7
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
// Enable CPU INT1 which is connected to CPU-Timer 0:
IER = 1;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
CpuTimer0Regs.TCR.bit.TSS = 0;
SPI_Init();
InitAdc();
// Configure ADC
AdcRegs.ADCTRL1.bit.SEQ_CASC = 0; // Dual Sequencer Mode
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // No Continuous run
AdcRegs.ADCTRL1.bit.CPS = 0; // prescaler = 1
AdcRegs.ADCMAXCONV.all = 0x0001; // Setup 2 conv's on SEQ1
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x1; // Setup ADCINA0 as 1st SEQ1 conv.
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x9; // Setup ADCINB0 as 2nd SEQ1 conv.
AdcRegs.ADCTRL2.bit.EVA_SOC_SEQ1 = 0; // Disable EVASOC to start SEQ1
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // Enable SEQ1 interrupt (every EOS)
AdcRegs.ADCTRL3.bit.ADCCLKPS = 2; // Divide HSPCLK by 4
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.ADCINT = &ADC_ISR;
EDIS; // This is needed to disable write to EALLOW protected registers
PieCtrlRegs.PIEIER1.bit.INTx6 = 1; // Enable ADCINT in PIE group 1
while(1)
{
while(CpuTimer0.InterruptCount < 3); // wait for Timer 0
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; // start ADC
CpuTimer0.InterruptCount = 0;
GpioDataRegs.GPBTOGGLE.bit.GPIOB0 = 1; // Toggle LED B0
DAC_Update('B',Voltage_B);
DAC_Update('A',Voltage_A);
if (Voltage_A++ > 511) Voltage_A = 0;
if (Voltage_B-- < 0) Voltage_B = 511;
EALLOW;
SysCtrlRegs.WDKEY = 0xAA; // and serve watchdog #2
EDIS;
}
}
void Gpio_select(void)
{
EALLOW;
GpioMuxRegs.GPAMUX.all = 0x0; // all GPIO port Pin's to I/O
GpioMuxRegs.GPBMUX.all = 0x0;
GpioMuxRegs.GPDMUX.all = 0x0;
GpioMuxRegs.GPFMUX.all = 0xF;
GpioMuxRegs.GPEMUX.all = 0x0;
GpioMuxRegs.GPGMUX.all = 0x0;
GpioMuxRegs.GPADIR.all = 0x0; // GPIO PORT as input
GpioMuxRegs.GPBDIR.all = 0x00FF; // GPIO Port B15-B8 input , B7-B0 output
GpioMuxRegs.GPDDIR.all = 0x0; // GPIO PORT as input
GpioMuxRegs.GPDDIR.bit.GPIOD0 = 1; // /CS for DAC
GpioMuxRegs.GPDDIR.bit.GPIOD6 = 1; // /CS for EEPROM
GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT as input
GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT as input
GpioMuxRegs.GPGDIR.all = 0x0; // GPIO PORT as input
GpioDataRegs.GPBDAT.all = 0x0000; // Switch off LED's ( B7...B0)
GpioDataRegs.GPDDAT.bit.GPIOD0 = 1; // deactivate /CS for the DAC
GpioDataRegs.GPDDAT.bit.GPIOD5 = 1; // deactivate /CS for the EEPROM
GpioMuxRegs.GPAQUAL.all = 0x0; // Set GPIO input qualifier values to zero
GpioMuxRegs.GPBQUAL.all = 0x0;
GpioMuxRegs.GPDQUAL.all = 0x0;
GpioMuxRegs.GPEQUAL.all = 0x0;
EDIS;
}
void InitSystem(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x00AF; // Setup the watchdog
// 0x00E8 to disable the Watchdog , Prescaler = 1
// 0x00AF to NOT disable the Watchdog, Prescaler = 64
SysCtrlRegs.SCSR = 0; // Watchdog generates a RESET
SysCtrlRegs.PLLCR.bit.DIV = 10; // Setup the Clock PLL to multiply by 5
SysCtrlRegs.HISPCP.all = 0x1; // Setup Highspeed Clock Prescaler to divide by 2
SysCtrlRegs.LOSPCP.all = 0x2; // Setup Lowspeed CLock Prescaler to divide by 4
// Peripheral clock enables set for the selected peripherals.
SysCtrlRegs.PCLKCR.bit.EVAENCLK=0;
SysCtrlRegs.PCLKCR.bit.EVBENCLK=0;
SysCtrlRegs.PCLKCR.bit.SCIAENCLK=0;
SysCtrlRegs.PCLKCR.bit.SCIBENCLK=0;
SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=0;
SysCtrlRegs.PCLKCR.bit.SPIENCLK=1;
SysCtrlRegs.PCLKCR.bit.ECANENCLK=0;
SysCtrlRegs.PCLKCR.bit.ADCENCLK=1;
EDIS;
}
interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
// Serve the watchdog every Timer 0 interrupt
EALLOW;
SysCtrlRegs.WDKEY = 0x55; // Serve watchdog #1
EDIS;
// Acknowledge this interrupt to receive more interrupts from group 1
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
void SPI_Init(void)
{
SpiaRegs.SPICCR.all = 0x004F;
// Bit 7 , Reset = 0 :
// Bit 6 , Clock Polarity = 1 : data output on falling edge of CLK
// , together with CLOCK PHASE = 1 : data output is one half cycle before
// , falling edge pf SPICLK
// Bit 5 , reserved
// Bit 4 , SPILBK = 0 : no loopback mode
// Bit 3-0 , Chars = 1111 : 16 bit data transfer
SpiaRegs.SPICTL.all =0x000E;
// Bit 7-5 : reserved
// Bit 4 , Overrun INT Enable = 0 : Disable Receiver Overrun Interrupt
// Bit 3 , Clock-Phase = 1 , one half clock delay
// Bit 2 , Master/Slave = 1 , MASTER
// Bit 1 , Talk = 1 , Enable Transmission
// Bit 0 , SPI INT ENA = 0 , No SPI - Interrupts
SpiaRegs.SPIBRR = 124;
// SPI Baud Rate = LSPCLK / ( SPIBRR + 1)
// = 37,5 MHz / ( 124 + 1 )
// = 300 kHz
SpiaRegs.SPICCR.bit.SPISWRESET = 1; // relinquish SPI from reset
}
void DAC_Update(char channel, int value)
{
int i;
GpioDataRegs.GPDDAT.bit.GPIOD0 = 0; // activate /CS for the DAC
if (channel == 'B')
SpiaRegs.SPITXBUF = 0x1000 + (value<<2);// transmit data to DAC-Buffer
if (channel == 'A')
SpiaRegs.SPITXBUF = 0x8000 + (value<<2);// transmit data to DAC-A
// and update DAC-B with Buffer
while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; // wait for end of transmission
for (i=0;i<100;i++); // wait for DAC to finish off
GpioDataRegs.GPDDAT.bit.GPIOD0 = 1; // deactivate /CS for the DAC
i = SpiaRegs.SPIRXBUF; // dummy read of RXBUF to reset SPI
}
//===========================================================================
// End of SourceCode.
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -