TI中文支持网
TI专业的中文技术问题搜集分享网站

【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;
}

HG:

请检查自己的采样次数设置?  

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;

… …

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

PS:位序的时间配置应该与收发器的实际延时相匹配。 

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;
}

Chao Huang2:

回复 HG:

谢谢HG:

    因为  只有当比特率预分频值大于 4 时 (BRP>4) 选择三重采样样本模式,而 can_baud_1000K时的 ECanShadow.CANBTC.bit.BRPREG = 4,作为特殊情况进行处理,故将 SAM设置为0.

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;
}

HG:

回复 Chao Huang2:

你仔细看一下你的default,还有其它分支,你的程序会不会导致在不同的分支路径下同样case的sam值却不一样。

希望问题已经解决。

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;
}

Chao Huang2:

回复 HG:

Hi, HG:

确定了,SAM只有在1M时为0,其它情况为1,问题依然没有解决。

赞(0)
未经允许不得转载:TI中文支持网 » 【28232】【CAN】波特率切换的问题
分享到: 更多 (0)