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硬件跳线板
按照惯例先上电下载例程看效果,选择如下:
此测试通过SCI-A端口接收和返回数据。串口设置为: 波特率:9600 数据位:8 校验:无 停止位:1 程序将打印出问候语,然后要求您输入一个字符,它将返回到终端。 外部接线: GPIO28是 SCI_A-RXD 需要连接PC-TX; GPIO29是 SCI_A-TXD 需要连接PC-RX。
芯片串口的引脚在跳线后没有连接,如下图所示:
踩坑2:发送字符丢失
// // 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. // EIN;
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++;
}
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 以上是整个学习过程中遇到的问题,做一个总结回顾,希望能够帮到和我一样刚入门的小伙伴,也是自己学习过程的一个见证。有错误的地方还请多多指教。