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-EXP430FR5994:DMA 值回绕

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1111499/msp-exp430fr5994-dma-value-wrap-around

器件型号:MSP-EXP430FR5994

您好!

在 DMA_VALUE 中、接收到的字节的顺序仍然存在问题。 当 BQ 芯片请求一个字节时、在开始 DMA 传输前清零 RXIFG 会有所帮助。 现在、我从 BQ 芯片请求了2个字节、找到最后一个 CRC 字节回绕到字节0位置、其余字节位于位置1-7。 如何纠正这种情况? 我添加了在 CCS IDE 中看到的 DMA_VALUE 字节和在逻辑分析器字节中看到的正确响应。

       for(channel=0; channel<(ACTIVECHANNELS*2); channel+=2)
       {
           ReadReg(0x00, cellStartAddr+channel, response_frame, 2, 0, FRMWRT_STK_R);
           while (dmaDataReady == 0);
           boardByteStart = 8*currentBoard;
           rawData = (uint16_t) ((response_frame[boardByteStart+4] << 8) | (response_frame[boardByteStart+5]));
           dmaDataReady = 0;
           rawDataSign = twosComplementToDecimal(rawData);
           cellVoltage[cellvolIndex-1][currentBoard] = cellVoltageScaleFactorMult(rawDataSign);
           cellvolIndex--;
       }
void DMA_Init(){
    __data20_write_long((uintptr_t)&BQUART_DMASA, (uintptr_t)&BQUART_RXBUF);
    __data20_write_long((uintptr_t)&BQUART_DMADA, (uintptr_t) dma_value);

    BQUART_DMACTL &= ~DMAEN;
    DMACTL0 |= BQUART_DMA_RX_TRIGGER;
    DMACTL4 |= DMARMWDIS;

    //Repeated single transfer; increment destination address; source address unchanged;
    //byte to byte transfer source to DMA; byte to byte transfer destination to DMA;
    //rising edge DMA trigger; DMA enable

    BQUART_DMACTL |= DMADT_4|DMADSTINCR_3|DMASRCINCR_0|DMASRCBYTE__WORD|DMADSTBYTE__WORD|DMA_TRIGGER_RISINGEDGE|DMAEN;

}
void uartSend(int length, uint8_t * data){
    uint8_t i;
    uint8_t zeros[(8)*TOTALBOARDS] = {0};

    BQUART_DMASZ = uartRxLen;
    dmaDataReady = 0;
    memcpy(dma_value, zeros, uartRxLen);
    BQUART_IFG &= ~UCRXIFG;

    BQUART_DMACTL |= DMAEN;
    BQUART_DMACTL |= DMAIE;


    for (i = 0; i < length; i++){
        while (!(BQUART_IFG & UCTXIFG));
        BQUART_TXBUF = data[i];
    }


}

void uartReceive(void){
uint8_t i;

    if (startMeasure == 1){
       for (i = 0; i < uartRxLen; i++){
           response_frame[i] = (uint8_t) dma_value[i];
       }
       dmaDataReady = 1;
    }

    if (bqAddr == 1){
        for (i = 0; i < uartRxLen; i++){
           autoaddr_response_frame[i] = (uint8_t) dma_value[i];
        }

        bq79600Addr = autoaddr_response_frame[4];
        bqAddr = 0;
        startMeasure = 1;
    }

}

#pragma vector=DMA_VECTOR
__interrupt void dmaIsrHandler(void)
{
    switch(__even_in_range(DMAIV,  BQUART_DMAIV_IFG))
    {
    case BQUART_DMAIV_IFG:
        BQUART_DMACTL &= ~DMAIE;

        uartReceive();

        // Exit low power mode on wake-up
        __bic_SR_register_on_exit(LPM4_bits);
        break;
    case DMAIV_DMA0IFG:
        break;

    case DMAIV_DMA2IFG:
        break;

    case DMAIV_DMA3IFG:
            break;

    case DMAIV_DMA4IFG:
        break;

    case DMAIV_DMA5IFG:
        break;

    default: break;
    }
}

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

    > BQUART_DMACTL |= DMADDT_4|DMADSTINCR_3|DMASRCINCR_0|DMASRCBYTE_WORD|DMADSTBYTE_WORD|DMADSTBYTE_DMA_TRIGGER_RISINGE|DMAEN;

    我建议您不要在这里设置 DMAEN、因为从现在到现在之间的任何 RXIFG 都会触发它、使您不再按1运行。 您已经在 uartSend 中将 DMAEN 设置为关闭。

    更一般地说:我建议您使用 DMADD_0而不是 DMADD_4、以便在每个事务上重新同步 DMA。

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

    更改为单次传输会有所不同。 尽管在 DMA_Init 期间 DMAEN 似乎是必要的。 谢谢!