OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3618|回复: 3

CAN告诉帮我看看 找了一天这个can进不了中断?

[复制链接]

22

主题

83

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2012-6-14
在线时间
0 小时
发表于 2015-9-9 20:43:06 | 显示全部楼层 |阅读模式
5金钱
/****************************************Copyright (c)******************************************
**
**
**-------------------------------------文件信息-------------------------------------------------
  **  文 件 名:    CanDriver.c 
  **  描    述:    STM32的CAN总线驱动文件
  **  创 建 人:    BG
**----------------------------------------------------------------------------------------------
  **  修改历史:
  **  2015/09/09   BG   创建
************************************************************************************************/
/* 系统头文件 */
#include "stdio.h"
#include "string.h"
/* 库文件头 */
#include "stm32f10x.h"
#include "sys.h"
/* 类型定义文件 */
#define STM32_CAN1LOCAL
/* 本地头文件*/
#include "CanDriver.h"

CanRxMsg RxMessage;

u8 CAN1_TXReady;
//定义需要用到的CAN_ID
const CanIdUserDef CanIdConfig[] = 
{
//CanID OnLineFlg NoComTime(ms)//NoComTime 表示CAN总线的can数据没有收到过来

{0x18E4A5A6, TRUE, 200}, //VCU_IPC_1--- ID=0x18E4A5A6--- Cycletime=100ms---DLC=8

{0x1000A6A9, TRUE, 200}, //BMS_3 ---ID = 0x1000A6A9 --- Cycletime=100ms ---DLC-8

{0x0CFF1ED0, TRUE, 200}, //MCU_2 ---ID = 0x0C09A7F0 --- Cycletime=50ms --- DLC=8

{0x0800A6A9, TRUE, 200}, //BMS_1 报警等级灯
};

CanFrameDef CanCmdInputBuf[CAN_IDNUM_MAX];
/*************************************************************************************************
** 函数名称: STM32_CAN1_Init
** 功能描述: CAN1 初始化
** 输   入: 无
** 输   出: 无     
** 返 回 值: 无
*************************************************************************************************/
void STM32_CAN1_Init(void)
{
u8 i;
CAN_InitTypeDef       CAN_InitStructure;
NVIC_InitTypeDef      NVIC_InitStructure;
GPIO_InitTypeDef      GPIO_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE); //延时后在使能,工业常用
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//250kps
CAN_InitStructure.CAN_TTCM = DISABLE; //MCR-TTCM  关闭时间触发通信模式使能
CAN_InitStructure.CAN_ABOM = DISABLE; //MCR-ABOM  自动离线管理 
CAN_InitStructure.CAN_AWUM = DISABLE; //MCR-AWUM  使用自动唤醒模式
CAN_InitStructure.CAN_NART = ENABLE; //MCR-NART  禁止报文自动重传  DISABLE-自动重传
CAN_InitStructure.CAN_RFLM = DISABLE; //MCR-RFLM  接收FIFO 锁定模式  DISABLE-溢出时新报文会覆盖原有报文  
CAN_InitStructure.CAN_TXFP = DISABLE; //MCR-TXFP  发送FIFO优先级 DISABLE-优先级取决于报文标示符 

CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;   //正常工作模式
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; //BTR-SJW 重新同步跳跃宽度 1个时间单元
CAN_InitStructure.CAN_BS1 = CAN_BS1_12tq; //BTR-TS1 时间段1 占用了6个时间单元
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq; //BTR-TS1 时间段2 占用了1个时间单元
CAN_InitStructure.CAN_Prescaler = 9; //BTR-BRP 波特率分频器 0-1024 定义了时间单元的时间长度 36/((1+13+4)*8)=250KB

CAN_Init(CAN1, &CAN_InitStructure); //can接口初始化

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //CAN中断向量分组

NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; //CAN总线的接收中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

CAN_ITConfig(CAN1,CAN_IT_FMP0 |CAN_IT_TME, ENABLE);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = USB_HP_CAN1_TX_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);  

memset(CanCmdInputBuf,0,sizeof(CanCmdInputBuf));

for(i = 0; i < CAN_IDNUM_MAX; i++)
{
CanCmdInputBuf.OnLineFlg = FALSE;
CanCmdInputBuf.NoComTimeCnt = 0;
}
CAN_FilterSetID();

}
//can总线过滤器初始化*/
void CAN_FilterSetID(void)
{
CAN_FilterInitTypeDef CAN_FilterInitStructure;

CAN_FilterInitStructure.CAN_FilterNumber = 0; //选择CAN过滤器1
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;   //初始化为标识屏蔽位模式(必须关心和不用关心)
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;   //选择过滤器位宽为1个32位,32位标识位屏蔽位模式

CAN_FilterInitStructure.CAN_FilterIdHigh     = 0x0000; //CAN_FxR1作为ID,过滤器标识号高16位(使用的是标准帧左移五位)
CAN_FilterInitStructure.CAN_FilterIdLow         = 0x0000;   //过滤器标识号低16位

CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; //CAN_FxR2作为屏蔽,根据模式选择过滤器标识号或屏蔽号的高16位 ,表示不关心过滤情况统一接收
CAN_FilterInitStructure.CAN_FilterMaskIdLow     = 0x0000;   //根据模式选择过滤器标识号或屏蔽号的低16位 ,0x0000表示不用关心,可以过滤任何消息
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0; //将FIFO 0分配给过滤器0
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;   //使能过滤器

  CAN_FilterInit(&CAN_FilterInitStructure); //初始化结构体
}

/*************************************************************************************************
** 函数名称:   USB_LP_CAN_RX0_IRQHandler
** 功能描述: CAN1 中断接收数据
** 输   入:    无
** 输   出:    无     
** 返 回 值:    无
*************************************************************************************************/
void USB_LP_CAN1_RX0_IRQHandler (void) 
{
CanRxMsg RxMessage;

CAN_Receive(CAN1,CAN_FIFO0, &RxMessage);

CANComm_Recv(&RxMessage);

CAN_Flg = 1;
}
/*************************************************************************************************
** 函数名称:    USB_HP_CAN_TX_IRQHandler
** 功能描述: CAN1 发送中断
** 输   入:    无
** 输   出:    无     
** 返 回 值:    无
** 先决条件: 
** 全局变量: 
** 调用模块: 
**--------------------------------------------------------------------------------------------
** 修改记录:
** 2015/09/09   BG   建立  
*************************************************************************************************/
void USB_HP_CAN1_TX_IRQHandler (void) 
{
if (CAN1->TSR & CAN_TSR_RQCP0) CAN1->TSR |= CAN_TSR_RQCP0; 
if (CAN1->TSR & CAN_TSR_RQCP1) CAN1->TSR |= CAN_TSR_RQCP1;                 
  if (CAN1->TSR & CAN_TSR_RQCP2) CAN1->TSR |= CAN_TSR_RQCP2;  
CAN1_TXReady = TRUE;
}

/*************************************************************************************************
** 函数名称:    CanComm_Init
** 功能描述:
** 输   入:    无
** 输   出:    无     
** 返 回 值:    无
**--------------------------------------------------------------------------------------------
*************************************************************************************************/
void CanComm_Init(void)
{
STM32_CAN1_Init();
CAN_FilterSetID();
TxMessage.StdId = CanIdConfig[0].CanID>>18;
TxMessage.ExtId = CanIdConfig[0].CanID;
TxMessage.IDE=CAN_ID_EXT;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.DLC=8;
CAN1_TXReady = TRUE;
CAN_Flg = FALSE;
}
/***********************************************************************************************
** 函数名称: void CANComm_Recv(CanRxMsg *Msg)
** 功能描述: CAN接收任务
** 输   入: 接收数据地址
** 输   出: 无     
** 返 回 值: 无
**----------------------------------------------------------------------------------------------
************************************************************************************************/
void CANComm_Recv(CanRxMsg *Msg)
{
INT8U i;
INT32U CanID;
CanID = Msg->ExtId;
for(i = 0; i < CAN_IDNUM_MAX; i++)
{
if(CanID == CanIdConfig.CanID)
{
CanCmdInputBuf.CanId = CanID;
CanCmdInputBuf.data[0] =  Msg->Data[0];
CanCmdInputBuf.data[1] =  Msg->Data[1];
CanCmdInputBuf.data[2] =  Msg->Data[2];
CanCmdInputBuf.data[3] =  Msg->Data[3];
CanCmdInputBuf.data[4] =  Msg->Data[4];
CanCmdInputBuf.data[5] =  Msg->Data[5];
CanCmdInputBuf.data[6] =  Msg->Data[6];
CanCmdInputBuf.data[7] =  Msg->Data[7];

CanCmdInputBuf.OnLineFlg = TRUE;
CanCmdInputBuf.NoComTimeCnt = 0;
break;
}
}
}
/*********************************************************************************************
** 函数名称: INT8U CANComm_Send(CanTxMsg *TxMessage)
** 功能描述: CAN发送一帧数据
** 输   入: 待发送的数据地址
** 输   出: 无     
** 返 回 值: 无
**--------------------------------------------------------------------------------------------
**********************************************************************************************/
u8 CANComm_Send(CanTxMsg *TxMessage,u32 CanID) 
{
INT8U  TransmitMailbox,i;   
INT32U TimeOut = 0;
for(i = 0; i < CAN_IDNUM_MAX; i++)
{
if(CanID == CanCmdInputBuf.CanId )

TxMessage->StdId = CanID>>18;
TxMessage->ExtId = CanID;
TxMessage->Data[0] = CanCmdInputBuf.data[0];
TxMessage->Data[1] = CanCmdInputBuf.data[1];
TxMessage->Data[2] = CanCmdInputBuf.data[2];
TxMessage->Data[3] = CanCmdInputBuf.data[3];
TxMessage->Data[4] = CanCmdInputBuf.data[4];
TxMessage->Data[5] = CanCmdInputBuf.data[5];
TxMessage->Data[6] = CanCmdInputBuf.data[6];
TxMessage->Data[7] = CanCmdInputBuf.data[7];
}
else  
for(i = 0; i < 8; i++) TxMessage->Data = 0;
TransmitMailbox = CAN_Transmit(CAN1,TxMessage);
while(CAN_TransmitStatus(CAN1,TransmitMailbox) != CAN_TxStatus_Ok)
{
TimeOut++;
if(TimeOut > 10000000) return  CAN1_FALSE;
}
}
return CAN1_TRUE;
}

/*********************************************************************************************
** 函数名称: CanDeviceOnlineCheckService
** 功能描述: 检测CAN设备信号状态, 判断是否在线
** 输   入: 无
** 输   出: 无     
** 返 回 值: 无0000000
**--------------------------------------------------------------------------------------------
**********************************************************************************************/
void CanDeviceOnlineCheckService(void)
{
u16 i;

for(i = 0; i < CAN_IDNUM_MAX; i++)
{
if(++CanCmdInputBuf.NoComTimeCnt >= CanIdConfig.NoComTime)
{
CanCmdInputBuf.NoComTimeCnt = 0;
CanCmdInputBuf.OnLineFlg = FALSE;
}
}
}
/*********************************************************************************************
** 函数名称: GetCanDeviceOnlineStutas
** 功能描述: 获取对应CAN的在线状态
** 输   入: ID号码
** 输   出: 无     
** 返 回 值: 无
**--------------------------------------------------------------------------------------------
**********************************************************************************************/

u8 GetCanDeviceOnlineStutas(u32 CanID)
{
u16 i;

for(i = 0; i < CAN_IDNUM_MAX; i++)
{
if(CanID == CanIdConfig.CanID) return CanCmdInputBuf.OnLineFlg;
}
return 0;
}
/*************************************************************************************************
**       END FILE
**************************************************************************************************/






越是自由的环境中越要自律
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-9-9 23:34:31 | 显示全部楼层
楼主可以参考我们的can例程。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

22

主题

83

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2012-6-14
在线时间
0 小时
 楼主| 发表于 2015-9-10 11:27:40 | 显示全部楼层
回复【2楼】正点原子:
--------------------------------- 
采用的HSI,没有用HSE,不知道问他啊!
越是自由的环境中越要自律
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-9-10 22:46:15 | 显示全部楼层
回复【3楼】bingge191:
---------------------------------
根据时钟频率.  相应的做修改即可.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 00:07

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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