SJA1000+XC7Z030,SJA1000初始化及PS数据读取

本人某高校研究生,刚刚研一,接触了一些小项目,想单纯记录一下项目进度以及成果。水平不足,仅供参考,希望能够对大家有所帮助。

板卡介绍:板卡上共4片SJA1000-T芯片,具体芯片功能不进行赘述了,布线方面,四片SJA1000的AD0~AD7拉成了一套数据地址总线,RD#、WR#、RST均是总线形式,ALE、INT#、CS#则是每片使用。

以下是SJA1000的具体原理图,采用了两片晶振分别为16MHZ和12MHZ,通过拨码开关进行选择。

接下来进行SJA1000初始化的具体操作:

Vivado部分:

首先,在Vivado中加入system.bd以及AXI GPIO IP核,此程序选择dual channel 模式:

Auto Connect以后生成以下design。其中GPIO_0是所有的控制引脚,GPIO2_0则为AD0~AD7(需要注意的是,这里的信号反向全部使用IO,在SDK中我们可以通过XGpio_SetDirection函数进行输入输出方向的设置,其内部原理就是控制IOBUF中的IO_t引脚高低电平)

之后Create HDL——Genrate Output——xdc管脚约束——generate bitstream——export hardware——launch sdk

SDK部分:

1.首先我们要根据Datasheet中给出的寄存器偏移地址写出SJA1000.h文件方便之后寄存器调用

#ifndef  __SJA1000_H__
#define  __SJA1000_H__
#include  "string.h"


#define  SJA_BaseAdr  0X00


#define         REG_CONTROL       SJA_BaseAdr+0x00       //内部控制寄存器
#define         REG_COMMAND       SJA_BaseAdr+0x01       //命令寄存器      只写
#define         REG_STATUS        SJA_BaseAdr+0x02       //状态寄存器      只读
#define         REG_INTERRUPT     SJA_BaseAdr+0x03       //中断寄存器      只读
#define         REG_INTENABLE     SJA_BaseAdr+0x04       //中断使能寄存器   可读可写
#define         REG_RESVER0       SJA_BaseAdr+0x05       //保留0
#define         REG_BTR0          SJA_BaseAdr+0x06       //总线定时寄存器0  复位模式读写
                                                         //定义了波特率预设值BRP 和同步跳转宽度SJW 的值
#define         REG_BTR1          SJA_BaseAdr+0x07       //总线定时寄存器1  复位模式读写
//总线定时寄存器1 定义了每个位周期的长度采样点的位置和在每个采样点的采样数目
#define         REG_OCR           SJA_BaseAdr+0x08       //输出控制寄存器  复位模式读写
//输出控制寄存器实现了由软件控制不同输出驱动配置的建立
#define         REG_TEST          SJA_BaseAdr+0x09       //测试寄存器
#define         REG_RESVER1       SJA_BaseAdr+0x0A       //保留1
#define         REG_ARBITRATE     SJA_BaseAdr+0x0B       //仲裁丢失捕捉    只读
#define         REG_ERRCATCH      SJA_BaseAdr+0x0C       //错误代码捕捉    只读
#define         REG_ERRLIMIT      SJA_BaseAdr+0x0D       //错误报警限额    工作模式只读 复位模式可读写


#define         REG_RXERR         SJA_BaseAdr+0x0E         //接收错误计数器工作模式只读 复位模式可读写
#define         REG_TXERR         SJA_BaseAdr+0x0F         //发送错误计数器工作模式只读 复位模式可读写


#define         REG_ACR0          SJA_BaseAdr+0x10       //验收代码寄存器
#define         REG_ACR1          SJA_BaseAdr+0x11       //验收代码寄存器
#define         REG_ACR2          SJA_BaseAdr+0x12       //验收代码寄存器
#define         REG_ACR3          SJA_BaseAdr+0x13       //验收代码寄存器
#define         REG_AMR0          SJA_BaseAdr+0x14       //验收屏蔽寄存器
#define         REG_AMR1          SJA_BaseAdr+0x15       //验收屏蔽寄存器
#define         REG_AMR2          SJA_BaseAdr+0x16       //验收屏蔽寄存器
#define         REG_AMR3          SJA_BaseAdr+0x17       //验收屏蔽寄存器


// 发送缓冲区寄存器  (发送缓冲区长13字节,在CAN地址是16-28即0x10-0x1c)
#define         REG_TXBuffer1     SJA_BaseAdr+0x10         //发送缓冲区1
#define         REG_TXBuffer2     SJA_BaseAdr+0x11         //发送缓冲区2
#define         REG_TXBuffer3     SJA_BaseAdr+0x12         //发送缓冲区3
#define         REG_TXBuffer4     SJA_BaseAdr+0x13         //发送缓冲区4
#define         REG_TXBuffer5     SJA_BaseAdr+0x14         //发送缓冲区5
#define         REG_TXBuffer6     SJA_BaseAdr+0x15         //发送缓冲区6
#define         REG_TXBuffer7     SJA_BaseAdr+0x16         //发送缓冲区7
#define         REG_TXBuffer8     SJA_BaseAdr+0x17         //发送缓冲区8
#define         REG_TXBuffer9     SJA_BaseAdr+0x18         //发送缓冲区9
#define         REG_TXBuffer10    SJA_BaseAdr+0x19         //发送缓冲区10
#define         REG_TXBuffer11    SJA_BaseAdr+0x1A         //发送缓冲区11
#define         REG_TXBuffer12    SJA_BaseAdr+0x1B         //发送缓冲区12
#define         REG_TXBuffer13    SJA_BaseAdr+0x1C         //发送缓冲区13


// 接收缓冲区寄存器   (接收缓冲区长13字节,在CAN地址是16-28即0x10-0x1c)
#define         REG_RXBuffer1     SJA_BaseAdr+0x10       //接收缓冲区1
#define         REG_RXBuffer2     SJA_BaseAdr+0x11       //接收缓冲区2
#define         REG_RXBuffer3     SJA_BaseAdr+0x12        //接收缓冲区3
#define         REG_RXBuffer4     SJA_BaseAdr+0x13       //接收缓冲区4
#define         REG_RXBuffer5     SJA_BaseAdr+0x14        //接收缓冲区5
#define         REG_RXBuffer6     SJA_BaseAdr+0x15         //接收缓冲区6
#define         REG_RXBuffer7     SJA_BaseAdr+0x16         //接收缓冲区7
#define         REG_RXBuffer8     SJA_BaseAdr+0x17         //接收缓冲区8
#define         REG_RXBuffer9     SJA_BaseAdr+0x18         //接收缓冲区9
#define         REG_RXBuffer10    SJA_BaseAdr+0x19        //接收缓冲区10
#define         REG_RXBuffer11    SJA_BaseAdr+0x1A        //接收缓冲区11
#define         REG_RXBuffer12    SJA_BaseAdr+0x1B        //接收缓冲区12
#define         REG_RXBuffer13    SJA_BaseAdr+0x1C        //接收缓冲区13


#define         REG_RXCOUNT       SJA_BaseAdr+0x1D         //RX报文计数器  只读 RX信息计数器(RMC)反应RXFIFO中可用的信息数目
#define         REG_RBSA          SJA_BaseAdr+0x1E         //RX缓冲器起始地址寄存器(RBSA)可读写 复位模式只写
                                                           //反映了当前可用来存储位于接收缓冲器窗口中的信息的内部RAM地址
#define         REG_CDR           SJA_BaseAdr+0x1F         //时钟分频寄存器
//时钟分频寄存器为微控制器控制CLKOUT 的频率以及屏蔽CLKOUT 引脚而且它还控制着TX1上
//的专用接收中断脉冲接收比较通道和BasicCAN 模式与PeliCAN 模式的选择


/*
功能说明:   CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为16MHZ*/


#define         BTR0_Rate_20k      0x53          //20KBPS的预设值
#define         BTR1_Rate_20k      0x2F          //20KBPS的预设值
#define         BTR0_Rate_40k      0x87          //40KBPS的预设值
#define         BTR1_Rate_40k      0xFF          //40KBPS的预设值
#define         BTR0_Rate_50k      0x47          //50KBPS的预设值
#define         BTR1_Rate_50k      0x2F          //50KBPS的预设值
#define         BTR0_Rate_80k      0x83          //80KBPS的预设值
#define         BTR1_Rate_80k      0xFF          //80KBPS的预设值
#define         BTR0_Rate_100k     0x43          //100KBPS的预设值
#define         BTR1_Rate_100k     0x2f          //100KBPS的预设值
#define         BTR0_Rate_125k     0x03          //125KBPS的预设值
#define         BTR1_Rate_125k     0x1c          //125KBPS的预设值
#define         BTR0_Rate_200k     0x81          //200KBPS的预设值
#define         BTR1_Rate_200k     0xFA          //200KBPS的预设值
#define         BTR0_Rate_250k     0x01          //250KBPS的预设值
#define         BTR1_Rate_250k     0x1c          //250KBPS的预设值
#define         BTR0_Rate_400k     0x43          //400KBPS的预设值
#define         BTR1_Rate_400k     0x11          //400KBPS的预设值
#define         BTR0_Rate_500k     0x81          //500KBPS的预设值
#define         BTR1_Rate_500k     0x23          //500KBPS的预设值
#define         BTR0_Rate_666k     0x41          //666KBPS的预设值
#define         BTR1_Rate_666k     0x12          //666KBPS的预设值
#define         BTR0_Rate_800k     0x41          //800KBPS的预设值
#define         BTR1_Rate_800k     0x11          //800KBPS的预设值
#define         BTR0_Rate_1000k    0x40          //1000KBPS的预设值
#define         BTR1_Rate_1000k    0x23          //1000KBPS的预设值
//BPS
//功能说明:   CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为24MHZ*/
#define         BTR0_Rate_10k      0xEF          //20KBPS的预设值
#define         BTR1_Rate_10k      0xFF          //20KBPS的预设值


#define         ByteRate_10k       10
#define         ByteRate_20k       20
#define         ByteRate_40k       40
#define         ByteRate_50k       50
#define         ByteRate_80k       80
#define         ByteRate_100k      100
#define         ByteRate_125k      125
#define         ByteRate_200k      200
#define         ByteRate_250k      250
#define         ByteRate_400k      400
#define         ByteRate_500k      500
#define         ByteRate_800k      800
#define         ByteRate_1000k     1000


//命令字
#define    TR_CMD     0X01  //CMR.0发送请求位
#define    AT_CMD     0X02  //CMR.1中止发送位
#define    RRB_CMD    0X04  //CMR.2释放接收缓冲器
#define    COS_CMD    0X08  //CMR.3清除数据溢出
#define    SRR_CMD    0X10  //CMR.4自接收模式
#define    GTS_CMD    0X10  //????CMR.5.CMR7保留位


//错误字
#define CAN_INTERFACE_OK      0     //CAN总线接口OK
#define CAN_BUS_OK            0     //CAN总线OK
#define CAN_INTERFACE_ERR     0XFF  //CAN总线接口错误
#define CAN_ENTERSET_ERR      0XFE  //CAN总线初始化错误
#define CAN_QUITSET_ERR       0XFD  //CAN总线退出复位模式错误
#define CAN_INITOBJECT_ERR    0XFC  //CAN总线初始化对象错误
#define CAN_INITBTR_ERR       0XFB  //?
#define CAN_INITOUTCTL_ERR    0XFA  //??
#define CAN_INTCLKDIV_ERR     0XF9  //??
#define CAN_BUS_ERR           0XF8  //CAN总线错误


#define ID28_21    0X0A;
#define ID20_13    0X4A;
#define ID12_5     0X6B;
#define ID4_0      0XE8; //低三位不影响设为0
//定义扩展模式数据帧ID
//Basic CAN模式标准帧格式 :帧信息,TX识别码1-2,TX数据字节1-8
//Pelican模式扩展帧格式   :帧信息,TX识别码1-4,TX数据字节1-8

#endif
 

2.根据时序图进行寄存器读写操作,因为我采用的是Intel模式,这里只给出Intel的时序图。

贴入部分代码,以下SJA1000_WR_Time_1是通过控制CS,ALE,RD,WR根据SJA1000的datasheet给出的时序图进行地址锁存以及数据读写,这将应用在之后的SJA1000初始化时各寄存器的读写。

SJA1000_Read_1则是单纯的寄存器数据读。

(注:这两个程序只是SJA1000中1片的读写,因为各片CS,ALE连接至PL端的引脚不同,所以每个都需要重新编写)

    int SJA1000_WR_Time_1(unsigned int Address,unsigned int Data)
{
/* Set the direction for all signals as inputs except the LED output */
//WRITE
    int s;
    XGpio_SetDataDirection(&Gpio1, CAN_CHANNEL1, 0x8E01);//all output except CAN_INT-input
    XGpio_SetDataDirection(&Gpio2, CAN_CHANNEL2, 0x00);//all output AD0~AD7
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFF);//Test_Reg,ALE-1,WR-1,RD-1,CS-1,INT-1
    XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, Address);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFD);//Test_Reg,ALE-0,WR-1,RD-1,CS-1,INT-1,KEEP-ADDRESS
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FDD);//Test_Reg,ALE-0,WR-1,RD-1,CS-0,INT-1,KEEP-ADDRESS
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FD5);//Test_Reg,ALE-0,WR-0,RD-1,CS-0,ADDRESS-FREE
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FD5);//Test_Reg,SET-DATA,ALE-0,WR-0,RD-1,CS-0
    XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, Data);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FDD);//Test_Reg,SET-DATA,ALE-0,WR-1,RD-1,CS-0
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x99);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFD);//Test_Reg,SET-DATA,ALE-0,WR-1,RD-1,CS-1
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x99);
    Delay_ms(1000);
//READ
    //CHANNEL1:0:CAN1_INT,1:CAN1_ALE,2:CAN_RST,3:CAN_WR,4:CAN_RD,5:CAN1_CS,6:CAN2_CS,7:CAN3_CS,8:CAN4_CS
    //CHANNEL2:0~7:AD0~AD7
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFF);//Test_Reg,ALE-1,WR-1,RD-1,CS-1,SET-ADDRESS
    XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, Address);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFD);//Test_Reg,ALE-0,WR-1,RD-1,CS-1,KEEP-ADDRESS
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FDD);//Test_Reg,ALE-0,WR-1,RD-1,CS-0,KEEP-ADDRESS
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FCD);//Test_Reg,ALE-0,WR-1,RD-0,CS-0,ADDRESS-FREE
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_SetDataDirection(&Gpio2, CAN_CHANNEL2, 0xFF);
    Delay_ms(1000);
    s = XGpio_DiscreteRead(&Gpio2, CAN_CHANNEL2);//Test_Reg,READ_DATA,ALE-0,WR-1,RD-0,CS-0
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FDD);//Test_Reg,ALE-0,WR-1,RD-1,CS-0?
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFD);//Test_Reg,ALE-0,WR-1,RD-1,CS-1
    if(s == Data) return 1;
    else  return 0;
}
///
    int SJA1000_Read_1(unsigned int Address)
{
    int s;
    XGpio_SetDataDirection(&Gpio1, CAN_CHANNEL1, 0x8E01);//all output except CAN_INT-input
    XGpio_SetDataDirection(&Gpio2, CAN_CHANNEL2, 0x00);//all output AD0~AD7
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFF);//Test_Reg,ALE-1,WR-1,RD-1,CS-1,SET-ADDRESS
    XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, Address);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFD);//Test_Reg,ALE-0,WR-1,RD-1,CS-1,KEEP-ADDRESS
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FDD);//Test_Reg,ALE-0,WR-1,RD-1,CS-0,KEEP-ADDRESS
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FCD);//Test_Reg,ALE-0,WR-1,RD-0,CS-0,ADDRESS-FREE
//        XGpio_DiscreteWrite(&Gpio2, CAN_CHANNEL2, 0x09);
    Delay_ms(1000);
    XGpio_SetDataDirection(&Gpio2, CAN_CHANNEL2, 0xFF);
    Delay_ms(1000);
    s = XGpio_DiscreteRead(&Gpio2, CAN_CHANNEL2);//Test_Reg,READ_DATA,ALE-0,WR-1,RD-0,CS-0
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FDD);//Test_Reg,ALE-0,WR-1,RD-1,CS-0?
    Delay_ms(1000);
    XGpio_DiscreteWrite(&Gpio1, CAN_CHANNEL1, 0x0FFD);//Test_Reg,ALE-0,WR-1,RD-1,CS-1
    return s;

}

3.SJA1000的初始化:这里给出的是一片SJA1000的初始化操作(这些是包含在主函数内部的,AXI GPIO的初始化等操作不再赘述了,看SDK内部例程即可),具体各寄存器内部配置请参考SJA1000的datasheet,大致就是要先进行测试寄存器读写判断通道是否正常,时序是否有问题,之后进入复位模式,配置波特率,ACR,AMR,工作模式等,最后退出复位模式。

    while(c==0){
            if(SJA1000_WR_Time_4(REG_TEST,0XAA)==1)//sja_interface_test();
                {
                    printf("Interface is OK!\r\n");
                    a = 1;
                }
                else
                {
                    printf("Interface error!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_CONTROL,0x09)==1 && a==1) //sja_init();
                {
                    printf("Enter RST Mode is OK!\r\n");
                    b = SJA1000_Read_4(REG_CONTROL);//0X09
                }
                else
                {
                    printf("RST Mode fail\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_TEST,0xAA)==1 && a==1)
                {
                    printf("Test PASS!\r\n");
                }
                else
                {
                    printf("Test Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_CDR,0xC8)==1 && a==1)
                {
                    printf("Clock Set is ok!\r\n");
                }
                else
                {
                    printf("Clock Set Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_ACR0,0x0A)==1 && a==1)
                {
                    printf("ACR0 SET 0X0A!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_ACR1,0x4A)==1 && a==1)
                {
                    printf("ACR1 SET 0X4A!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_ACR2,0x6B)==1 && a==1)
                {
                    printf("ACR2 SET 0X6B!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_ACR3,0x78)==1 && a==1)
                {
                    printf("ACR3 SET 0X78!\r\n");

                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_AMR0,0x00)==1 && a==1)
                {
                    printf("AMR0 SET MODE 0X00!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_AMR1,0x00)==1 && a==1)
                {
                    printf("AMR1 SET MODE 0X4A!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_AMR2,0x00)==1 && a==1)
                {
                    printf("AMR2 SET MODE 0X6B!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_AMR3,0x03)==1 && a==1)
                {
                    printf("AMR3 SET MODE 0X78!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_BTR0,BTR0_Rate_1000k)==1 && a==1)
                {
                    printf("BANDRATE1 SET IS OK!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_BTR1,BTR1_Rate_1000k)==1 && a==1)
                {
                    printf("BANDRATE2 SET IS OK!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_INTENABLE,0xFF)==1 && a==1)
                {
                    printf("Interrupt SET IS OK!\r\n");
                }
                else
                {
                    printf("Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_OCR,0x1A)==1 && a==1)
                {
                    printf("OUTPUT MODE SET!\r\n");
                }
                else
                {
                    printf("OUTPUT MODE Fail!\r\n");
                    a = 0;
                }
                if(SJA1000_WR_Time_4(REG_CONTROL,0x08) == 1 && a==1)//?
                {
                    printf("RST MODE IS QUIT!\r\n");
                }
                else
                {
                    printf("RST MODE QUIT Fail!\r\n");
                    a = 0;
                }
                if(a==1)
                {
                    printf("SJA1000_4 Init is OK\r\n");
                    c = 1;
                }
    }

4.通过中断信号进行数据读取:

这里只是简单的数据读取,当SJA1000内部RXBuffer接收到数据时,会产生INT引脚拉低的情况,我的初步思考是通过读取引脚电平,进行相应的数据读取。

之前也考虑过中断触发的方式,但看了例程和网上PL-PS点灯的程序后,感觉也是进行中断使能读取的操作,不知道有没有大佬给讲讲为什么要采用中断方式,我这种直接读取电平方式会有什么问题。

    while(b)
    {//4093 2045 1111 1111 1101   0111 1111 1101
        Which_SJA1000 = XGpio_DiscreteRead(&Gpio1, CAN_CHANNEL1);
            if((Which_SJA1000 & 0x0800) == 0)
            {
                data1 = SJA1000_Read_4(REG_RXBuffer1);
            }
            else if((Which_SJA1000 & 0x0400) == 0)
            {
                data2 = SJA1000_Read_3(REG_RXBuffer1);
            }
            else if((Which_SJA1000 & 0x0200) == 0)
            {
                data3 = SJA1000_Read_2(REG_RXBuffer1);
            }
            else if((Which_SJA1000 & 0x0001) == 0)
            {
                data4 = SJA1000_Read_1(REG_RXBuffer1);
            }


    }
}

以上就是SJA1000的调试过程,历经两个星期调到了现在这个程度,感觉自己还是有点云里雾里的,有一个重点就是在起初的管脚约束时,引脚一定要分配正确!!!我就是因为xdc问题,导致开始无法正确读写寄存器数据,搞了很久最后发现是XDC的问题。大家引以为戒,如果有任何建议和问题,请告诉我,我们共同进步。

  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值