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,问题依然没有解决。