初级会员

- 积分
- 195
- 金钱
- 195
- 注册时间
- 2012-6-14
- 在线时间
- 0 小时
|
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
**************************************************************************************************/
|
|