我使用EVT中的CAN/testdemo文件夹中的回环模式进行测试,能测试通过。我自己写的程序中只能发送数据,不能接收数据,是我的程序中对CAN的初始化哪里不正确还是我的接收程序不对,以及是否还有其它什么原因?使用CAN分析仪查看正确接收到来自单片机的数据,向单片机发送的数据也是成功了的
以下是我的初始化代码
/*
*********************************************************************************************************
* 模块名称 : can驱动模块
* 文件名称 : bsp_can.c
* 说 明 : 驱动can接口
* 修改记录 :
*********************************************************************************************************
*/
#include "../bsp.h"
/*
*********************************************************************************************************
* 宏定义
*********************************************************************************************************
*/
/* CAN1时钟 */
#define CAN1_CLK RCC_APB1Periph_CAN1
#define CAN1_MODE CAN_Mode_Normal /* 工作模式 */
/* CAN1_TX的引脚 */
#define CAN1_TX_RCC RCC_APB2Periph_GPIOD
#define CAN1_TX_PIN GPIO_Pin_1
#define CAN1_TX_PORT GPIOD
/* CAN1_RX的引脚 */
#define CAN1_RX_RCC RCC_APB2Periph_GPIOD
#define CAN1_RX_PIN GPIO_Pin_0
#define CAN1_RX_PORT GPIOD
/* CAN1 STB的引脚 */
#define CAN1_STB_RCC RCC_APB2Periph_GPIOD
#define CAN1_STB_PIN GPIO_Pin_11
#define CAN1_STB_PORT GPIOD
/* 接收中断配置 */
#define CAN1_RX_IRQ_HANDLE CAN1_RX1_IRQHandler
#define CAN1_RX_IRQ CAN1_RX1_IRQn
#define CAN1_RX_IRQ_PRIO 10
/* CAN1 绑定FIFO的编号 */
#define CAN1_FIFIO_NUM CAN_Filter_FIFO0
/*
*********************************************************************************************************
* 函数声明
*********************************************************************************************************
*/
int bsp_can_set_status(CAN_PORT_ENUM can, CAN_STATUS_ENUM status);
/*
*********************************************************************************************************
* 变量
*********************************************************************************************************
*/
/* can消息 */
CanRxMsg can_rx_msg[CAN_PORT_NUM];
const CAN_PIN_MNT can_pin_mnt[CAN_PORT_NUM] = {
/* CAN0 */
{
{CAN1_RX_RCC, CAN1_RX_PIN, CAN1_RX_PORT}, /* rx */
{CAN1_TX_RCC, CAN1_TX_PIN, CAN1_TX_PORT}, /* tx */
{CAN1_STB_RCC, CAN1_STB_PIN, CAN1_STB_PORT} /* stb */
}
};
CAN_CFG_MNT_T can_cfg_mnt[CAN_PORT_NUM] = {
/* CAN1 */
{
CAN1, /* 端口 */
CAN1_CLK, /* 时钟 */
CAN_BAUDRATE_500K, /* 波特率 */
CAN1_RX_IRQ, /* 中断号 */
CAN1_RX_IRQ_PRIO, /* 中断优先级 */
0, /* 接收中断回调 */
CAN_WORK_STATUS, /* 工作状态 */
CAN1_MODE, /* 工作模式 */
0, /* 标准ID */
}
};
/*
*********************************************************************************************************
* 函 数 名: bsp_can_init_port
* 功能说明: 配置can指示灯相关的GPIO
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
int bsp_can_init_port(const CAN_PIN_MNT *can)
{
GPIO_InitTypeDef GPIO_InitSturcture={0};
/* 时钟初始化 */
RCC_APB2PeriphClockCmd(can->rx.clk | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(can->tx.clk | RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(can->stb.clk, ENABLE);
/* 将CAN1重映射到 PD0和PD1引脚上 */
GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE);
/* 初始化 tx pin */
GPIO_InitSturcture.GPIO_Pin = can->tx.pin;
GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(can->tx.port, &GPIO_InitSturcture);
/* 初始化 rx pin */
GPIO_InitSturcture.GPIO_Pin = can->rx.pin;
GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(can->rx.port, &GPIO_InitSturcture);
/* 初始化 STB pin */
GPIO_InitSturcture.GPIO_Pin = can->stb.pin;
GPIO_InitSturcture.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(can->stb.port, &GPIO_InitSturcture);
return 0;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_can_init_cfg
* 功能说明: 配置CAN总线相关参数
* 形 参: can can配置结构体
* 返 回 值: 0 成功
*********************************************************************************************************
*/
int bsp_can_init_cfg(CAN_CFG_MNT_T *can, CAN_PORT_ENUM port)
{
int result = 0;
CAN_InitTypeDef CAN_InitSturcture = {0};
CAN_FilterInitTypeDef CAN_FilterInitSturcture = {0};
NVIC_InitTypeDef NVIC_InitStructure = {0};
/* 初始化CAN时钟 */
RCC_APB1PeriphClockCmd(can->can_clk, ENABLE);
/* initialize CAN parameters */
CAN_InitSturcture.CAN_TTCM = DISABLE; /* 禁止时间触发模式(不生成时间戳), T */
CAN_InitSturcture.CAN_ABOM = DISABLE; /* 禁止自动总线关闭管理 */
CAN_InitSturcture.CAN_AWUM = DISABLE; /* 禁止自动唤醒模式 */
CAN_InitSturcture.CAN_NART = ENABLE; /* 使能仲裁丢失或出错后的自动重传功能 */
CAN_InitSturcture.CAN_RFLM = DISABLE; /* 禁止接收FIFO */
CAN_InitSturcture.CAN_TXFP = DISABLE; /* 禁止传输FIFO优先级 */
CAN_InitSturcture.CAN_Mode = can->mode; /* 设置CAN为正常工作模式 */
/*
CAN 波特率 = apb1 / Prescaler / (SJW + BS1 + BS2);
SJW = synchronisation_jump_width
BS = bit_segment
本例中,设置CAN波特率为1000Kbps
CAN 波特率 = 72000000 / 6 / (1 + 5 + 6) / = 1000kHz
*/
CAN_InitSturcture.CAN_SJW = CAN_SJW_1tq;
CAN_InitSturcture.CAN_BS1 = CAN_BS1_6tq;
CAN_InitSturcture.CAN_BS2 = CAN_BS2_5tq;
switch(can->baudrate){
case CAN_BAUDRATE_1M:
CAN_InitSturcture.CAN_Prescaler = 6;
break;
case CAN_BAUDRATE_500K:
CAN_InitSturcture.CAN_Prescaler = 12;
break;
case CAN_BAUDRATE_250K:
CAN_InitSturcture.CAN_Prescaler = 24;
break;
case CAN_BAUDRATE_125K:
CAN_InitSturcture.CAN_Prescaler = 48;
break;
case CAN_BAUDRATE_100K:
CAN_InitSturcture.CAN_Prescaler = 60;
break;
case CAN_BAUDRATE_50K:
CAN_InitSturcture.CAN_Prescaler = 120;
break;
default:
/* 默认500k */
CAN_InitSturcture.CAN_Prescaler = 12;
result = -1;
break;
}
/* initialize CAN */
if(CAN_Init(CAN1, &CAN_InitSturcture) == ERROR) {
result = -1;
}
/* initialize filter */
CAN_FilterInitSturcture.CAN_FilterNumber = 0; /* 滤波器序号,0-13,共14个滤波器 */
CAN_FilterInitSturcture.CAN_FilterMode = CAN_FilterMode_IdList; /* 滤波器模式,设置ID掩码模式 */
CAN_FilterInitSturcture.CAN_FilterScale = CAN_FilterScale_32bit; /* 32位滤波 */
CAN_FilterInitSturcture.CAN_FilterIdHigh = 0x0000; /* 掩码后ID的高16bit */
CAN_FilterInitSturcture.CAN_FilterIdLow = 0x0000; /* 掩码后ID的低16bit */
CAN_FilterInitSturcture.CAN_FilterMaskIdHigh = 0x0000; /* ID掩码值高16bit */
CAN_FilterInitSturcture.CAN_FilterMaskIdLow = 0x0006; /* ID掩码值低16bit */
CAN_FilterInitSturcture.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; /* 滤波器绑定FIFO 0 */
CAN_FilterInitSturcture.CAN_FilterScale = ENABLE; /* 使能滤波器 */
CAN_FilterInit(&CAN_FilterInitSturcture);
/* 配置工作模式 */
bsp_can_set_status(port, can->status);
return result;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_init_can
* 功能说明: 配置can
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
int bsp_init_can(
CAN_PORT_ENUM can,
int (*rx_msg_irq_callback)(CanRxMsg *msg))
{
int result = -1;
if(can < CAN_PORT_NUM) {
/* IO初始化 */
bsp_can_init_port(&can_pin_mnt[can]);
/* CAN初始化 */
bsp_can_init_cfg(&can_cfg_mnt[can], can);
/* 设置回到函数 */
can_cfg_mnt[can].rx_irq_callback = rx_msg_irq_callback;
result = 0;
}
return result;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_can_set_status
* 功能说明: 设置CAN状态
* 形 参: port 端口
* status 状态
* 返 回 值: 0 成功
*********************************************************************************************************
*/
int bsp_can_set_status(CAN_PORT_ENUM can, CAN_STATUS_ENUM status)
{
int result = -1;
if(can < CAN_PORT_NUM) {
if(status == CAN_STANDBY_STATUS) {
can_pin_mnt[can].stb.port->BSHR = can_pin_mnt[can].stb.pin;
} else {
can_pin_mnt[can].stb.port->BCR = can_pin_mnt[can].stb.pin;
}
result = 0;
}
return result;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_can_tx_msg
* 功能说明: 发送数据
* 形 参: msg 发送数据缓冲区
* port CAN端口值
* 返 回 值: 0 发送成功
* -1 发送失败
*********************************************************************************************************
*/
int bsp_can_tx_msg(CAN_PORT_ENUM port, CanTxMsg *msg)
{
uint8_t mbox;
uint16_t i = 0;
int result = -1;
if(port < CAN_PORT_NUM) {
mbox = CAN_Transmit(can_cfg_mnt[port].com, msg);
i = 0;
while((CAN_TransmitStatus(can_cfg_mnt[port].com, mbox) != CAN_TxStatus_Ok) && (i < 0xFFF)){
i++;
}
if( i != 0xFFF ){
result = 0;
}
}
return result;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_can_receive_msg
* 功能说明: 接收数据
* 形 参: buf 接收区数据缓冲区
* port CAN端口值
* 返 回 值: 接收数据长度
*********************************************************************************************************
*/
uint8_t bsp_can_receive_msg( uint8_t *buf, CAN_PORT_ENUM port)
{
uint8_t result = 0;
CanRxMsg CanRxStructure;
if( CAN_MessagePending(can_cfg_mnt[port].com, CAN_FIFO0) != 0){
CAN_Receive(can_cfg_mnt[port].com, CAN_FIFO0, &CanRxStructure );
memcpy(buf, CanRxStructure.Data, CanRxStructure.DLC);
result = CanRxStructure.DLC;
}
return result;
}
/*
*********************************************************************************************************
* 函 数 名: bsp_can_get_cfg_info
* 功能说明: 获取can配置结构体
* 形 参: can 端口
* 返 回 值: 0 成功
*********************************************************************************************************
*/
CAN_CFG_MNT_T *bsp_can_get_cfg_info(CAN_PORT_ENUM port)
{
return &can_cfg_mnt[port];
}
/*******************************************************************************************************/