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.

【28232】【CAN】波特率切换的问题



1. 上电后,CANB以1M波特率,正常发送数据;

2. 在运行过程中,将CANB的波特率由1M切换到800K,可正常发送数据;

3. 由800K切换到1M,无法正常发送数据;

4. 再由1M切换到800K,可正常发送数据;

切换波特率代码如下:

/**
 *@brief:        设置CAN模块波特率
 *@details:
 *@return:
 */
void    CAN_setBaud(volatile struct ECAN_REGS  *pstCan,
                            can_baud_e baud)
{
    struct ECAN_REGS    ECanShadow;

    EALLOW;

    // config begin
    ECanShadow.CANMC.all = pstCan->CANMC.all;
    ECanShadow.CANMC.bit.CCR = 1;  // Set CCR = 1
    pstCan->CANMC.all = ECanShadow.CANMC.all;

    //ECanbShadow.CANES.all = pstCan->CANES.all;
    do
    {
        ECanShadow.CANES.all = pstCan->CANES.all;
    } while(ECanShadow.CANES.bit.CCE != 1 );       // Wait for CCE bit to be  cleared..

    ECanShadow.CANBTC.all = pstCan->CANBTC.all;

    ECanShadow.CANBTC.bit.SAM = 1;

    /* for 100M CPU : CAN时钟为 50MHz
            50MHz / ((brp+1)*((t2+1)+(t1+1)+1)) */
    switch (baud)
    {
        case can_baud_1000K:    // 50MHz / 5*10
            ECanShadow.CANBTC.bit.BRPREG = 4;
            ECanShadow.CANBTC.bit.TSEG2REG = 1;
            ECanShadow.CANBTC.bit.TSEG1REG = 6;
            ECanShadow.CANBTC.bit.SAM = 0;
            break;

        case can_baud_800k:     // 50MHz / 7*9
            ECanShadow.CANBTC.bit.BRPREG = 6;
            ECanShadow.CANBTC.bit.TSEG2REG = 1;
            ECanShadow.CANBTC.bit.TSEG1REG = 5;
            break;

        case can_baud_500K:     // 50MHz / 10*10
            ECanShadow.CANBTC.bit.BRPREG = 9;
            ECanShadow.CANBTC.bit.TSEG2REG = 1;
            ECanShadow.CANBTC.bit.TSEG1REG = 6;
            break;

        case can_baud_250K:     // 50MHz / 20*10
            ECanShadow.CANBTC.bit.BRPREG = 19;
            ECanShadow.CANBTC.bit.TSEG2REG = 1;
            ECanShadow.CANBTC.bit.TSEG1REG = 6;
            break;

        case can_baud_125K:     // 50MHz / 40*10
            ECanShadow.CANBTC.bit.BRPREG = 39;
            ECanShadow.CANBTC.bit.TSEG2REG = 1;
            ECanShadow.CANBTC.bit.TSEG1REG = 6;
            break;

        case can_baud_100K:     // 50MHz / 50*10
            ECanShadow.CANBTC.bit.BRPREG = 49;
            ECanShadow.CANBTC.bit.TSEG2REG = 1;
            ECanShadow.CANBTC.bit.TSEG1REG = 6;
            break;

        case can_baud_50K:     // 50MHz / 50*20
            ECanShadow.CANBTC.bit.BRPREG = 49;
            ECanShadow.CANBTC.bit.TSEG2REG = 3;
            ECanShadow.CANBTC.bit.TSEG1REG = 14;
            break;

        case can_baud_20K:     // 50MHz / 125*20
            ECanShadow.CANBTC.bit.BRPREG = 124;
            ECanShadow.CANBTC.bit.TSEG2REG = 3;
            ECanShadow.CANBTC.bit.TSEG1REG = 14;
            break;

        default:    // can_baud_1000K
            ECanShadow.CANBTC.bit.BRPREG = 4;
            ECanShadow.CANBTC.bit.TSEG2REG = 1;
            ECanShadow.CANBTC.bit.TSEG1REG = 6;
            break;
    }

    pstCan->CANBTC.all = ECanShadow.CANBTC.all;

    // config end
    ECanShadow.CANMC.all = pstCan->CANMC.all;
    ECanShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
    pstCan->CANMC.all = ECanShadow.CANMC.all;

    //ECanbShadow.CANES.all = pstCan->CANES.all;
    do
    {
        ECanShadow.CANES.all = pstCan->CANES.all;
    } while(ECanShadow.CANES.bit.CCE != 0 );       // Wait for CCE bit to be  cleared..

    EDIS;
}