TMS320F280049C 串行通信接口Serial Communications Interface (SCI)之RS485通信(多摩川编码器)

TMS320F280049C 串行通信接口Serial Communications Interface (SCI)之RS485通信(多摩川编码器)

之前很少用到通信的模块,但是一涉及通信的就让人头疼不已,好在经历了N久努力之后成功通信。

首先研读280049C的官方手册23章,全部过了一遍之后直接上手TI提供的例程。

例程的位置在C:\ti\c2000\C2000Ware_3_01_00_00\driverlib\f28004x\examples\sci

​ 根据官方手册得知Launch XL板子的仿真器中集成了一个串口,所以不需要其他硬件就可以调试串口,当然还需要一个软件:串口调试助手(TI有官方提供的HELLODSP调试助手,本人在调试过程中选用的SSCOM串口调整工具)
这里建议看一看他的博客https://blog.csdn.时雨晴天

踩坑1:Launch XL板的硬件跳线

​ 按照惯例先要上电下载例程看看效果,选用的是:

示例1. SCI Echoback
此测试通过SCI-A端口接收和回送数据。串口的设置为:
波特率:9600
数据位:8
校验:无
停止位:1
程序将打印出一个问候语,然后要求您输入一个字符,它将回显到终端。
外部接线:
GPIO28是 SCI_A-RXD 需要连接PC-TX;
GPIO29是 SCI_A-TXD 需要连接PC-RX。

一切就绪后串口可以连接并且打开,唯独没有数据发送至串口调试助手,代码是官方例程不会出错,只有硬件的问题,于是乎翻开Launch XL板子的原理图,最终发现是跳线后没有将仿真器与芯片的串口引脚接通,如下图所示:

在这里插入图片描述

踩坑2:发送字符丢失

在示例1成功发送字符后,选用比较贴合实际的示例2 做字符发送测试,按照例程发送看不出来差异,当发送一个字符时,总会丢失,最终在HEX接收下发现例程代码发送字符时,总会丢失两个字符,回头继续研究寄存器情况,最终确定是没有判断移位寄存器导致代码执行较快丢失的。

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

#ifdef _FLASH
// These are defined by the linker (see device linker command file)
extern uint16_t RamfuncsLoadStart;
extern uint16_t RamfuncsLoadSize;
extern uint16_t RamfuncsRunStart;
#endif

//
// Defines
//
// Define AUTOBAUD to use the autobaud lock feature
//#define AUTOBAUD

//
// Globals
//
uint16_t counter = 0;
unsigned char *msg;

//
// Function Prototypes
//
__interrupt void sciaTxISR(void);
__interrupt void sciaRxISR(void);

//
// Main
//
void main(void)
{
    //
    // Configure PLL, disable WD, enable peripheral clocks.
    //
    Device_init();

    //
    // Disable pin locks and enable internal pullups.
    //
    Device_initGPIO();

    //
    // GPIO28 is the SCI Rx pin.
    //
    GPIO_setMasterCore(DEVICE_GPIO_PIN_SCIRXDA, GPIO_CORE_CPU1);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCIRXDA);
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCIRXDA, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCIRXDA, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCIRXDA, GPIO_QUAL_ASYNC);

    //
    // GPIO29 is the SCI Tx pin.
    //
    GPIO_setMasterCore(DEVICE_GPIO_PIN_SCITXDA, GPIO_CORE_CPU1);
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCITXDA);
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCITXDA, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCITXDA, GPIO_PIN_TYPE_STD);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCITXDA, GPIO_QUAL_ASYNC);

    //
    // Disable global interrupts.
    //
    DINT;

    //
    // Initialize interrupt controller and vector table.
    //
    Interrupt_initModule();
    Interrupt_initVectorTable();
    IER = 0x0000;
    IFR = 0x0000;

    //
    // Map the ISR to the wake interrupt.
    //
    Interrupt_register(INT_SCIA_TX, sciaTxISR);
    Interrupt_register(INT_SCIA_RX, sciaRxISR);

    //
    // Initialize SCIA and its FIFO.
    //
    SCI_performSoftwareReset(SCIA_BASE);

    //
    // Configure SCIA for echoback.
    //
    SCI_setConfig(SCIA_BASE, 25000000, 9600, (SCI_CONFIG_WLEN_8 |
                                             SCI_CONFIG_STOP_ONE |
                                             SCI_CONFIG_PAR_NONE));
    SCI_resetChannels(SCIA_BASE);
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXRDY | SCI_INT_RXRDY_BRKDT);
    SCI_enableModule(SCIA_BASE);
    SCI_performSoftwareReset(SCIA_BASE);

    //
    // Enable the TXRDY and RXRDY interrupts.
    //
    SCI_enableInterrupt(SCIA_BASE, SCI_INT_TXRDY | SCI_INT_RXRDY_BRKDT);

#ifdef AUTOBAUD
    //
    // Perform an autobaud lock.
    // SCI expects an 'a' or 'A' to lock the baud rate.
    //
    SCI_lockAutobaud(SCIA_BASE);
#endif

    //
    // Send starting message.
    //
    msg = "\r\n\n\nHello World!\0";
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)msg, 17);
    msg = "\r\nYou will enter a character, and the DSP will echo it back!\n\0";
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)msg, 62);

    //
    // Clear the SCI interrupts before enabling them.
    //
    SCI_clearInterruptStatus(SCIA_BASE, SCI_INT_TXRDY | SCI_INT_RXRDY_BRKDT);

    //
    // Enable the interrupts in the PIE: Group 9 interrupts 1 & 2.
    //
    Interrupt_enable(INT_SCIA_RX);
    Interrupt_enable(INT_SCIA_TX);
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

    //
    // Enable global interrupts.
    //
    EINT;

    for(;;)
    {
    }
}

//
// sciaTxISR - Disable the TXRDY interrupt and print message asking
//             for a character.
//
__interrupt void
sciaTxISR(void)
{
    //
    // Disable the TXRDY interrupt.
    //
    SCI_disableInterrupt(SCIA_BASE, SCI_INT_TXRDY);

    msg = "\r\nEnter a character: \0";
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)msg, 22);

    //
    // Ackowledge the PIE interrupt.
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
}

//
// sciaRxISR - Read the character from the RXBUF and echo it back.
//
__interrupt void
sciaRxISR(void)
{
    uint16_t receivedChar;

    //
    // Enable the TXRDY interrupt again.
    //
    SCI_enableInterrupt(SCIA_BASE, SCI_INT_TXRDY);

    //
    // Read a character from the RXBUF.
    //
    receivedChar = SCI_readCharBlockingNonFIFO(SCIA_BASE);

    //
    // Echo back the character.
    //
    msg = "  You sent: \0";
    SCI_writeCharArray(SCIA_BASE, (uint16_t*)msg, 13);
    SCI_writeCharBlockingNonFIFO(SCIA_BASE, receivedChar);

    //
    // Acknowledge the PIE interrupt.
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);

    counter++;
}

看看接收结果:

在这里插入图片描述

尝试发送3个字符的程序片段如下:
在经过不断折腾与翻阅库文件后,通过while(SCI_isTransmitterBusy(SCIB_BASE));函数判断SCI端口是否空闲,亦为是否发送完毕,达到目的:

在这里插入图片描述

至此,通信的发送与接收调试完毕,这里建议大家使用FIFO发送与接收的形式去做,不会有丢失字符的情况。其优势可以参考如下文章:

https://blog.csdn.net/antidote_/article/details/119805562

与多摩川编码器通信的过程中用到了各种各样的问题,刚开始阅读完多摩川协议手册后参考了以下文章:
https://github.com/imuncle/imuncle.github.io/issues/32

文章中遇到的问题在这里就不提了,下面是我遇到的问题:

踩坑3:主频频率和波特率计算错误

Launch XL板的主频时100MHz,该主频下的最高波特率时1.56M,然多摩川编码器支持的通信是2.5M,只能通过计算重新确定主频。计算的方式参考如下:
https://www.ti2k.com/92.html
以上是整个学习过程中遇到的问题,做一个总结回顾,希望能够帮到和我一样刚入门的小伙伴,也是自己学习过程的一个见证。有错误的地方还请多多指教。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值