This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28379D:通过 sci 发送 ADC 结果时出现问题

Guru**** 2606375 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/680506/tms320f28379d-problem-with-transmitting-the-adc-result-via-the-sci

器件型号:TMS320F28379D

您好!
我修正了"adc_soc_ePWM_cpu01"、以包含串行通信接口(SCI)、如下所示代码所示。 我想将 ADC 的结果(结果)传输到超级终端。 终端工作和我收到了 hello World 和 Conversion 完成消息,但它没有收到结果。 我使用 sprintf 将交互器存储在字符串数组中、但终端未接收到任何内容。

可能的主要问题是、为了能够传输 ADC 结果、我应该做些什么更改。  
我的第二个问题是、当我尝试两个位置时、应该将发送消息放置在何处、一个在 ADC_ISR 中以红色突出显示、另一个在绿色。  此时两个位置都不发送消息。 但是、ISR 中的值会使转换结果不正确。  

非常感谢你的帮助

此致  

/
//包含的文件
//
#include "F28x_Project.h"
//#include "stdio.h"

//
//函数原型
//
void ConfigureADC (void);
void ConfigureEPWM (void);
void SetupADCepwm (uint16通道);
中断 void adca1_ISR (void);
//中断 void adcb1_ISR (void);
//中断 void adcd1_ISR (void);

void scia_echoback_init (void);
void scia_fifo_init (void);
void scia_xmit (int a);
void scia_msg (char * msg);
//void scia_sprintfmsg (int *msg);//我添加了此行


//
//定义
//
#define results_buffer_size 64
//#define ADC_SAMPLE_PERIOD 0x1000 // 1999 =具有100MHz ePWM 时钟的50kHz 采样

//
//全局
//
uint16 AdcaResults[results_buffer_size];
float32 AdcaResults1[results_buffer_size];
//uint16 AdcbResults[results_buffer_size];
//uint16 AdcdResults[results_buffer_size];
uint16结果索引;
uint16结果索引 x1;
//uint16 LoopCount;//来自 sci 示例
易失性 uint16 bufferFull;
易失性 uint16 bufferFull1;

char sprintf_msg[5];

int z;
char *msg;

void main (void)

//
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 F2837xD_SYSCTRL.c 文件中。
//
InitSysCtrl();

//
//步骤2. 初始化 GPIO:
//此示例函数位于 F2837xD_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
//
InitGpio();//针对此示例跳过

//
//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
//
Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 F2837xD_PIECTRL.c 文件中。
//
InitPieCtrl();

//
//禁用 CPU 中断并清除所有 CPU 中断标志:
//
IER = 0x0000;
IFR = 0x0000;

//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 F2837xD_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 F2837xD_PieVect.c 中找到
//
InitPieVectTable();

//
//映射 ISR 函数
//
EALLOW;
PieVectTable.ADCA1_INT =&adca1_ISR;//针对 ADCA 中断1的函数
// PieVectTable.ADCB1_INT =&adcb1_ISR;// ADCB 中断1的函数
// PieVectTable.ADCD1_INT =&adcd1_ISR;// ADCD 中断1的函数
EDIS;

//
//配置 ADC 并为其加电
//
ConfigureADC();

//
//配置 ePWM
//
ConfigureEPWM();

//
//在通道0上设置用于 ePWM 触发转换的 ADC
//
SetupADCepwm (0);

//
//启用全局中断和更高优先级的实时调试事件:
//
IER |= M_INT1;//启用组1中断
EINT;//启用全局中断 INTM
ERTM;//启用全局实时中断 DBGM

//
//初始化结果缓冲区
//
for (resultsIndex = 0;resultsIndex < results_buffer_size;resultsIndex++)

AdcaResults[resultsIndex]=0;
// AdcbResults[resultsIndex]= 0;
// AdcdResults[resultsIndex]= 0;
// sprintf (sprintf_msg、"%d"、AdcaResults[resultsIndex]);
// scia_msg (sprintf_msg);

resultsIndex = 0;
bufferFull = 0;

for (results 索引 x1 = 0;results 索引 x1 < results_buffer_size;results 索引 x1++)

AdcaResults1[结果 x1]= 0;
// AdcbResults[resultsIndex]= 0;
// AdcdResults[resultsIndex]= 0;
// sprintf (sprintf_msg、"%d"、AdcaResults[resultsIndex]);
// scia_msg (sprintf_msg);

结果索引 x1 = 0;
bufferFull1 = 0;
//
//启用 PIE 中断
//
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
// PieCtrlRegs.PIEIER1.bit.INTx2 = 1;
// PieCtrlRegs.PIEIER1.bit.INTx6=1;


//
//对于这个示例、只初始化针对 SCI-A 端口的引脚。
// GPIO_SetupPinMux ()-设置 GPxMUX1/2和 GPyMUX1/2寄存器位
// GPIO_SetupPinOptions ()-设置 GPIO 的方向和配置
//这些函数可在 F2837xD_GPIO.c 文件中找到。
//
GPIO_SetupPinMux (28、GPIO_MUX_CPU1、1);
GPIO_SetupPinOptions (28、GPIO_INPUT、GPIO_PushPull);
GPIO_SetupPinMux (29、GPIO_MUX_CPU1、1);
GPIO_SetupPinOptions (29、GPIO_OUTPUT、GPIO_异 步);


scia_fifo_init();//初始化 SCI FIFO
scia_echoback_init ();//初始化用于 echoback 的 SCI

MSG ="\r\n\n\nHello World!\n\n";
scia_msg (msg);

int values[5]={'1'、'2'、'2'、'5'、'6'}; //我添加了第185 - 192行
对于(z=0;z<5;z++){
int num =值[z];
scia_xmit (num);


MSG ="\r\n 您将输入一个字符,DSP 将回显它! \n\n";
scia_msg (msg);

//
//同步 ePWM
//
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=1;

//
//循环无限地进行转换
//
操作

//
//启动 ePWM
//
EPwm1Regs.ETSEL.bit.SOCAEN = 1;//启用 SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 0;//取消冻结、并进入递增计数模式

//
//等待、而 ePWM 导致 ADC 转换、然后导致中断、
//填充结果缓冲区,最终设置 bufferFull
//flag
//
while (!bufferFull);
bufferFull = 0;//清除缓冲区已满标志

while (!bufferFull1);
bufferFull = 0;//清除缓冲区已满标志

//
//停止 ePWM
//
EPwm1Regs.ETSEL.bit.SOCAEN = 0;//禁用 SOCA
EPwm1Regs.TBCTL.bit.CTRMODE = 3;//冻结计数器

//
//此时,AdcaResults[]包含一系列转换
//从所选通道
//


sprintf (sprintf_msg、"%d"、AdcResults);
scia_msg (sprintf_msg);

MSG ="\r\n\n\n 转换完成!\n\n";
scia_msg (msg);


//
//软件断点,再次点击运行以获取更新的转换
//
asm (" ESTOP0");

//InitSci (结果);

} while (1);

//
// ConfigureADC -写入 ADC 配置并为两者加电
// ADC A 和 ADC B
//
空配置 ADC (空)

EALLOW;

//
//写入配置
//
AdcaRegs.ADCCTL2.bit.prescale = 6;//将 ADCCLK 分频器设置为/4
AdcSetMode (ADC_ADCA、ADC_resolution_12位、ADC_SIGNALMODE_SINGLE);

//
//将脉冲位置设置为晚期
//
AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1;

//
//为 ADC 加电
//
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;

//
//延迟1ms 以允许 ADC 加电时间
//
DELAY_US (1000);

EDIS;

//
// ConfigureEPWM -配置 ePWM SOC 并比较值
//
空配置 EPWM (空)

EALLOW;
//假设 ePWM 时钟已启用
EPwm1Regs.ETSEL.bit.SOCAEN = 0;//禁用组上的 SOC
EPwm1Regs.ETSEL.bit.SOCASEL = 4;//在递增计数时选择 SOC
EPwm1Regs.ETPS.bit.SOCAPRD = 1;//在发生第一个事件时生成脉冲
EPwm1Regs.CMPA.bit.CMPA = 0x0800;//将比较 A 值设置为2048个计数、其值为0x0800
EPwm1Regs.TBPRD = 0x1000;//将周期设置为4096个计数、它是0x1000
EPwm1Regs.TBCTL.bit.CTRMODE = 3;//冻结计数器
EDIS;

//
// SetupADCepwm -设置 ADC ePWM 采集窗口
//
void SetupADCepwm (uint16通道)

uint16 acqps;

//
//根据分辨率确定最小采集窗口(在 SYSCLKS 中)
//
if (adc_resolution_12bit = AdcaRegs.ADCCTL2.bit.resolution)

acqps = 14;//75ns

否则、//分辨率为16位

acqps = 63;//320ns

//
//选择要转换的通道和转换结束标志
//
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL =通道;//SOC0将转换引脚 A0
AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps;//采样窗口为100个 SYSCLK 周期
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 5;// ePWM1 SOCA/C 上的触发
AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// SOC0结束将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用 INT1标志
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除
EDIS;

//
// adca1_ISR -在 ISR 中读取 ADC 缓冲器
//
中断 void adca1_ISR (void)

AdcaResults[resultsIndex++]=AdcaResultRegs.ADCRESULT0/500;

if (results_buffer_size <= resultsIndex)

resultsIndex = 0;
bufferFull = 1;

// InitSci (结果);

//sprintf (sprintf_msg、"%d"、结果);
// msg ="\r\n\nHello Hayder!\n\n";
//scia_msg (sprintf_msg);

AdcaResults1[Indexsx1++]=(float32) AdcaResultRegs.ADCRESULT0 *(float32)(3/1096);
if (results_buffer_size <= resultsIndex1)

结果索引 x1 = 0;
bufferFull1 = 1;


AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 INT1标志
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;

//
// scia_echoback_init -测试1、SCIA DLB、8位字、波特率0x000F、
//默认,1个停止位,无奇偶校验
//

void scia_echoback_init ()

//
//注意:SCIA 外设的时钟被打开
//在 InitSysCtrl()函数中
//

SciaRegs.SCICCR.all = 0x0007;// 1停止位,无回路
//无奇偶校验,8个字符位,
//异步模式,空闲线协议
SciaRegs.SCICTL1.all = 0x0003;//启用 TX、RX、内部 SCICLK、
//禁用 RX ERR、睡眠、TXWAKE
SciaRegs.SCICTL2.all = 0x0003;
SciaRegs.SCICTL2.bit.TXINTENA=1;
SciaRegs.SCICTL2.bit.RXBKINTENA=1;

//
// SCIA 为9600波特
//@LSPCLK = 50MHz (200MHz SYSCLK) HBAUD = 0x02且 LBAUD = 0x8B。
//@LSPCLK = 30MHz (120MHz SYSCLK) HBAUD = 0x01且 LBAUD = 0x86。
//
SciaRegs.SCIHBAUD.ALL = 0x0002;
SciaRegs.SCILBAUD.ALL = 0x008B;

SciaRegs.SCICTL1.all = 0x0023;//从复位中撤回 SCI

//
// scia_xmit -从 SCI 发送一个字符
//
void scia_xmit (int a)

while (SciaRegs.SCIFFTX.bit.TXFFST!= 0){}
SciaRegs.SCITXBUF.ALL =A;


//
// scia_msg -通过 SCIA 发送消息
//
void scia_msg (char * msg)

int i;
I = 0;
while (msg[i]!='\0')

scia_xmit (msg[i]);
i++;


// scia_fifo_init -初始化 SCI FIFO
//
void scia_fifo_init()

SciaRegs.SCIFFTX.ALL = 0xE040;
SciaRegs.SCIFFRX.ALL = 0x2044;
SciaRegs.SCIFFCT.all = 0x0;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Hayder、

    我认为一个好的开始是手动设置 char*的 ASCII 值并将其发送到模拟 ADC 结果。

    例如、假设您以十六进制编码、结果0x5A8我认为将为{53、65、56}、这是最简单的。 您可能还需要进行实验以确定是否需要零端接器。

    确认所需的编码有效后、请使用某种方法对 ADC 结果进行编码(调用 sprintf 等函数)。 然后、您可以检查存储器中的输出、以查看是否按照您的预期进行了编码。 如果不是、您需要处理编码、如果是、您可以发送并查看是否满足您的期望。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Devin、

    感谢您的回复。 以下是此示例上的更新、通过 sci 进行传输时产生了正确的转换:

    首先:在 Adca_ISR 中:
    中断 void adca1_ISR (void)

    AdcaResults[resultsIndex++]=AdcaResultRegs.ADCRESULT0;
    if (results_buffer_size = resultsIndex){
    对于(z=0;z <RESULTS_BUFFER_SIZE;z++)

    Vin =结果[z];
    SEND_RESULT (Vin);



    if (results_buffer_size <= resultsIndex)

    resultsIndex = 0;
    bufferFull = 1;
    // InitSci (结果);

    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 INT1标志
    PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;


    第二:我添加了以下函数、以便在文件末尾传输 ADC 结果:
    void send_result (uint16分辨率)

    int b3、b2、b1、b0;
    B3 =(res/1000)+48;
    B2 =((res%1000)/100)+48;
    B1 =((res%100)/10)+48;
    B0 =(res%10)+48;
    scia_xmit (B3);
    scia_xmit (B2);
    scia_xmit (b1);
    scia_xmit (b0);
    MSG ="、";
    scia_msg (msg);
    返回;



    波特率为9600时这些变化、我认为 ADC 的采样频率为12kHz、项目转换 A/D 并正确传输。

    供参考我在另一个主题中提到了更多详细信息。
    此致
    Hayder