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.

[参考译文] MSP-EXP430FR2433:来自 driverlib 的 UART 和 SPI 示例不能协同工作

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1067504/msp-exp430fr2433-uart-and-spi-examples-from-driverlib-don-t-work-together

部件号:MSP-EXP430FR2433
《线程:MSP430WARE》中讨论的其他部件

问题:我想在 UCA0上使用 UART,在 UCA1上使用 SPI。 已加入 driverlib 库中的示例。 SPI 初始化后,UART 开始工作不正常。

代码:

#include "driverlib.h"
#include "Board.h"
#include "stdio.h"

#define STR_LEN 100

char str[STR_LEN];
uint8_t RXData = 0;
uint8_t check = 0;

void initClocks(void);
void initGpio(void);
void initSPI(void);
void sendUartMsg(char* str);
void initUart(void);
uint8_t stringLength(char* str);


void main(void)
{
    //Stop Watchdog Timer
    WDT_A_hold(WDT_A_BASE);

    initClocks();

    initGpio();

    // clocks should be initialized
    // appropriately
    initUart();
    initSPI();


    // Enable global interrupts
    __enable_interrupt();

    while (1)
    {
        sprintf(str, "abcdef\r\n");
        sendUartMsg(str);
        sprintf(str, "a\r\n");
        sendUartMsg(str);
        _delay_cycles(100000);
    }

    return;
}

void initClocks(void) {
    //Set ACLK = REFOCLK with clock divider of 1
    CS_initClockSignal(CS_ACLK,CS_REFOCLK_SELECT,CS_CLOCK_DIVIDER_1);
    //Set SMCLK = DCO with frequency divider of 1
    CS_initClockSignal(CS_SMCLK,CS_DCOCLKDIV_SELECT,CS_CLOCK_DIVIDER_1);
    //Set MCLK = DCO with frequency divider of 1
    CS_initClockSignal(CS_MCLK,CS_DCOCLKDIV_SELECT,CS_CLOCK_DIVIDER_1);
}

void initGpio(void) {
    //Configure UART pins
        GPIO_setAsPeripheralModuleFunctionInputPin(
            GPIO_PORT_UCA0TXD,
            GPIO_PIN_UCA0TXD,
            GPIO_FUNCTION_UCA0TXD
        );
        GPIO_setAsPeripheralModuleFunctionInputPin(
            GPIO_PORT_UCA0RXD,
            GPIO_PIN_UCA0RXD,
            GPIO_FUNCTION_UCA0RXD
        );

        GPIO_setAsPeripheralModuleFunctionInputPin(
                GPIO_PORT_P2,
                GPIO_PIN4 + GPIO_PIN5 + GPIO_PIN6,
                GPIO_PRIMARY_MODULE_FUNCTION
            );

        PMM_unlockLPM5();
}

void initUart(void) {
    //Configure UART
    //SMCLK = 1MHz, Baudrate = 115200
    //UCBRx = 8, UCBRFx = 0, UCBRSx = 0xD6, UCOS16 = 0
    EUSCI_A_UART_initParam param = {0};
    param.selectClockSource = EUSCI_A_UART_CLOCKSOURCE_SMCLK;
    param.clockPrescalar = 8;
    param.firstModReg = 0;
    param.secondModReg = 0xD6;
    param.parity = EUSCI_A_UART_NO_PARITY;
    param.msborLsbFirst = EUSCI_A_UART_LSB_FIRST;
    param.numberofStopBits = EUSCI_A_UART_ONE_STOP_BIT;
    param.uartMode = EUSCI_A_UART_MODE;
    param.overSampling = EUSCI_A_UART_LOW_FREQUENCY_BAUDRATE_GENERATION;

    if (STATUS_FAIL == EUSCI_A_UART_init(EUSCI_A0_BASE, &param)) {
        return;
    }

    EUSCI_A_UART_enable(EUSCI_A0_BASE);

    EUSCI_A_UART_clearInterrupt(EUSCI_A0_BASE,
        EUSCI_A_UART_RECEIVE_INTERRUPT);

    // Enable USCI_A0 RX interrupt
    EUSCI_A_UART_enableInterrupt(EUSCI_A0_BASE,
        EUSCI_A_UART_RECEIVE_INTERRUPT);
}

void sendUartMsg(char* str) {
    uint8_t i;
    uint8_t length = stringLength(str);
    char curChar;

    for (i = 0; i < length; ++i) {

        curChar = str[i];

        //need to print first symbol correctly
        _delay_cycles(10000);

        // Load data onto buffer
        EUSCI_A_UART_transmitData(EUSCI_A0_BASE, curChar);

    }
}

uint8_t stringLength(char* str) {
    uint8_t i = 0;

    while (str[i] != '\0') {
        i++;
    }

    return i;
}

void initSPI(void) {
    //Initialize Master
        EUSCI_A_SPI_initMasterParam param = {0};
        param.selectClockSource = EUSCI_A_SPI_CLOCKSOURCE_SMCLK;
        param.clockSourceFrequency = CS_getSMCLK();
        param.desiredSpiClock = 500000;
        param.msbFirst = EUSCI_A_SPI_MSB_FIRST;
        param.clockPhase = EUSCI_A_SPI_PHASE_DATA_CHANGED_ONFIRST_CAPTURED_ON_NEXT;
        param.clockPolarity = EUSCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW;
        param.spiMode = EUSCI_A_SPI_3PIN;
        EUSCI_A_SPI_initMaster(EUSCI_A1_BASE, &param);

        //Enable SPI module
        EUSCI_A_SPI_enable(EUSCI_A1_BASE);

        //Clear receive interrupt flag
        EUSCI_A_SPI_clearInterrupt(EUSCI_A1_BASE,
              EUSCI_A_SPI_RECEIVE_INTERRUPT
              );

        // Enable USCI_A1 RX interrupt
        EUSCI_A_SPI_enableInterrupt(EUSCI_A1_BASE,
                             EUSCI_A_SPI_RECEIVE_INTERRUPT);
}

CCS 版本: 11.0.0.00012

操作系统:Ubuntu

提前预订泰纳克;)

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

    您是否为 SPI 创建了中断服务例程?

    启用 SPI 后,我们预计它将触发 TX 中断,从而导致无法预测的行为。

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

    我对 MCU 的编码非常熟悉。 定义不行动是否足够? 问题未解决。

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=USCI_A1_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(USCI_A1_VECTOR)))
    #endif
    void USCI_A1_ISR(void)
    {
        switch(__even_in_range(UCA1IV, USCI_SPI_UCTXIFG))
        {
            case USCI_SPI_UCRXIFG:
                __delay_cycles(2);
                break;
            case USCI_SPI_UCTXIFG:
                __delay_cycles(2);
                break;
            default:
                break;
        }
    }

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

     无法对#include "Board.h"的文件进行微调,能否在此处上载该文件?

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

    它来自目录/home/<user>/ti/msp430ware_3_80_14_01/driverlib/examples/MSP430FR2xx_4xx。

    Board.h: https://drive.google.com/file/d/1iVkMAHYh2amcJGm1JpS0sFJkizbONoaP/view?usp=sharing

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

    我可以在 google 驱动器中访问该文件。 您可以直接在此处上传项目吗? 为什么要使用驱动程序库? 我建议使用更易于阅读的注册级别代码。