can通信问题
本人使用的是STC32G8K64型号的芯片和STM32F303进行can通信,STM32F303作为数据发动段,STC32G8K64作为读取和处理数据端。can波特率为500kHz,接收端的程序是仿照着官方例程来写的。但是在通信过程中无法接收到数据。通过调试发现接收端程序无法进入到if(B_Can1Read){}判断里面,我尝试着用串口打印CAN状态寄存器(SR)的值,发现会返回0x22和0x2A两个值,通过查看STC32G8的芯片手册发现CAN状态寄存器(SR)中的B1位始终为1,即ES:CAN模块错误状态位始终为1。但是对于芯片手册中关于这一位的描述有点摸不着头脑:该位为1时表示"CAN模块至少有一个错误寄存器的值达到或超过了96",但是在芯片手册中找了一段时间发现没有对can的错误寄存器进行叙述。现求教论坛内的大佬,知道这是什么原因吗?代码需要修改哪里才能成功实现两块芯片之间的can通信?
//相关宏定义
#define TSG1 2 //0~15
#define TSG2 1 //1~7 (TSG2 不能设置为0)
#define BRP 3 //0~63
#define SJW 0 //重新同步跳跃宽度
#define SAM 0 //总线电平采样次数: 0:采样1次; 1:采样3次
//can波特率设置函数
void CANSetBaudrate()
{
CanWriteReg(BTR0,(SJW << 6) + BRP);
CanWriteReg(BTR1,(SAM << 7) + (TSG2 << 4) + TSG1);
}
void app_can_init(void)
{
CANEN = 1; //CAN1模块使能
CANSEL = 0; //选择CAN1模块
P_SW1 = (P_SW1 & ~(3<<4)) | (0<<4);
CanWriteReg(MR,0x04);//使能 Reset Mode
CANSetBaudrate(); //设置波特率
//不进行滤波,接收所有报文
CanWriteReg(ACR0,0x00); //总线验收代码寄存器
CanWriteReg(ACR1,0x00);
CanWriteReg(ACR2,0x00);
CanWriteReg(ACR3,0x00);
CanWriteReg(AMR0,0xFF); //总线验收屏蔽寄存器
CanWriteReg(AMR1,0xFF);
CanWriteReg(AMR2,0xFF);
CanWriteReg(AMR3,0xFF);
CanWriteReg(IMR ,0xff); //中断寄存器
CanWriteReg(ISR ,0xff); //清中断标志
CanWriteReg(MR,0x01);//退出 Reset Mode, 采用单滤波设置(设置过滤器后注意选择滤波模式)
CANICR = 0x02;//CAN中断使能
}
//can通信处理函数
void vApp_Can_Process(void)
{
u8 n,i,j;
u8 sr;
if(msecond >= 1000) //1秒到
{
msecond = 0;
sr = CanReadReg(SR);
printf("%#x\r\n", sr);
if(sr & 0x01) //判断是否有 BS:BUS-OFF状态
{
CANAR = MR;
CANDR &= ~0x04;//清除 Reset Mode, 从BUS-OFF状态退出
}
}
if(B_Can1Read)//判断 CAN1 是否接收到数据
{
B_Can1Read = 0;
//CANSEL = CAN1; //选择CAN1模块
n = CanReadMsg(CAN1_Rx); //读取接收内容
if(n>0)
{
for(i=0;i<n;i++)
{
// CanSendMsg(&CAN1_Rx);//CAN总线原样返回
printf("CAN1 ID=0x%08lX DLC=%d FF=%d RTR=%d ",CAN1_Rx.ID,CAN1_Rx.DLC,CAN1_Rx.FF,CAN1_Rx.RTR); //串口打印帧信息
for(j=0;j<CAN1_Rx.DLC;j++)
{
printf("0x%02X ",CAN1_Rx.DataBuffer); //从串口输出收到的数据
}
printf("\r\n");
}
}
}
}
//定时器配置函数
void Timer_config(void)
{
TIM_InitTypeDef TIM_InitStructure; //结构定义
TIM_InitStructure.TIM_Mode = TIM_16BitAutoReload; //指定工作模式, TIM_16BitAutoReload,TIM_16Bit,TIM_8BitAutoReload,TIM_16BitAutoReloadNoMask
TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_1T; //指定时钟源, TIM_CLOCK_1T,TI
TIM_InitStructure.TIM_ClkOut = DISABLE; //是否输出高速脉冲, ENABLE或DISABLE
TIM_InitStructure.TIM_Value = (u16)(65536UL - (MAIN_Fosc / 1000UL)); //中断频率, 1000次/秒
TIM_InitStructure.TIM_PS = 0; //8位预分频器(n+1), 0~255
TIM_InitStructure.TIM_Run = ENABLE; //是否初始化后启动定时器, ENABLE或D
Timer_Inilize(Timer0,&TIM_InitStructure); //初始化Timer0 Timer0,Timer1,Timer2,Timer3,Timer4
NVIC_Timer0_Init(ENABLE,Priority_0); //中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}
//定时器中断函数
void Timer0_ISR_Handler (void) interrupt TMR0_VECTOR //锟斤拷锟叫讹拷时锟窖撅拷锟斤拷锟斤拷锟斤拷?
{
msecond++;
}
//main函数
void main(void)
{
WTST = 0; //设置程序指令延时参数,赋值为0可将CPU执行指令的速度设置为最快
EAXSFR(); //扩展SFR(XFR)访问使能
CKCON = 0; //提高访问XRAM速度
// GPIO_config();
P1_MODE_IO_PU(GPIO_Pin_0 | GPIO_Pin_1);
Timer_config();
UART_config();
app_can_init();
EA = 1;
B_Can1Send = 0;
while (1)
{
vApp_Can_Process();
}
}
建议先直接使用例程包里面的CAN总线收发例子测试,最多修改一下脚位通道,收发功能测试正常后再进行修改或者移植。 乘风飞扬 发表于 2024-8-5 18:40
建议先直接使用例程包里面的CAN总线收发例子测试,最多修改一下脚位通道,收发功能测试正常后再进行修改或 ...
乘风大佬,两块芯片集成在一个开发板上面,不太好做测试,而且手头上没有现成的STC开发板,准备使用pcan-view这个PC端软件来测试STC程序是否正确然后在进行后续的问题排查 乘风飞扬 发表于 2024-8-5 18:40
建议先直接使用例程包里面的CAN总线收发例子测试,最多修改一下脚位通道,收发功能测试正常后再进行修改或 ...
乘风大佬,今天参考了官方的can通信例程,can通信选择can1模块,串口选择串口2打印,但是烧入程序后仍然无法实现通信,后来用示波器测量can1_Tx引脚,发现始终都保持高电平但是我的程序里面引脚初始化已经写了CAN1_SW(CAN1_P00_P01),也进行了相应的初始化(初始化代码就是官方例程的代码,没有改动),请问出现这样的现象可能是什么原因? CharlieJo 发表于 2024-8-6 14:50
乘风大佬,今天参考了官方的can通信例程,can通信选择can1模块,串口选择串口2打印,但是烧入程序后仍然 ...
P00,P01的IO口模式需要设置。
此外进行CAN总线通信需要至少2个节点。
CAN_TX,CAN_RX通过收发器跟另外一个节点连接,才能正常进行通信测试。 乘风飞扬 发表于 2024-8-6 15:56
P00,P01的IO口模式需要设置。
此外进行CAN总线通信需要至少2个节点。
CAN_TX,CAN_RX通过收发器跟另外一 ...
乘风大佬,可以正常can通信了,问题出在can收发器上了,换了个新的can收发器就能正常收到stm32发来的数据了{:4_167:} 通信电缆上要并联一个120欧的电阻,不要忘记了
请问楼主可不可以给我一份stc32g864的can通信代码 CharlieJo 发表于 2024-8-7 17:09
乘风大佬,可以正常can通信了,问题出在can收发器上了,换了个新的can收发器就能正常收到stm32发来的数据 ...
你好,仅仅是CAN收发器的问题吗?你用的是什么型号?
页:
[1]