📄 spi_dac5617.c
字号:
//===========================================================
//
// 文件名称:SPI_DAC5617
//
// TITLE: DSP28 SPI - DAC TLV5617A,
// 采用CPU Timer0产生定时周期50ms,输出锯齿波
// 使能看门狗,在主函数中刷新计数器
//
//===========================================================
#include "DSP281x_Device.h"
// 函数原形声明
void Gpio_select(void);
void InitSystem(void);
void SPI_Init(void);
void DAC_Update(char channel,int value);
interrupt void cpu_timer0_isr(void); // 定时器中断
void main(void)
{
int Voltage_A = 0;
int Voltage_B = 511;
InitSystem(); // 初始化处理器内核寄存器
Gpio_select(); // 设置IO功能
InitPieCtrl(); // 调用外设中断扩展初始化单元 PIE-unit ( 代码 : DSP281x_PieCtrl.c)
InitPieVectTable(); // 初始化 PIE vector向量表 ( 代码 : DSP281x_PieVect.c )
// 重新映射 PIE - Timer 0的中断
EALLOW; // 解除寄存器保护
PieVectTable.TINT0 = &cpu_timer0_isr;
EDIS; // 使能寄存器保护
InitCpuTimers();
// 配置 CPU-Timer 0 周期50 ms:
// 150MHz CPU 频率, 50000 微妙中断周期
ConfigCpuTimer(&CpuTimer0, 150, 50000);
// 使能PIE内的 TINT0 : Group 1 interrupt 7
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
// 使能 CPU INT 1 (CPU定时器0中断)
IER = 1;
// 全局中断使能和更高优先级的实时调试事件
EINT; // 全局中断使能INTM
ERTM; // 使能实时调试中断DBGM
CpuTimer0Regs.TCR.bit.TSS = 0;
SPI_Init();
while(1)
{
while(CpuTimer0.InterruptCount < 3); // 等待定时中断3次
CpuTimer0.InterruptCount = 0;
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; // 看门狗控制
EDIS;
}
}
void Gpio_select(void)
{
EALLOW;
GpioMuxRegs.GPAMUX.all = 0x0; // 所有GPIO引脚配置为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 配置为输入
GpioMuxRegs.GPBDIR.all = 0x0; // GPIO PORT 配置为输入
GpioMuxRegs.GPDDIR.all = 0x0; // GPIO PORT 配置为输入
GpioMuxRegs.GPDDIR.bit.GPIOD0 = 1; // DAC的/CS使能信号
GpioMuxRegs.GPDDIR.bit.GPIOD6 = 1; // EEPROM的/CS使能信号
GpioMuxRegs.GPEDIR.all = 0x0; // GPIO PORT 配置为输入
GpioMuxRegs.GPFDIR.all = 0x0; // GPIO PORT 配置为输入
GpioMuxRegs.GPGDIR.all = 0x0; // GPIO PORT 配置为输入
GpioDataRegs.GPBDAT.all = 0x0; // GPIO PORT 配置为输入
GpioDataRegs.GPDDAT.bit.GPIOD0 = 1; // DAC的/CS信号处于无效状态
GpioDataRegs.GPDDAT.bit.GPIOD5 = 1; // EEPROM的/CS信号处于无效状态
GpioMuxRegs.GPAQUAL.all = 0x0; // 设置所有 GPIO 输入的量化值等于0
GpioMuxRegs.GPBQUAL.all = 0x0;
GpioMuxRegs.GPDQUAL.all = 0x0;
GpioMuxRegs.GPEQUAL.all = 0x0;
EDIS;
}
void InitSystem(void)
{
EALLOW;
SysCtrlRegs.WDCR= 0x00AF; // 配置看门狗
// 0x00E8 禁止看门狗,预定标系数Prescaler = 1
// 0x00AF 不禁止看门狗, 预定标系数Prescaler = 64
SysCtrlRegs.SCSR = 0; // 看门狗产生复位
SysCtrlRegs.PLLCR.bit.DIV = 10; // 配置处理器锁相环,倍频系数为5
SysCtrlRegs.HISPCP.all = 0x1; // 配置高速外设时钟分频系数: 2
SysCtrlRegs.LOSPCP.all = 0x2; // 配置低速外设时钟分频系数: 4
// 使用的外设时钟时钟设置:
// 一般不使用的外设的时钟禁止,降低系统功耗
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; //使能SPI时钟
SysCtrlRegs.PCLKCR.bit.ECANENCLK=0;
SysCtrlRegs.PCLKCR.bit.ADCENCLK=0;
EDIS;
}
interrupt void cpu_timer0_isr(void)
{
CpuTimer0.InterruptCount++;
// 每个定时器中断清除一次看门狗计数器
EALLOW;
SysCtrlRegs.WDKEY = 0x55; // 看门狗控制
EDIS;
// 响应中断并允许系统接收更多的中断
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}
void SPI_Init(void)
{
SpiaRegs.SPICCR.all = 0x004F;
// Bit 7 , Reset = 0 :
// Bit 6 , 时钟极性 = 1 : 在SPICLK的下降沿输出数据
// , 结合相位控制CLOCK PHASE = 1 : 在SPICLK的下降沿半个周期前输出数据
// Bit 5 , 保留
// Bit 4 , SPILBK = 0 :非循环模式
// Bit 3-0, Chars = 1111 : 16 bit 数据传输
SpiaRegs.SPICTL.all =0x000E;
// Bit 7-5 : 保留
// Bit 4 , 过载 INT Enable = 0 :禁止接收器过载中断
// Bit 3 , Clock-Phase = 1 :半个周期的延时
// Bit 2 , Master/Slave = 1 :MASTER模式
// Bit 1 , Talk = 1 :使能传输
// Bit 0 , SPI INT ENA = 0 :禁止SPI
SpiaRegs.SPIBRR = 124;
// SPI通信波特率 = LSPCLK / ( SPIBRR + 1)
// = 37,5 MHz / ( 124 + 1 )
// = 300 kHz
SpiaRegs.SPICCR.bit.SPISWRESET = 1; // SPI退出复位
}
void DAC_Update(char channel, int value)
{
int i;
GpioDataRegs.GPDDAT.bit.GPIOD0 = 0; // DAC的/CS有效
if (channel == 'B')
SpiaRegs.SPITXBUF = 0x1000 + (value<<2); // 发送数据到DAC缓冲
if (channel == 'A')
SpiaRegs.SPITXBUF = 0x8000 + (value<<2); // 将数据传送到DAC-A并刷新DAC-B的缓冲
while (SpiaRegs.SPISTS.bit.INT_FLAG == 0) ; // 等待传输结束
for (i=0;i<100;i++); // 等待DAC结束
GpioDataRegs.GPDDAT.bit.GPIOD0 = 1; // DAC的/CS无效
i = SpiaRegs.SPIRXBUF; // 对SPI接收缓冲空读操作使SPI复位
}
//===========================================================================
// 代码结束
//===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -