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**** 2609895 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/679344/tms320f28379d-transmitting-the-result-of-adc-using-sci-to-hyperterminal

器件型号:TMS320F28379D

您好!  

我修改了 C28xx 的实验7示例、以包含带有一些更改 的 SCI_echoback main、从而将 AdcBuf 中的结果传输到超级终端。 lab7主代码和 SCI 代码如下所示:  

void main (void)

//-- CPU 初始化
InitSysCtrl();//初始化 CPU (文件:sysctrl.c)
InitGpio();//初始化共享 GPIO 引脚(文件:gpio.c)
InitXbar();//初始化输入、输出和 ePWM X-Bar (文件:xbar.c)
InitPieCtrl();//初始化并启用 PIE (文件:PIECTRL.c)
InitWatchdog();//初始化看门狗计时器(文件:watchdog.c)

//--外设初始化
InitAdca();//初始化 ADC-A (文件:adc.c)
InitDacb ();//初始化 DAC-B (文件:dac.c)
InitEPwm();//初始化 ePWM (文件:ePWM.c)
InitECap();//初始化 ECAP (文件:ecap.c)

//--启用全局中断
asm (" CLRC INTM、DBGM");//启用全局中断和实时调试

//--主循环
while (1)//无限循环-等待中断

asm (" NOP");
   InitSci();

// main 的末尾()

而 sci.c 文件为:  

#include "Lab.h"

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

//
//主函
//
空 InitSci (空)

// uint16 ReceivedChar;
char *msg;
// char *msg1;//我添加了此行

/*我删除了原始 Echoback 示例中的代码,因为我没有在此处删除它*/
//
//步骤4. 用户特定代码:
//
//LoopCount = 0;

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

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

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


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

scia_msg (msg);

/* for (;;)

MSG ="\r\n 输入字符:\0";
scia_msg (msg);

//
//等待 inc 字符
//
while (SciaRegs.SCIFFRX.bit.RXFFST ==0){}//等待空状态

//
//获取字符
//
ReceivedChar = SciaRegs.SCIRXBUF.ALL;

//
//回显字符
//
MSG ="您已发送:\0";
scia_msg (msg);
scia_xmit (ReceivedChar);

LoopCount++;
}*/

//
// 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)
//void scia_xmit (uint16 AdcBuf)

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

//
// 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;

//
//文件末尾 sci.c
//

我很困惑、我有几个问题:  

当我尝试在主循环中或在 ADC_ISR 中启动 SCI 以连续发送到 HEYPERterminal 时、最好在哪里启动 SCI?

SCI 正常运行、上面已发布的代码、并传输 hello world 消息和我创建的简单数组、 但我不知道如何将 AdcBuf 中的结果复制到 SCI 为了传输它、我尝试在 ADC_ISR 中启动 SCI、但它不起作用。
我非常感谢为解决此问题提供的任何帮助。  
此致

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

    您应该只初始化 SCI 一次、然后根据需要设置 SCI 后、您应该能够使用它来发送消息。

    在 ADC ISR 期间写入 SCI TX 缓冲器可能是合理的、但您需要考虑 ADC 生成数据的速度和 SCI 传输数据的速度;根据设置的方式、ADC 可能比 SCI 快得多。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Devin、

    是的、我只初始化了一次 sci、但我尝试了几个地方来找到最适合我的地方。 我将按照您的建议在 ADC_ISR 中启动它。

    ADC 使用的采样速度为50kHz、而 sci 的波特率为9600。 因为我要将 ADC 的结果传输到超级终端、所以这是否是我想要做的事情的问题?

    作为更新、我尝试了以下步骤:

    首先:我在 ADC_ISR 中启动了 sci、如下所示:

    中断空 ADCB1_ISR (空)// PIE1.2 @ 0x000D42 ADC-B 中断#1

      静态 uint16 * AdcBufPtr1 = AdcBuf1;          //指向缓冲区的指针

      PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;     //必须确认 PIE 组

    //--管理 ADC 寄存器

      AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;      //清除 ADCINT1标志

    //---读取 ADC 结果

      * AdcBufPtr1++= AdcbResultRegs.ADCRESULT0;      //读取结果

      InitSci();

    //--蛮力强制循环缓冲器

      if (AdcBufPtr1 =>(AdcBuF1 + ADC_BUF_LEN))

      AdcBufPtr1 = AdcBuF1;           //将指针回卷到开头

    第二步:为了传输 ADC 的结果,我在 sci 中添加了以下代码,但是在 HyperTerminal 上,我收到 了如下所示的奇怪符号:

    //此代码用于通过 sci 传输 ADC 的结果

           静态 uint16 * AdcBufPtr6;

           * AdcBufPtr6 = AdcbResultRegs.ADCRESULT0;

           内部 Z1;

           对于(Z1=0;Z1<4;Z1++){

                 int num1 =&AdcBufPtr6[Z1];

                  scia_xmit (num1);

                  }

    超级终端接收到的消息:

    由于 sci 只传输8位字符、我尝试将 adcResult 除以1000以将其更改为一个数字值、但仍然只传输随附图片中显示的符号。  

    最后一点、当我如上所述在 ISR 中启动 sci 时、ADC 结果变为不正确。 如何解决此问题?  

    此致  

    Hayder

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

    看起来您仍然在 ISR 内部调用 SCI 初始化=" InitSci();"。 我想您只想初始化模块一次。

    如果 SCI 波特率为9.6kbs、ePWM 为50kHz、则每个 ePWM 周期不能发送一个波特率。

    我将在此处评论另一个线程中的数据格式:
    e2e.ti.com/.../680506
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Devin、  
    感谢您的回复:

    我进行了流动变化 ,将 AdcResults 传输到终端:-  

    首先:我现在在实验7主文件中初始化 SCI 一次 、如下所示:  

    //-- CPU 初始化
    InitSysCtrl();//初始化 CPU (文件:sysctrl.c)
    InitGpio();//初始化共享 GPIO 引脚(文件:gpio.c)
    InitXbar();//初始化输入、输出和 ePWM X-Bar (文件:xbar.c)
    InitPieCtrl();//初始化并启用 PIE (文件:PIECTRL.c)
    InitWatchdog();//初始化看门狗计时器(文件:watchdog.c)

    //--外设初始化
    InitSci();
    InitAdca();//初始化 ADC-A (文件:adc.c)
    InitDacb ();//初始化 DAC-B (文件:dac.c)
    InitEPwm();//初始化 ePWM (文件:ePWM.c)
    InitECap();

    //--启用全局中断
    asm (" CLRC INTM、DBGM");//启用全局中断和实时调试

    //--主循环
    while (1)//无限循环-等待中断

    asm (" NOP");

    第二步:然后我在 ISR 中创建了一个调用函数、以将结果从 ISR 复制到 SCI、如下所示:  

    中断空 ADCC1_ISR (空)// PIE1.3 @ 0x000D44 ADC-C 中断#1

    静态 uint16 * AdcBufPtr2 = AdcBuf2;//指向缓冲区的指针
    int z;
    uint16 Vin;

    PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;//必须确认 PIE 组

    //--管理 ADC 寄存器
    AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 ADCINT1标志

    //---读取 ADC 结果
    *AdcBufPtr2++= AdccResultRegs.ADCRESULT0;//读取结果

    对于(z=0;z<50;z++){
    Vin = AdcBuf2[z];

    SEND_RESULT (Vin);

    //--蛮力强制循环缓冲器
    if (AdcBufPtr2 ==(AdcBuf2 + ADC_BUF_LEN))

    AdcBufPtr2 = AdcBuf2;//将指针回卷到开头

     第三:在 SCI 文件中、我添加了以下命令来传输 ADC 结果:  

    void send_result (uint16分辨率)

    char *msg;
    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 ="V、";
    scia_msg (msg);
    返回;

    因此、当我运行项目时 、超级终端开始接收 ADC 转换结果。 但是、正如我之前提到的、ADC 转换会变得不正确。 如何解决此问题?  
    例如、我需要提高波特率、还是有其他方法?  

    此外,感谢在另一篇文章上重放。 为了向您介绍最新信息、我在另一篇文章中对其他程序进行了上述更改、并在终端上接收到 ADC 转换、但仍然存在损坏 ADC 精度的相同问题。 我想"adc_soc_ePWM_cpu01.c"示例的原始采样速度为12kHz、SCI 波特率为9600。

    此致  

    Hayder  

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

    我想您需要比采样率快~20倍的波特率、因为每个波特仅对一位数据进行编码、每个采样具有12至16位数据(此外、您还需要时隙来进行组帧)。 或者、您只能每隔20次左右扫描一次。

    不清楚消息是如何损坏的。 您是否验证了代码是否为数字 ADC 结果值生成了正确的 ASCII 编码?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Devin、

    当我调用通过 SCI 传输的 adcBuf 结果时、我对 ADC_ISR 进行了简单更改。 这种变化会导致正确的 A/D 转换和传输。 但是。 传输中存在一点延迟、这对我目前没有太大影响。 请参阅以下代码更改:



    中断空 ADCC1_ISR (空)// PIE1.3 @ 0x000D44 ADC-C 中断#1


    静态 uint16 * AdcBufPtr2 = AdcBuf2;//指向缓冲区的指针

    int z;
    uint16 Vin;


    PieCtrlRegs.PIEACX.ALL = PIEACK_Group1;//必须确认 PIE 组

    //--管理 ADC 寄存器
    AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//清除 ADCINT1标志

    //---读取 ADC 结果
    *AdcBufPtr2++= AdccResultRegs.ADCRESULT0;//读取结果

    if (AdcBufPtr2 =(AdcBuf2 + ADC_BUF_LEN)){
    对于(z=0;z <ADC_BUF_LEN;z++){
    Vin = AdcBuf2[z];
    SEND_RESULT (Vin);



    //--蛮力强制循环缓冲器
    if (AdcBufPtr2 ==(AdcBuf2 + ADC_BUF_LEN))

    AdcBufPtr2 = AdcBuf2;//将指针回卷到开头



    为了解决延迟问题、我将波特率更改为1Mbaud、建议采样率至少为 x16或 x20、采样率为50kHz、因此我将波特率寄存器更改为(SciaRegs.SCIHBAUD.all = 0x0000; SciaRegs.SCILBAUD.ALL = 0x0005;)根据 BRR 公式、其中 my LSPCLK = 50MHz。 由于这些更改、当我运行项目实验7时、传输速度会增加、但我开始接收奇怪的符号、而不是 AdcBuf 内容、并且转换精度也会受到影响。

    更新了"adc_soc_ePWM_cpu01.c"项目在我的另一篇文章 e2e.ti.com/.../680506中、我进行了相同的更改、它开始以9600波特率正确传输和转换。

    最后、我必须返回到9600波特率、此时该速率起作用。

    此致

    Hayder

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

    很高兴您能让它正常工作。

    我认为可以实现~1M 波特率、但比典型使用的波特率高得多。 如果您想将符号速率推得非常高、则必须确保 MCU 和接收器具有非常好的时钟精度。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Devin、

    感谢您提供的所有支持。

    我现在遇到另一个问题、当我调试并运行项目时、它可以正常工作、并且我在 Hyperterminal 上接收 adcBuf2阵列。 但是、当我暂停并再次运行该项目时、我开始接收如下图所示的符号:

    我不明白为什么会发生这种情况、在我发送 adcBuf2时、我没有遇到这个问题。 我认为我在工作后没有改变任何东西。

    要解决此问题、我需要检查什么?  

    很好的地方

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

    您只是停止程序、还是正常地完成发送正在进行的任何消息、然后代码停止?

    您可以尝试在程序中创建一个'volatil'变量、您可以通过表达式窗口写入该变量。 当代码看到此设置时、它将停止创建新消息、并在所有当前消息完成后点击 SW 断点(asm (" ESTOP0");)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Devin、  

    感谢您的回复。

    我实际上只是停止程序、然后我重新运行它、这会发生。  

    关于易失性变量、我不熟悉它、但我将读取以执行它。  


    此致

    Hayder

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

    好的、看看平稳停止程序是否有帮助。 如果没有、我们可以继续进一步调试。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Hayder、

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

    您好 Devin、  

    在停止后重新运行程序时,我没有解决最后一个问题,我在终端上收到了一个错误的字符,而不是 AdcResult。

    此致

    Hayder

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

    好的。 您是否尝试更好地停止程序、或者该实验是否仍在等待进行?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Devin、

    我不知道如何缓慢地停止程序、因为我不知道程序编程的确切含义。 您能向我解释一下什么是正常停止吗?

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

    基本上、您需要确保在停止程序之前所有内容都处于空闲状态且传输已完成。

    不要只点击"halt"、这可能导致程序在传输过程中停止、而是让程序查找设置为1的变量(可能称为"sttop_program"等变量)。 您可以在"Expressions"窗口中设置此变量。 变量应为"volatile"、因为代码不会更改值。 当程序检测到该变量已设置时、它会一直等到所有当前消息都被接收和处理、并且对这些传入消息的任何响应都已完成并正确终止。 一旦所有内容都空闲、那么只有这样程序才会停止。

    考虑一下从 PC 拔下电源线或告知您要关闭的窗口之间的区别。

    查看我之前的帖子:

    "您只是停止程序、还是正常地完成发送正在进行的任何消息、然后代码停止?

    您可以尝试在程序中创建一个'volatil'变量、您可以通过表达式窗口写入该变量。 当代码看到此设置时、它将停止创建新消息、并在所有当前消息完成后点击 SW 断点(asm (" ESTOP0");)。"
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Devin、

    感谢您的解释、我将停止该程序、它肯定位于发送消息的中间。 我仍然是编程的初学者、我会按照您的建议尝试平稳地阻止它、但我需要一段时间才能知道如何实现它。 如果你能引导我看任何这样做的示例或任何帖子都是一个起点。

    此致
    Hayder