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里,后边再优化吧,如果有那个小伙伴有时间可以搞一下。目前测试没有发现问题。可能还存在不完善的地方,如果遇到什么问题可以给我留言。