找回密码
 立即注册
查看: 933|回复: 8

can通信问题

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2024-11-16 09:51:54

1

主题

3

回帖

127

积分

注册会员

积分
127
发表于 2024-8-5 16:19:18 | 显示全部楼层 |阅读模式
本人使用的是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[i]);  //CAN总线原样返回
                printf("CAN1 ID=0x%08lX DLC=%d FF=%d RTR=%d ",CAN1_Rx[i].ID,CAN1_Rx[i].DLC,CAN1_Rx[i].FF,CAN1_Rx[i].RTR);   //串口打印帧信息
                for(j=0;j<CAN1_Rx[i].DLC;j++)

                {
                    printf("0x%02X ",CAN1_Rx[i].DataBuffer[j]);    //从串口输出收到的数据
                }
                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();

        }
}

QQ截图20240805161745.png
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2024-8-5 18:40:53 | 显示全部楼层
建议先直接使用例程包里面的CAN总线收发例子测试,最多修改一下脚位通道,收发功能测试正常后再进行修改或者移植。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2024-11-16 09:51:54

1

主题

3

回帖

127

积分

注册会员

积分
127
发表于 2024-8-5 19:08:19 | 显示全部楼层
乘风*** 发表于 2024-8-5 18:40
建议先直接使用例程包里面的CAN总线收发例子测试,最多修改一下脚位通道,收发功能测试正常后再进行修改或 ...

乘风大佬,两块芯片集成在一个开发板上面,不太好做测试,而且手头上没有现成的STC开发板,准备使用pcan-view这个PC端软件来测试STC程序是否正确然后在进行后续的问题排查
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2024-11-16 09:51:54

1

主题

3

回帖

127

积分

注册会员

积分
127
发表于 2024-8-6 14:50:42 | 显示全部楼层
乘风*** 发表于 2024-8-5 18:40
建议先直接使用例程包里面的CAN总线收发例子测试,最多修改一下脚位通道,收发功能测试正常后再进行修改或 ...

乘风大佬,今天参考了官方的can通信例程,can通信选择can1模块,串口选择串口2打印,但是烧入程序后仍然无法实现通信,后来用示波器测量can1_Tx引脚,发现始终都保持高电平但是我的程序里面引脚初始化已经写了CAN1_SW(CAN1_P00_P01),也进行了相应的初始化(初始化代码就是官方例程的代码,没有改动),请问出现这样的现象可能是什么原因?
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:415
  • 最近打卡:2025-04-30 09:58:34
已绑定手机

39

主题

2006

回帖

6841

积分

论坛元老

积分
6841
发表于 2024-8-6 15:56:23 | 显示全部楼层
Charl*** 发表于 2024-8-6 14:50
乘风大佬,今天参考了官方的can通信例程,can通信选择can1模块,串口选择串口2打印,但是烧入程序后仍然 ...

P00,P01的IO口模式需要设置。
此外进行CAN总线通信需要至少2个节点。
CAN_TX,CAN_RX通过收发器跟另外一个节点连接,才能正常进行通信测试。
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:4
  • 最近打卡:2024-11-16 09:51:54

1

主题

3

回帖

127

积分

注册会员

积分
127
发表于 2024-8-7 17:09:14 | 显示全部楼层
乘风*** 发表于 2024-8-6 15:56
P00,P01的IO口模式需要设置。
此外进行CAN总线通信需要至少2个节点。
CAN_TX,CAN_RX通过收发器跟另外一 ...

乘风大佬,可以正常can通信了,问题出在can收发器上了,换了个新的can收发器就能正常收到stm32发来的数据了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:320
  • 最近打卡:2025-04-30 11:29:16
已绑定手机

21

主题

487

回帖

1023

积分

金牌会员

积分
1023
发表于 2024-8-22 16:05:24 | 显示全部楼层
通信电缆上要并联一个120欧的电阻,不要忘记了
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-03-26 10:21:37
已绑定手机

6

主题

9

回帖

86

积分

注册会员

积分
86
发表于 2025-1-6 15:38:22 | 显示全部楼层
请问楼主可不可以给我一份stc32g864的can通信代码
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:21
  • 最近打卡:2025-05-01 08:32:21

8

主题

50

回帖

337

积分

中级会员

积分
337
发表于 6 小时前 | 显示全部楼层
Charl*** 发表于 2024-8-7 17:09
乘风大佬,可以正常can通信了,问题出在can收发器上了,换了个新的can收发器就能正常收到stm32发来的数据 ...

你好,仅仅是CAN收发器的问题吗?你用的是什么型号?
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-1 15:53 , Processed in 0.140276 second(s), 113 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表