基于GD32F407和RTthread的MCP/SIT2515驱动详解

1.简介

本文主要介绍了基于GD32F407和RT thread的sit2515驱动的程序编写和使用方法。

2.ENV程序编写

使用硬件和软件SPI转CAN扩展了两路CAN接口,在board文件里找到Kconfig文件并打开,在menu "Onboard Peripheral Drivers"内添加如下代码:

 menuconfig BSP_USING_SIT2515
        bool "Enable SIT2515"
        default n
        select RT_USING_SPI
        if BSP_USING_SIT2515
            menuconfig BSP_USING_SIT2515_0
                bool "Using 2515CAN0"
					default n
					if BSP_USING_SIT2515_0
						config SIT2515_0_USING_SOFT_SPI
						bool "2515CAN0 using soft spi"				
						if SIT2515_0_USING_SOFT_SPI
							choice
								prompt "using soft spi"
								config SIT2515_0_USING_SOFT_SPI0
									bool "Using soft sspi0"
									select BSP_USING_SOFT_SPI
									select BSP_USING_SOFT_SPI0
								config SIT2515_0_USING_SOFT_SPI1
									bool "Using soft sspi1"
									select BSP_USING_SOFT_SPI
									select BSP_USING_SOFT_SPI1
								config SIT2515_0_USING_SOFT_SPI2
									bool "Using soft sspi2"
									select BSP_USING_SOFT_SPI
									select BSP_USING_SOFT_SPI2
								config SIT2515_0_USING_SOFT_SPI3
									bool "Using soft sspi3"
									select BSP_USING_SOFT_SPI
									select BSP_USING_SOFT_SPI3
							endchoice
							config SIT2515_SPI_BUS_NAME0
							string "SIT2515_0 bus name"
							default "sspi0"
						endif
						
						config SIT2515_0_USING_HARD_SPI
						bool "2515CAN0 using hard spi"				
						if SIT2515_0_USING_HARD_SPI
							choice
								prompt "using hard spi"
								config SIT2515_0_USING_SPI0
									bool "Using hard spi0"
									select BSP_USING_SPI
									select BSP_USING_SPI0
								config SIT2515_0_USING_SPI1
									bool "Using hard spi1"
									select BSP_USING_SPI
									select BSP_USING_SPI1
								config SIT2515_0_USING_SPI2
									bool "Using hard spi2"
									select BSP_USING_SPI
									select BSP_USING_SPI2
							endchoice
							config SIT2515_SPI_BUS_NAME0
							string "SIT2515_0 bus name"
							default "spi0"
						endif
						config SIT2515_DEVICE_NAME0
							string "SIT2515_0 device name"
							default "2515can0"
						config SIT2515_INT_PIN_NUM0
							int "SIT2515_0 int pin number"
							range 1 216
							default 40
					endif
            menuconfig BSP_USING_SIT2515_1
                bool "Using 2515CAN1"
                default n
					if BSP_USING_SIT2515_1
						config SIT2515_1_USING_SOFT_SPI
						bool "2515CAN1 using soft spi"				
						if SIT2515_1_USING_SOFT_SPI
							choice
								prompt "using soft spi"
								config SIT2515_1_USING_SOFT_SPI0
									bool "Using soft sspi0"
									select BSP_USING_SOFT_SPI
									select BSP_USING_SOFT_SPI0
								config SIT2515_1_USING_SOFT_SPI1
									bool "Using soft sspi1"
									select BSP_USING_SOFT_SPI
									select BSP_USING_SOFT_SPI1
								config SIT2515_1_USING_SOFT_SPI2
									bool "Using soft sspi2"
									select BSP_USING_SOFT_SPI
									select BSP_USING_SOFT_SPI2
								config SIT2515_1_USING_SOFT_SPI3
									bool "Using soft sspi3"
									select BSP_USING_SOFT_SPI
									select BSP_USING_SOFT_SPI3
							endchoice
							config SIT2515_SPI_BUS_NAME1
							string "SIT2515_1 bus name"
							default "sspi1"
						endif
						
						config SIT2515_1_USING_HARD_SPI
						bool "2515CAN0 using hard spi"				
						if SIT2515_1_USING_HARD_SPI
							choice
								prompt "using hard spi"
								config SIT2515_1_USING_SPI0
									bool "Using hard spi0"
									select BSP_USING_SPI
									select BSP_USING_SPI0
								config SIT2515_1_USING_SPI1
									bool "Using hard spi1"
									select BSP_USING_SPI
									select BSP_USING_SPI1
								config SIT2515_1_USING_SPI2
									bool "Using hard spi2"
									select BSP_USING_SPI
									select BSP_USING_SPI2
							endchoice
							config SIT2515_SPI_BUS_NAME1
							string "SIT2515_1 bus name"
							default "spi1"
						endif
						config SIT2515_DEVICE_NAME1
							string "SIT2515_1 device name"
							default "2515can1"
						config SIT2515_INT_PIN_NUM1
							int "SIT2515_1 int pin number"
							range 1 216
							default 55
					endif
        endif

3.ENV配置

1打开ENV

2使能SIT2515

3选择要配置的SIT2515

4下面配置的是硬件SPI扩展CAN,设置SPI接口,驱动设备名称,中断引脚

5下面配置的是模拟SPI扩展CAN,设置SPI接口,驱动设备名称,中断引脚

6配置完成后rtconfig.h中就自动定义了, 如下所示。

#define BSP_USING_SIT2515

#define BSP_USING_SIT2515_0

#define SIT2515_SPI_BUS_NAME0 "spi1"

#define SIT2515_0_USING_HARD_SPI

#define SIT2515_0_USING_SPI1

#define SIT2515_DEVICE_NAME0 "2515can0"

#define SIT2515_INT_PIN_NUM0 26

#define BSP_USING_SIT2515_1

#define SIT2515_1_USING_SOFT_SPI

#define SIT2515_1_USING_SOFT_SPI2

#define SIT2515_SPI_BUS_NAME1 "sspi2"

#define SIT2515_DEVICE_NAME1 "2515can1"

#define SIT2515_INT_PIN_NUM1 79

 4.SIT2515驱动的头文件drv_sit2515.h

#ifndef __DRV_SIT2515_H__
#define __DRV_SIT2515_H__
#include <rtdevice.h>

/**/
#ifdef BSP_USING_SIT2515_0
extern struct CAN_control Can2_control;
#endif
#ifdef BSP_USING_SIT2515_1
extern struct CAN_control Can3_control;
#endif

/*SIT2515CAN0*/
#ifdef BSP_USING_SIT2515_0
//#define SIT2515_DEVICE_NAME0     "2515can0" /*驱动设备名称*/
/*********软件模拟SPI********/
//#define SIT2515_SSPI_BUS_NAME0       "sspi0"  /* 传感器连接的SPI总线设备名称 */
//#define SPI_DEVICE_NAME0             "sspi00"
/*********硬件SPI********/
//#define SIT2515_SPI_BUS_NAME0       "spi1"  /* 传感器连接的SPI总线设备名称 */
#define SPI_DEVICE_NAME0             "2515_0"
/***********SPI CS引脚定义***********/
#define SIT2515_0_SPI_CS_GPIOX   		GPIOB
#define SIT2515_0_SPI_CS_GPIOX_PIN_X 	GPIO_PIN_12
#define SIT2515_0_SPI_CS_GPIOX_RCU 	    RCU_GPIOB

/* 引脚编号,通过查看设备驱动文件drv_gpio.c确定 */
//#ifndef SIT2515_INT_PIN_NUM0 //中断引脚配置
//    #define SIT2515_INT_PIN_NUM0            40  /* PC8 */
//#endif
#endif



/*SIT2515CAN1*/
#ifdef BSP_USING_SIT2515_1
//#define SIT2515_DEVICE_NAME1     "2515can1" /*驱动设备名称*/

/*********软件模拟SPI********/
//#define SIT2515_SSPI_BUS_NAME1       "sspi1"  /* 传感器连接的SPI总线设备名称 */
#define SPI_DEVICE_NAME1             "2515_1"
/*********硬件SPI********/
//#define SIT2515_SPI_BUS_NAME1       "spi1"  /* 传感器连接的SPI总线设备名称 */
//#define SPI_DEVICE_NAME1             "spi10"
/***********SPI CS引脚定义***********/
#define SIT2515_1_SPI_CS_GPIOX   		GPIOE
#define SIT2515_1_SPI_CS_GPIOX_PIN_X 	GPIO_PIN_11
#define SIT2515_1_SPI_CS_GPIOX_RCU 	    RCU_GPIOE

/* 引脚编号,通过查看设备驱动文件drv_gpio.c确定 */
//#ifndef SIT2515_INT_PIN_NUM1 //中断引脚配置
//    #define SIT2515_INT_PIN_NUM1            55  /* PD7 */
//#endif
#endif

/*环形数据接收缓冲区长度*/
#define RECV_BUF_SIZE 	20


/* Configuration Registers */
#define CANSTAT         0x0E
#define CANCTRL         0x0F
#define BFPCTRL         0x0C
#define TEC             0x1C
#define REC             0x1D
#define CNF3            0x28
#define CNF2            0x29
#define CNF1            0x2A
#define CANINTE         0x2B
#define CANINTF         0x2C
#define EFLG            0x2D
#define TXRTSCTRL       0x0D

/*  Recieve Filters */
#define RXF0SIDH        0x00
#define RXF0SIDL        0x01
#define RXF0EID8        0x02
#define RXF0EID0        0x03
#define RXF1SIDH        0x04
#define RXF1SIDL        0x05
#define RXF1EID8        0x06
#define RXF1EID0        0x07
#define RXF2SIDH        0x08
#define RXF2SIDL        0x09
#define RXF2EID8        0x0A
#define RXF2EID0        0x0B
#define RXF3SIDH        0x10
#define RXF3SIDL        0x11
#define RXF3EID8        0x12
#define RXF3EID0        0x13
#define RXF4SIDH        0x14
#define RXF4SIDL        0x15
#define RXF4EID8        0x16
#define RXF4EID0        0x17
#define RXF5SIDH        0x18
#define RXF5SIDL        0x19
#define RXF5EID8        0x1A
#define RXF5EID0        0x1B

/* Receive Masks */
#define RXM0SIDH        0x20
#define RXM0SIDL        0x21
#define RXM0EID8        0x22
#define RXM0EID0        0x23
#define RXM1SIDH        0x24
#define RXM1SIDL        0x25
#define RXM1EID8        0x26
#define RXM1EID0        0x27

/* Tx Buffer 0 */
#define TXB0CTRL        0x30
#define TXB0SIDH        0x31
#define TXB0SIDL        0x32
#define TXB0EID8        0x33
#define TXB0EID0        0x34
#define TXB0DLC         0x35
#define TXB0D0          0x36
#define TXB0D1          0x37
#define TXB0D2          0x38
#define TXB0D3          0x39
#define TXB0D4          0x3A
#define TXB0D5          0x3B
#define TXB0D6          0x3C
#define TXB0D7          0x3D

/* Tx Buffer 1 */
#define TXB1CTRL        0x40
#define TXB1SIDH        0x41
#define TXB1SIDL        0x42
#define TXB1EID8        0x43
#define TXB1EID0        0x44
#define TXB1DLC         0x45
#define TXB1D0          0x46
#define TXB1D1          0x47
#define TXB1D2          0x48
#define TXB1D3          0x49
#define TXB1D4          0x4A
#define TXB1D5          0x4B
#define TXB1D6          0x4C
#define TXB1D7          0x4D

/* Tx Buffer 2 */
#define TXB2CTRL        0x50
#define TXB2SIDH        0x51
#define TXB2SIDL        0x52
#define TXB2EID8        0x53
#define TXB2EID0        0x54
#define TXB2DLC         0x55
#define TXB2D0          0x56
#define TXB2D1          0x57
#define TXB2D2          0x58
#define TXB2D3          0x59
#define TXB2D4          0x5A
#define TXB2D5          0x5B
#define TXB2D6          0x5C
#define TXB2D7          0x5D

/* Rx Buffer 0 */
#define RXB0CTRL        0x60
#define RXB0SIDH        0x61
#define RXB0SIDL        0x62
#define RXB0EID8        0x63
#define RXB0EID0        0x64
#define RXB0DLC         0x65
#define RXB0D0          0x66
#define RXB0D1          0x67
#define RXB0D2          0x68
#define RXB0D3          0x69
#define RXB0D4          0x6A
#define RXB0D5          0x6B
#define RXB0D6          0x6C
#define RXB0D7          0x6D

/* Rx Buffer 1 */
#define RXB1CTRL        0x70
#define RXB1SIDH        0x71
#define RXB1SIDL        0x72
#define RXB1EID8        0x73
#define RXB1EID0        0x74
#define RXB1DLC         0x75
#define RXB1D0          0x76
#define RXB1D1          0x77
#define RXB1D2          0x78
#define RXB1D3          0x79
#define RXB1D4          0x7A
#define RXB1D5          0x7B
#define RXB1D6          0x7C
#define RXB1D7          0x7D


/*******************************************************************
 *               Bit register masks                                *
 *******************************************************************/

/* TXBnCTRL */
#define TXREQ           0x08
#define TXP             0x03

/* RXBnCTRL */
#define RXM             0x60
#define BUKT            0x04

/* CANCTRL */
#define REQOP           0xE0 
#define ABAT            0x10
#define	OSM             0x08
#define CLKEN           0x04
#define CLKPRE          0x03

/* CANSTAT */
#define REQOP           0xE0
#define ICOD            0x0E

/* CANINTE */
#define RX0IE           0x01
#define RX1IE           0x02
#define TX0IE           0x04
#define TX1IE           0x08
#define TX2IE           0x10
#define ERRIE           0x20
#define WAKIE           0x40
#define MERRE           0x80

/* CANINTF */
#define RX0IF           0x01
#define RX1IF           0x02
#define TX0IF           0x04
#define TX1IF           0x08
#define TX2IF           0x10
#define ERRIF           0x20
#define WAKIF           0x40
#define MERRF           0x80

/* BFPCTRL */
#define B1BFS           0x20
#define B0BFS           0x10
#define B1BFE           0x08
#define B0BFE           0x04
#define B1BFM           0x02
#define B0BFM           0x01

/* CNF1 Masks */
#define SJW             0xC0
#define BRP             0x3F

/* CNF2 Masks */
#define BTLMODE         0x80
#define SAM             0x40
#define PHSEG1          0x38
#define PRSEG           0x07

/* CNF3 Masks */
#define WAKFIL          0x40
#define PHSEG2          0x07

/* TXRTSCTRL Masks */
#define TXB2RTS         0x04
#define TXB1RTS         0x02
#define TXB0RTS         0x01


/*******************************************************************
 *                    Bit Timing Configuration                     *
 *******************************************************************/
 
/* CNF1 */
#define SJW_1TQ         0x40
#define SJW_2TQ         0x80
#define SJW_3TQ         0x90
#define SJW_4TQ         0xC0

/* CNF2 */
#define BTLMODE_CNF3    0x80
#define BTLMODE_PH1_IPT 0x00

#define SMPL_3X         0x40
#define SMPL_1X         0x00

#define PHSEG1_8TQ      0x38
#define PHSEG1_7TQ      0x30
#define PHSEG1_6TQ      0x28
#define PHSEG1_5TQ      0x20
#define PHSEG1_4TQ      0x18
#define PHSEG1_3TQ      0x10
#define PHSEG1_2TQ      0x08
#define PHSEG1_1TQ      0x00

#define PRSEG_8TQ       0x07
#define PRSEG_7TQ       0x06
#define PRSEG_6TQ       0x05
#define PRSEG_5TQ       0x04
#define PRSEG_4TQ       0x03
#define PRSEG_3TQ       0x02
#define PRSEG_2TQ       0x01
#define PRSEG_1TQ       0x00

/* CNF3 */
#define PHSEG2_8TQ      0x07
#define PHSEG2_7TQ      0x06
#define PHSEG2_6TQ      0x05
#define PHSEG2_5TQ      0x04
#define PHSEG2_4TQ      0x03
#define PHSEG2_3TQ      0x02
#define PHSEG2_2TQ      0x01
#define PHSEG2_1TQ      0x00

#define SOF_ENABLED     0x80
#define WAKFIL_ENABLED  0x40  //开启过滤器
#define WAKFIL_DISABLED 0x00  //关闭过滤器


/*******************************************************************
 *                  Control/Configuration Registers                *
 *******************************************************************/

/* CANINTE */
#define RX0IE_ENABLED   0x01
#define RX0IE_DISABLED  0x00
#define RX1IE_ENABLED   0x02
#define RX1IE_DISABLED  0x00
#define G_RXIE_ENABLED  0x03
#define G_RXIE_DISABLED 0x00

#define TX0IE_ENABLED   0x04
#define TX0IE_DISABLED  0x00
#define TX1IE_ENABLED   0x08
#define TX2IE_DISABLED  0x00
#define TX2IE_ENABLED   0x10
#define TX2IE_DISABLED  0x00
#define G_TXIE_ENABLED  0x1C
#define G_TXIE_DISABLED 0x00

#define ERRIE_ENABLED   0x20
#define ERRIE_DISABLED  0x00
#define WAKIE_ENABLED   0x40
#define WAKIE_DISABLED  0x00
#define IVRE_ENABLED    0x80
#define IVRE_DISABLED   0x00

/* CANINTF */
#define RX0IF_SET       0x01
#define RX0IF_RESET     0x00
#define RX1IF_SET       0x02
#define RX1IF_RESET     0x00
#define TX0IF_SET       0x04
#define TX0IF_RESET     0x00
#define TX1IF_SET       0x08
#define TX1IF_RESET     0x00
#define TX2IF_SET       0x10
#define TX2IF_RESET     0x00
#define ERRIF_SET       0x20
#define ERRIF_RESET     0x00
#define WAKIF_SET       0x40
#define WAKIF_RESET     0x00
#define IVRF_SET        0x80
#define IVRF_RESET      0x00

/* CANCTRL */ 
#define REQOP_CONFIG    0x80
#define REQOP_LISTEN    0x60
#define REQOP_LOOPBACK  0x40
#define REQOP_SLEEP     0x20
#define REQOP_NORMAL    0x00 

#define ABORT           0x10

#define OSM_ENABLED     0x08

#define CLKOUT_ENABLED  0x04
#define CLKOUT_DISABLED 0x00
#define CLKOUT_PRE_8    0x03
#define CLKOUT_PRE_4    0x02
#define CLKOUT_PRE_2    0x01
#define CLKOUT_PRE_1    0x00

/* CANSTAT */
#define OPMODE_CONFIG   0x80
#define OPMODE_LISTEN   0x60
#define OPMODE_LOOPBACK 0x40
#define OPMODE_SLEEP    0x20
#define OPMODE_NORMAL   0x00


/* RXBnCTRL */
#define RXM_RCV_ALL     0x60
#define RXM_VALID_EXT   0x40
#define RXM_VALID_STD   0x20
#define RXM_VALID_ALL   0x00

#define RXRTR_REMOTE    0x08
#define RXRTR_NO_REMOTE 0x00

#define BUKT_ROLLOVER    0x04
#define BUKT_NO_ROLLOVER 0x00

#define FILHIT0_FLTR_1  0x01
#define FILHIT0_FLTR_0  0x00

#define FILHIT1_FLTR_5  0x05
#define FILHIT1_FLTR_4  0x04
#define FILHIT1_FLTR_3  0x03
#define FILHIT1_FLTR_2  0x02
#define FILHIT1_FLTR_1  0x01
#define FILHIT1_FLTR_0  0x00


/* TXBnCTRL */
#define TXREQ_SET       0x08
#define TXREQ_CLEAR     0x00

#define TXP_HIGHEST     0x03
#define TXP_INTER_HIGH  0x02
#define TXP_INTER_LOW   0x01
#define TXP_LOWEST      0x00
    

/*******************************************************************
 *                  Register Bit Masks                             *
 *******************************************************************/
 #define MASK_0          0x01
 #define MASK_1          0x02
 #define MASK_2          0x04
 #define MASK_3          0x08
 #define MASK_4          0x10
 #define MASK_5          0x20
 #define MASK_6          0x40
 #define MASK_7          0x80    
 
/*******************************************************************
 *                  CAN SPI commands                               *
 *******************************************************************/

#define CAN_RESET       0xC0
#define CAN_READ        0x03
#define CAN_WRITE       0x02
#define CAN_RTS         0x80
#define CAN_RTS_TXB0    0x81
#define CAN_RTS_TXB1    0x82
#define CAN_RTS_TXB2    0x84
#define CAN_RD_STATUS   0xA0
#define CAN_BIT_MODIFY  0x05  
#define CAN_RX_STATUS   0xB0
#define CAN_RD_RX_BUFF  0x90
#define CAN_LOAD_TX     0X40  


/*******************************************************************
 *                  Miscellaneous                                  *
 *******************************************************************/

#define DUMMY_BYTE      0x00
#define TXB0            0x31
#define TXB1            0x41
#define TXB2            0x51
#define RXB0            0x61
#define RXB1            0x71
#define EXIDE_SET       0x08
#define EXIDE_RESET     0x00


//MCP2515   采用8MHz晶振   建议使用20M晶振,否则CAN通讯速率较慢。
//#define CNF1_CAN_10Kbps 0x13
//#define CNF1_CAN_20Kbps 0x09
//#define CNF1_CAN_50Kbps 0x03
//#define CNF1_CAN_100Kbps 0x01
//#define CNF1_CAN_125Kbps 0x01
//#define CNF1_CAN_250Kbps 0x00
//#define CNF1_CAN_500Kbps 0x00
//#define CNF1_CAN_1Mbps 0x00	


//MCP2515   采用16MHz晶振
#define CNF1_CAN_10Kbps 0x31
#define CNF1_CAN_20Kbps 0x13
#define CNF1_CAN_50Kbps 0x07
#define CNF1_CAN_100Kbps 0x03
#define CNF1_CAN_125Kbps 0x03
#define CNF1_CAN_250Kbps 0x01
#define CNF1_CAN_500Kbps 0x00
#define CNF1_CAN_1Mbps 0x00	

//MCP2515   采用20MHz晶振
//#define CNF1_CAN_10Kbps 0x31
//#define CNF1_CAN_20Kbps 0x18
//#define CNF1_CAN_50Kbps 0x09
//#define CNF1_CAN_100Kbps 0x04
//#define CNF1_CAN_125Kbps 0x03
//#define CNF1_CAN_250Kbps 0x01
//#define CNF1_CAN_500Kbps 0x00
//#define CNF1_CAN_1Mbps 0x00

typedef enum
{
	_125kbps, /* 125 kBit/sec */
	_250kbps, /* 250 kBit/sec */
	_500kbps, /* 500 kBit/sec */
	_1Mbps/* 1 MBit/sec   */
}CanBaudRate;

typedef struct
{
	rt_uint32_t mask;//帧标识符屏蔽位
	rt_bool_t ext_flag;//=0为标准帧屏蔽位,=1为扩展帧标识符屏蔽位
}Mask;

typedef struct
{
	rt_uint32_t filter;
	rt_bool_t ext_flag;//=1仅用于扩展帧滤波 =0仅用于标准帧滤波
}Filter;

typedef struct
{
	Mask mask_0;
	Mask mask_1;
	Filter filter_0;	
	Filter filter_1;	
	Filter filter_2;	
	Filter filter_3;	
	Filter filter_4;	
	Filter filter_5;	
}CanFilter;

/*CAN报文结构体*/
typedef struct
{
//	rt_uint8_t node_num;	//节点号,用于多个sit2515的情况
	rt_uint32_t id;			//标识符
	rt_uint8_t dlc;			//数据长度0~8
	rt_uint8_t data[8];		//数据缓冲区
	rt_bool_t ext_flag;		//扩展帧标识 0标准帧 1扩展帧
	rt_bool_t rtr_flag;		//帧类型标识 0远程帧 1数据帧
}CanFrame;
/*波特率和报文滤波配置结构体*/
typedef struct
{
//	rt_uint8_t node_num;	//节点号
	rt_uint8_t baudrate;	//波特率
	CanFilter filter;		//滤波配置
	rt_bool_t br_flag;		//波特率配置是否有效标识
	rt_bool_t fi_flag;		//滤波是否有效标识
}CanDevConfig;
/*工作模式配置结构体*/
typedef struct
{
//	rt_uint8_t node_num;	//节点号
	rt_uint32_t oper_mode;	//节点工作模式
}CanDevMode;

/*环形数据接收缓冲区结构体*/
typedef struct
{
	CanFrame can_recv_buf[RECV_BUF_SIZE];	//环形数据缓冲区
	rt_int16_t recv_pos;					//数据存入缓冲区位置
	rt_int16_t read_pos;					//数据读出缓冲区位置
//	rt_mutex_t rw;							//数据读写互斥			
//	struct rt_messagequeue wq;//等待队列,用于实现阻塞型读操作
}CanDev;

/*中断结构体*/
typedef struct
{
	rt_bool_t tx;//发送中断
	rt_bool_t rx;//接收中断
	rt_bool_t err;//错误中断
	rt_bool_t wakie;//唤醒中断	
}IRQ;




/** sit2515设备用户操作配置结构图 */
struct sit2515_config
{
    uint32_t CS_GPIOx;
    uint32_t CS_GPIO_Pin;	
	rcu_periph_enum CS_GPIO_CLK;
	CanDevConfig 	config;
	CanDevMode		mode;
	CanDev 			Can_rx;//环形数据缓冲区
	CanDev 			Can_tx;//环形数据缓冲区
	IRQ				irq; 	//中断控制
};

struct CAN_control
{
	rt_device_t dev;
	rt_mutex_t mutex;	/*用于CAN发送互斥*/
	rt_sem_t int_sem;   /* 用于2515中断的信号量 */
	rt_sem_t rx_sem;    /* 用于接收CAN数据的信号量 */	
	rt_sem_t tx_sem;    /* 用于发送CAN数据的信号量 */
};


#endif

5.SIT2515驱动代码drv_sit2515.c

代码可以通过文章绑定的资源处下载。

6.配置方法

通过配置如下结构体可对SPI片选信号,CANID,波特率,滤波等进行配置

static struct sit2515_config sit2515_cfg0 = 
{
    .CS_GPIOx = SIT2515_0_SPI_CS_GPIOX,
    .CS_GPIO_Pin = SIT2515_0_SPI_CS_GPIOX_PIN_X,
    .CS_GPIO_CLK = SIT2515_0_SPI_CS_GPIOX_RCU,
	.config.baudrate = _1Mbps,//1000kbps
	.config.filter.mask_0.mask =0x1FFFFFFF,//屏蔽位
	.config.filter.mask_0.ext_flag =1,//=0用于标准帧屏蔽位,=1用于扩展帧屏蔽位
	.config.filter.mask_1.mask =0x1FFFFFFF,//屏蔽位
	.config.filter.mask_1.ext_flag =1,
	.config.filter.filter_0.filter =Set_CANID,//ID
	.config.filter.filter_0.ext_flag =1,//=0用于标准滤波器,=1用于扩展帧滤波器	
	.config.filter.filter_1.filter =Control_CANID,
	.config.filter.filter_1.ext_flag =1,
	.config.filter.filter_2.filter =0x0,
	.config.filter.filter_2.ext_flag =0,
	.config.filter.filter_3.filter =0x0,
	.config.filter.filter_3.ext_flag =0,
	.config.filter.filter_4.filter =0x0,
	.config.filter.filter_4.ext_flag =0,	
	.config.filter.filter_5.filter =0x0,
	.config.filter.filter_5.ext_flag =0,
	.config.br_flag =1,//=1波特率配置有效
	.config.fi_flag =1,//=1滤波配置有效
	.mode.oper_mode =REQOP_NORMAL,//正常模式
	.irq.tx = 0,//发送中断
	.irq.rx = 1,//接收中断
	.irq.err = 1,//错误中断
	.irq.wakie = 0//唤醒中断
};

sit2515_cfg0方法同上。

7.使用方法

通过以上配置后就可以把他当作单片机内部的CAN一样操作了。

/*************************************SIT2515 CAN1使用例程***************************************************************/
#ifdef BSP_USING_SIT2515_1
static void can3_rx_thread(void *parameter)
{
    struct rt_can_msg rxmsg = {0};	
	struct CAN_control *Can = (struct CAN_control *)parameter;
    while (1)
    {	
        /* 阻塞等待接收信号量 */
        rt_sem_take(Can->rx_sem, RT_WAITING_FOREVER);
        /* 从 CAN 读取一帧数据 */
        rt_device_read(Can->dev, 0, &rxmsg, sizeof(rxmsg));	
		/*发送接收到的数据*/
		if(rt_mutex_take(Can->mutex, RT_WAITING_FOREVER)==RT_EOK)/*获取互斥信号量*/
		{
			rt_device_write(Can->dev,0x00, &rxmsg, sizeof(rxmsg));
			rt_mutex_release(Can->mutex);/*释放互斥信号量*/
		}
    }
}
static int can3_sample_init(void)
{
	rt_err_t res;
	rt_thread_t thread;
    /* 查找 CAN 设备 */
	Can3_control.dev = rt_device_find(SIT2515_DEVICE_NAME1);
    if (!Can3_control.dev)
    {
        rt_kprintf("find %s failed!\n", SIT2515_DEVICE_NAME1);
        return RT_ERROR;
    }
	else 
	{				
		res = rt_device_open(Can3_control.dev, RT_DEVICE_FLAG_RDWR);
		if(res==RT_EOK)
		{
			res = rt_device_control(Can3_control.dev, RT_CAN_CMD_SET_BAUD,RT_NULL);
			res = rt_device_control(Can3_control.dev, RT_CAN_CMD_SET_FILTER,RT_NULL);
			res = rt_device_control(Can3_control.dev, RT_CAN_CMD_SET_MODE,RT_NULL);
			res = rt_device_control(Can3_control.dev, RT_DEVICE_CTRL_SET_INT,RT_NULL);
			/* 创建一个动态互斥量 用于发送互斥*/
			Can3_control.mutex = rt_mutex_create("can3_mutex", RT_IPC_FLAG_FIFO);	
			/* 创建数据接收线程 */
			thread = rt_thread_create("can3_rx", can3_rx_thread, &Can3_control, 512, 12, 5);
			if (thread != RT_NULL)
			{
				rt_thread_startup(thread);
			}
			else
			{
				rt_kprintf("create can3_rx thread failed!\n");
			}
		}
		return res;
	}
}
INIT_APP_EXPORT(can3_sample_init);
#endif

8.问题

SPI片选接口还没有来得及集成到ENV里,后边再优化吧,如果有那个小伙伴有时间可以搞一下。目前测试没有发现问题。可能还存在不完善的地方,如果遇到什么问题可以给我留言。

https://download.csdn.net/download/bfk2003/89350807?spm=1001.2014.3001.5503

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
RT-Thread作品秀】基于RT-Thread的CAN数据采集终端作者:tlled 概述在测试产品中,需要监听CAN通信上的数据,之前通过CAN适配器连接到电脑,在上位机上监听,但是在户外测试使用PC机不是很方便,使用ART-PI板卡外接显示屏,来显示要查看的设备总线的数据,以图形的方式显示出来,方便查看,我这次要实现的功能是显示显示十个测距传感器的距离,以条形的方式显示每个距离,同时显示测距传感器中最近的一个距离以数字的方式显示。 开发环境硬件:RT-Thread ART-PI STM32H750开发板,DIY 7寸电容触摸显示屏和CAN转换器 RT-Thread版本:RT-Thread 4.0.3 开发工具及版本:RT-Thread Studio 版本2.0.0 RT-Thread使用情况概述内核部分:线程创建,信号量,消息队列 组件部分:串口,CAN,I2C,LCD 软件包部分:FT6236驱动,peripheral_samples中的can_sample 例程,TouchGFX 4.15 其他:无 硬件框架硬件框图如下: 硬件说明: 1、LCD显示屏部分是根据ART-PI显示接口,绘制的转接驱动板,按照7寸的硬件驱动要求,绘制硬件电路设计电路PCB板。 2、显示触摸屏使用I2C协议的电容触摸屏。 3、CAN驱动是使用的mcp2551收发器芯片转接小板 软件框架说明软件总体流程图: 软件部分说明: 修改LCD和触摸屏驱动程序,能够正常显示和触摸。 使用TouchGFX组件,设计显示的界面。 创建消息队列,用于将CAN通信接收到的消息发送给TouchGFX组件,实现数据传输。 CAN通信接收处理。 软件模块说明演示效果https://www.bilibili.com/video/BV1bi4y1w74V/ 代码地址https://gitee.com/gtizhanghui/art-pi-prj 比赛感悟这次项目是在RT-Thread Studo软件创建ART-PI板卡对应的例程上进行修改的,也是第一次使用这个软件创建项目工程到下载板卡上运行,相比之前使用其他的编译工具,这个软件更方便,功能也更强大,可以直接在软件包里面找到相应设备的驱动直接可以应用到项目中,外设组件和设备驱动也可以应用,确实很方面。 这次项目中使用的TouchGFX与板卡之间的数据交互的实现,花费了较多的时间,通过网上查看资料,通过论坛的帮助,最终解决了问题,收获了不少。 CAN通信部分使用的例程修改的,这部分还好,就是使用硬件滤波功能时,会有报错提示。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值