//=============================================================================
//文件名称:can.c
//功能概要:
//库版本:V3.5.0
//版权所有:源地工作室http://vcc-gnd.taobao.com/
//版本更新:2015-02-20 V1.0
//调试方式:J-LINK-OB
//=============================================================================
//头文件
//#include "can.h"
#include "../../USER/user_app.h"
uint16_t CAN_ID;u32 canid;
uint8_t CAN_DATA0,CAN_DATA1,CAN_DATA2,CAN_DATA3,CAN_DATA4,CAN_DATA5,CAN_DATA6,CAN_DATA7;
uint8_t CanFlag,Display;
/* Private function prototypes -----------------------------------------------*/
/*******************************************************************************
* Function Name : GPIO_Configuration
* Description : Configures the different GPIO ports.
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void GPIO_Configuration_CAN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
// GPIO_PinRemapConfig(GPIO_Remap2_CAN1, ENABLE);
/* CAN Periph clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO,ENABLE);//
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap2_CAN1,ENABLE);
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOD, &GPIO_InitStructure);
}
/*******************************************************************************
* Function Name : NVIC_Configuration
* Description : Configures the nested vectored interrupt controller.
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void NVIC_Configuration_CAN(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Enable CAN1 RX0 interrupt IRQ channel */
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
* Function Name : CAN_Configuration
* Description : Configures the CAN
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void CAN_Configuration(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_Configuration_CAN();
GPIO_Configuration_CAN();
/* CAN register init */
CAN_DeInit(CAN1);//
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE; /* 时间触发禁止, 时间触发:CAN硬件的内部定时器被激活,并且被用于产生时间戳 */
CAN_InitStructure.CAN_ABOM = DISABLE; /* 自动离线禁止,自动离线:一旦硬件监控到128次11个隐性位,就自动退出离线状态。在这里要软件设定后才能退出 */
CAN_InitStructure.CAN_AWUM = DISABLE; /* 自动唤醒禁止,有报文来的时候自动退出休眠 */
CAN_InitStructure.CAN_NART = ENABLE; /* 报文重传, 如果错误一直传到成功止,否则只传一次 */
CAN_InitStructure.CAN_RFLM = DISABLE; /* 接收FIFO锁定, 1--锁定后接收到新的报文摘不要,0--接收到新的报文则覆盖前一报文 */
CAN_InitStructure.CAN_TXFP = ENABLE; /* 发送优先级 0---由标识符决定 1---由发送请求顺序决定 */
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; /* 模式 */
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; /* 重新同步跳宽,只有can硬件处于初始化模式时才能访问这个寄存器 */
// CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; /* 时间段1 100K*/
// CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq; /* 时间段2 100K*/
// CAN_InitStructure.CAN_Prescaler = 45; /* 波特率预分频数100K*/
CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; /* 时间段1 10K*/
CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq; /* 时间段2 10K*/
CAN_InitStructure.CAN_Prescaler = 450; /* 波特率预分频数 10K*/
/* 波特率计算方法 */
/* CANbps= Fpclk/((BRP+1)*((Tseg1+1)+(Tseg2+1)+1) 此处计算为 CANbps=36000000/(45*(4+3+1))=100kHz */ //此处Tseg1+1 = CAN_BS1_8tp
/* 配置大方向: Tseg1>=Tseg2 Tseg2>=tq; Tseg2>=2TSJW */
if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)
{
CAN_InitStructure.CAN_TTCM =CAN_InitStructure.CAN_TTCM;
/* 初始化时先设置CAN_MCR的初始化位 */
/* 然后查看硬件是否真的设置了CAN_MSR的初始化位来确认是否进入了初始化模式 */
}
/* 配置CAN过滤器 */
/* 32位对应的id */
/* stdid[10:0],extid[17:0],ide,rtr */
/* 16位对应的id */
/* stdid[10:0],ide,rtr,extid[17:15] */
/* 一般使用屏蔽模式 */
/* 要注意的是fifo接收存满了中断,还有就是fifo的概念,即取的一直是最早那一个数据, 要释放才能取下一个数据 */
/* 常使用的中断有 */
/* 1,有信息中断,即fifo挂号中断 */
/* 2,fifo满中断 */
/* 3,fifo满之后又有信息来则中断,即fifo溢出中断 */
CAN_FilterInitStructure.CAN_FilterNumber=0; /* 过滤器0 */
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; /* 屏敝模式 */
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; /* 32位 */
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000; /* 以下四个都为0, 表明不过滤任何id */
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0; /* 能够通过该过滤器的报文存到fifo0中 */
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); /* 挂号中断, 进入中断后读fifo的报文函数释放报文清中断标志 */
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);//FIFO0消息挂号中断使能
}
/*******************************************************************************
* Function Name : USB_LP_CAN1_RX0_IRQHandler
* Description : This function handles USB Low Priority or CAN RX0 interrupts
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void USB_LP_CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
OSIntEnter();
CAN_Receive(CAN1,CAN_FIFO0, &RxMessage); /* 此函数包含释放提出报文了的,在非必要时,不需要自己释放 */
CAN_ID=RxMessage.StdId;
CAN_DATA0=RxMessage.Data[0];
CAN_DATA1=RxMessage.Data[1];
CAN_DATA2=RxMessage.Data[2];
CAN_DATA3=RxMessage.Data[3];
CAN_DATA4=RxMessage.Data[4];
CAN_DATA5=RxMessage.Data[5];
CAN_DATA6=RxMessage.Data[6];
CAN_DATA7=RxMessage.Data[7];
Ptr=(uint8*)OSMemGet((OS_MEM*)&Cmd_MEM,(OS_ERR*)&err);
if(err == OS_ERR_NONE) //内存申请成功
{
Ptr[0]=Cmd_GET;
Ptr[1]=Cmd_mnhj;//发送模拟火警请求
OSQPost((OS_Q *)&T_Q_GPRS_Msg,(void*)Ptr,(OS_MSG_SIZE)(sizeof(Ptr)),OS_OPT_POST_FIFO,&err);
}
CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0); /* 清除挂起中断 */
// CanFlag = ENABLE;
OSIntExit();
}
#if 0
/*******************************************************************************
* Function Name : CanWriteData
* Description : Can Write Date to CAN-BUS
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void CanWriteData(uint16_t ID)
{
CanTxMsg TxMessage;
CAN_DATA0=0xaa; CAN_DATA1=0xbb;
CAN_DATA2=0xcc; CAN_DATA3=0xdd;