文章目录
前言
使用ADCINA0检测DAC的DB通道输出的电压值,并将DAC的DB输出电压值与ADCINA0检测的电压值通过串口输出。
SPI将DSP的指令发送给DAC实现DA转换
SCI将DSP存储的DAC转换结果和ADC采样结果发送给上位机
特此记录,加深印象~
1 SCIA FIFO 串口通信配置
博客TI DSP 28335 SCI FIFO中断 串口232通信已仔细介绍过SCIA配置。
此处不再详细展开介绍。
void UARTa_Init(Uint32 baud)
{
unsigned char scihbaud=0;
unsigned char scilbaud=0;
Uint16 scibaud=0;
scibaud=37500000/(8*baud)-1;
scihbaud=scibaud>>8;
scilbaud=scibaud&0xff;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.SCIAENCLK = 1; // SCI-A
EDIS;
InitSciaGpio();
//Initalize the SCI FIFO
SciaRegs.SCIFFTX.all=0xE040;
SciaRegs.SCIFFRX.all=0x204f;
SciaRegs.SCIFFCT.all=0x0;
// Note: Clocks were turned on to the SCIA peripheral
// in the InitSysCtrl() function
SciaRegs.SCICCR.all =0x0007; // 1 stop bit, No loopback
// No parity,8 char bits,
// async mode, idle-line protocol
SciaRegs.SCICTL1.all =0x0003; // enable TX, RX, internal SCICLK,
// Disable RX ERR, SLEEP, TXWAKE
SciaRegs.SCICTL2.all =0x0003;
SciaRegs.SCIHBAUD =scihbaud; // 9600 baud @LSPCLK = 37.5MHz.
SciaRegs.SCILBAUD =scilbaud;
// SciaRegs.SCICCR.bit.LOOPBKENA =1; // Enable loop back
SciaRegs.SCICTL1.all =0x0023; // Relinquish SCI from Reset
}
// Transmit a character from the SCI'
void UARTa_SendByte(int a)
{
while (SciaRegs.SCIFFTX.bit.TXFFST != 0);
SciaRegs.SCITXBUF=a;
}
void UARTa_SendString(char * msg)
{
int i=0;
while(msg[i] != '\0')
{
UARTa_SendByte(msg[i]);
i++;
}
}
2 DAC 数模转换 配置
2.1 TLV5620芯片简介
TLV5620是一个四通道8位数模转换(DAC)器件,3V-3.6V单电源供电,3线串行总线。
它具有11位命令字,包括八位数据、两个DAC选择位和一个范围位,后者允许进行选择1或2倍的输出范围。
通道选择位 | 输出范围位 | 数据位 |
---|---|---|
A1A0 | RNG | D7D6D5D4D3D2D1D0 |
DAC寄存器是双缓冲的,允许一组完整的新值写入到设备, 然后所有的DAC输出通过控制LDAC同时更新。
本开发板TLV5620芯片进行DAC转换时,数据的加载才用的方式为,将LDAC脚接地,通过LOAD脚控制转换及更新。
当进行DAC转换时,在CLK的每个下降沿数据被锁存到数据终端。当所有数据位送入之后,LOAD为低脉冲将数据从串行输入寄存器转移到选定的DAC输出通道。
2.2 TLV5620初始化函数
void TLV5620_Init(void)
{
EALLOW;
// 开启SPIA时钟
SysCtrlRegs.PCLKCR0.bit.SPIAENCLK = 1; // SPI-A
EDIS;
// 初始化SpiaGPIO
InitSpiaGpio();
// DAC LOAD脚GPIO配置
EALLOW;
GpioCtrlRegs.GPAMUX2.bit.GPIO26 = 0; // GPIO
GpioCtrlRegs.GPADIR.bit.GPIO26 = 1; // 输出
GpioCtrlRegs.GPAPUD.bit.GPIO26 = 0; // 上拉
EDIS;
// Spia配置
SpiaRegs.SPICCR.all =0x0a; // 进入初始状态,数据在上升沿输出,自测禁止,11位数据模式
SpiaRegs.SPICTL.all =0x0006; // 禁止溢出中断,普通SPI时钟,主机模式,使能发送,禁止SPI中断
SpiaRegs.SPIBRR =0x0031; //SPI波特率=37.5M/50=0.75MHZ
SpiaRegs.SPICCR.all =0x8a; //退出初始状态,配置生效
SpiaRegs.SPIPRI.bit.FREE = 1; // 自由运行,忽视仿真中断
// DAC LOAD脚拉高
GpioDataRegs.GPASET.bit.GPIO26 = 1;
}
2.2 DAC 输出函数
channel是4个通道的地址(00,01,10,11),rng是输出范围,dat是0~256数据
void DAC_SetChannelData(unsigned char channel,unsigned char rng,unsigned char dat)
{
Uint16 dacvalue=0;
//注意这里的有效数据是11位,SPI初始化中也进行了定义
dacvalue = ((channel<<14) | (rng<<13) | (dat<<5));
while(SpiaRegs.SPISTS.bit.BUFFULL_FLAG ==1); //判断SPI的发送缓冲区是否为空
SpiaRegs.SPITXBUF = dacvalue; //把发送的数据写入SPI发送缓冲区
while( SpiaRegs.SPISTS.bit.BUFFULL_FLAG==1);
// DAC LOAD脚拉低 传递数据给DAC
GpioDataRegs.GPACLEAR.bit.GPIO26=1;
DELAY_US(2);
// DAC LOAD脚拉高
GpioDataRegs.GPASET.bit.GPIO26 = 1;
DELAY_US(10);
}
3 ADC 模数转换 配置
博客TI DSP 28335 ADC ePWMSOC启动和Timer0启动已仔细介绍过ADC配置。
此处不再详细展开介绍。
该例程ADC采用软件触发。
注:不同于之前的ePWMSOC启动和Timer0启动,本例程采用连续采样模式(无需再次启动,但需要及时读取AD转换值)
AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Setup continuous run
完整ADC配置如下:
void ADC_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // ADC
EDIS;
// Specific clock setting for this example:
EALLOW;
SysCtrlRegs.HISPCP.all = 3; // HSPCLK = SYSCLKOUT/ADC_MODCLK
EDIS;
InitAdc(); // For this example, init the ADC
// Specific ADC setup for this example:
AdcRegs.ADCTRL1.bit.ACQ_PS = 0x0f;
AdcRegs.ADCTRL3.bit.ADCCLKPS = 1;
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascaded mode
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
AdcRegs.ADCTRL1.bit.CONT_RUN = 1; // Setup continuous run
// Start SEQ1 软件触发
AdcRegs.ADCTRL2.all = 0x2000;
}
Uint16 Read_ADCValue(void)
{
while (AdcRegs.ADCST.bit.INT_SEQ1== 0);
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;
return AdcRegs.ADCRESULT0>>4;
}
4 MAIN
//使用一根短接线,将DAC模块的DB输出口与P8排针的ADA0管脚连接。
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "uart.h"
#include "stdio.h"
#include "tlv5620.h"
#include "adc.h"
void main()
{
int i=0;
Uint16 dacvalue=64;
float dac_vol;
Uint16 dac_temp=0;
char dacbuf[6];
float adc_vol;
Uint16 adc_temp=0;
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
LED_Init();
TIM0_Init(150,200000);//200ms
UARTa_Init(4800);
TLV5620_Init();
ADC_Init();
while(1)
{
i++;
if(i%1000==0)
{
DAC_SetChannelData(1,0,dacvalue*2);
dac_vol=dacvalue*2*1.9/256;
dac_temp=dac_vol*100;
dacbuf[0]=dac_temp/100+0x30;
dacbuf[1]='.';
dacbuf[2]=dac_temp%100/10+0x30;
dacbuf[3]=dac_temp%100%10+0x30;
dacbuf[4]='V';
dacbuf[5]='\0';
UARTa_SendString("\r\nCH2_VOL=");
UARTa_SendString(dacbuf);
adc_vol=(float)Read_ADCValue()*3.0/4095;
adc_temp=adc_vol*100;
dacbuf[0]=adc_temp/100+0x30;
dacbuf[1]='.';
dacbuf[2]=adc_temp%100/10+0x30;
dacbuf[3]=adc_temp%100%10+0x30;
dacbuf[4]='V';
dacbuf[5]='\0';
UARTa_SendString("\r\nADC_CH1_VOL=");
UARTa_SendString(dacbuf);
}
DELAY_US(1*1000);
}
}
5 实验分析
dac_vol=dacvalue*2*1.9/256=64*2*1.9/256=0.95V
ADC采样电压为0.94V
总结
第42篇
21年第一更
要继续加油啊,战死为止
Flag完不成了,春节前肯定学不完DSP了
个人水平有限,有问题欢迎各位大神批评指正!