/***********************************************************************
文件名称:CAN.C
功 能:
编写时间:2012.11.22
编 写 人:
注 意:
***********************************************************************/
#include "CAN.h"
#include "stm32f10x.h"
unsigned char can1_rec_flag = 0;
unsigned char can2_rec_flag = 0;
unsigned char CAN1_DATA[8];
unsigned char CAN2_DATA[8];
unsigned char CAN3_DATA[8]= {0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02};
unsigned char CAN4_DATA[8]= {0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03};
//CAN总线的波特率=PCLK1/((CAN_SJW +CAN_BS1 + CAN_BS2)*CAN_Prescaler)
//格式: 波特率 CAN_SJW CAN_BS1 CAN_BS2 CAN_Prescaler
const unsigned int CAN_baud_table[CAN_BAUD_NUM][5] =
{
//波特率, CAN_SJW, CAN_BS1, CAN_BS2,CAN_Prescaler
{5, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,450}, //未通
{10, CAN_SJW_1tq,CAN_BS1_6tq,CAN_BS2_2tq, 400}, //未通
{15, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,150}, //15K
{20, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,200}, //20k
{25, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,90}, //25k
{40, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,100}, //40k
{50, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,45}, //50k
{62, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,36}, //62.5k
{80, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,50}, //80k
{100, CAN_SJW_1tq,CAN_BS1_5tq, CAN_BS2_2tq,45}, //100K
{125, CAN_SJW_1tq,CAN_BS1_13tq, CAN_BS2_2tq,18}, //125K
{200, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,20}, //200K
{250, CAN_SJW_1tq,CAN_BS1_13tq,CAN_BS2_2tq,9}, //250k
{400, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,10}, //400K
{500, CAN_SJW_1tq,CAN_BS1_5tq, CAN_BS2_2tq,9}, //500K
{666, CAN_SJW_1tq,CAN_BS1_5tq, CAN_BS2_2tq,8}, //未通
{800, CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,5}, //800K
{1000,CAN_SJW_1tq,CAN_BS1_6tq, CAN_BS2_2tq,4}, //1000K
};
void CAN_Configuration(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/////////can1初始///////////////////////////////////
CAN_DeInit(CAN1); //将CAN1的全部寄存器重设为缺省值
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */ //can单元设置
CAN_InitStructure.CAN_TTCM = DISABLE; /* 时间触发禁止, 时间触发:CAN硬件的内部定时器被激活,并且被用于产生时间戳 */
CAN_InitStructure.CAN_ABOM = DISABLE; /* 自动离线禁止,自动离线:一旦硬件监控到128次11个隐性位,就自动退出离线状态。在这里要软件设定后才能退出 */
CAN_InitStructure.CAN_AWUM = DISABLE; /* 自动唤醒禁止,有报文来的时候自动退出休眠 */
CAN_InitStructure.CAN_NART = DISABLE; /* 报文重传, 如果错误一直传到成功止,否则只传一次 */
CAN_InitStructure.CAN_RFLM = DISABLE; /* 接收FIFO锁定, 1--锁定后接收到新的报文摘不要,0--接收到新的报文则覆盖前一报文 */
CAN_InitStructure.CAN_TXFP = ENABLE; /* 发送优先级 0---由标识符决定 1---由发送请求顺序决定 */
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; /* 模式 */
CAN_Baud_Process(500,&CAN_InitStructure);//波特率500K
if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)
{
/* 初始化时先设置CAN_MCR的初始化位 */
/* 然后查看硬件是否真的设置了CAN_MSR的初始化位来确认是否进入了初始化模式 */
}
CAN_FilterInitStructure.CAN_FilterNumber = 0; ///* 过滤器组 */
CAN_FilterInitStructure.CAN_FilterMode =CAN_FilterMode_IdList;//CAN_FilterMode_IdList;//CAN_FilterMode_IdMask; /* 屏敝模式 */
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; ///* 32位 */
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x2220; //32为id 0x11
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;//32位mask
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; ///* 能够通过该过滤器的报文存到fifo0中 */
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); /* 挂号中断, 进入中断后读fifo的报文函数释放报文清中断标志 */
/////////can2初始///////////////////////////////////
CAN_DeInit(CAN2);
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 = DISABLE; /* 报文重传, 如果错误一直传到成功止,否则只传一次 */
CAN_InitStructure.CAN_RFLM = DISABLE; /* 接收FIFO锁定, 1--锁定后接收到新的报文摘不要,0--接收到新的报文则覆盖前一报文 */
CAN_InitStructure.CAN_TXFP = ENABLE; /* 发送优先级 0---由标识符决定 1---由发送请求顺序决定 */
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; /* 模式 */
CAN_Baud_Process(500,&CAN_InitStructure);//波特率500K
if (CAN_Init(CAN2,&CAN_InitStructure) == CANINITFAILED)
{
/* 初始化时先设置CAN_MCR的初始化位 */
/* 然后查看硬件是否真的设置了CAN_MSR的初始化位来确认是否进入了初始化模式 */
}
CAN_FilterInitStructure.CAN_FilterNumber = 14; ///* 过滤器组 */
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdList;//CAN_FilterMode_IdList;//CAN_FilterMode_IdMask; /* 屏敝模式 */
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; ///* 32位 */
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x2240; //0x12
CAN_FilterInitStructure.CAN_FilterIdLow = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; ///* 能够通过该过滤器的报文存到fifo0中 */
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN2,CAN_IT_FMP0, ENABLE); /* 挂号中断, 进入中断后读fifo的报文函数释放报文清中断标志 */
}
/***********************************************************************
文件名称:CAN_Baud_Process
功 能:计算波特率,返回
编写时间:2013.4.25
编 写 人:
注 意:
CAN_SJW : CAN_SJW_1tq - CAN_SJW_4tq 不能比任何一相位缓冲段长
CAN_BS1 : CAN_BS1_1tq - CAN_BS1_16tq
CAN_BS2 : CAN_BS2_1tq - CAN_BS2_8tq
CAN_Prescaler : 1 - 1024
配置说明:
CAN_SJW + CAN_BS1 / (CAN_SJW + CAN_BS1 + CAN_BS2)
0.75 baud > 800k
0.80 baud > 500k
0.875 baud <= 500k
baud = 36 / (CAN_SJW + CAN_BS1 + CAN_BS2) / CAN_Prescaler
***********************************************************************/
void CAN_Baud_Process(unsigned int Baud,CAN_InitTypeDef *CAN_InitStructure)
{
unsigned int i = 0;
for(i = 0; i < CAN_BAUD_NUM; i ++)
{
if(Baud == CAN_baud_table[i][0])
{
CAN_InitStructure->CAN_SJW = CAN_baud_table[i][1];
CAN_InitStructure->CAN_BS1 = CAN_baud_table[i][2];
CAN_InitStructure->CAN_BS2 = CAN_baud_table[i][3];
CAN_InitStructure->CAN_Prescaler = CAN_baud_table[i][4];
break;
}
}
}
u8 CAN1_Send_Msg(u8* msg,u8 len,u16 ID)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=ID; // 标准标识符11位
TxMessage.ExtId=ID; // 设置扩展标示符(29位)
TxMessage.IDE=CAN_ID_STD; // 1使用扩展标识符,0使用标准标识符
TxMessage.RTR=CAN_RTR_DATA; // 消息类型为数据帧,一帧8位
TxMessage.DLC=len; // 发送两帧信息
for(i=0; i<len; i++)
TxMessage.Data[i]=msg[i]; // 第一帧信息
mbox= CAN_Transmit(CAN1, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN1, mbox)==CANTXFAILED)&&(i<0XFFF))i++; //等待发送结束
if(i>=0XFFF)return 1;
return 0;
}
//CAN1中断程序
void CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
unsigned char i;
CAN_Receive(CAN1,CAN_FIFO0, &RxMessage); /* 此函数包含释放提出报文了的,在非必要时,不需要自己释放 */
for(i = 0; i < 8; i ++)
{
CAN1_DATA[i] = RxMessage.Data[i];
}
can1_rec_flag = 1;
CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0); /* 清除挂起中断 */
// SEI();//打开总中断
}
u8 CAN2_Send_Msg(u8* msg,u8 len,u16 ID)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=ID; // 标准标识符11位
TxMessage.ExtId=ID; // 设置扩展标示符(29位)
TxMessage.IDE=CAN_ID_STD; // 1使用扩展标识符,0使用标准标识符
TxMessage.RTR=CAN_RTR_DATA; // 消息类型为数据帧,一帧8位
TxMessage.DLC=len; // 发送两帧信息
for(i=0; i<len; i++)
TxMessage.Data[i]=msg[i]; // 第一帧信息
mbox= CAN_Transmit(CAN2, &TxMessage);
i=0;
while((CAN_TransmitStatus(CAN2, mbox)==CANTXFAILED)&&(i<0XFFF))i++; //等待发送结束
if(i>=0XFFF)return 1;
return 0;
}
//CAN2中断程序
void CAN2_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
unsigned char i;
can2_rec_flag = 1;
CAN_Receive(CAN2,CAN_FIFO0, &RxMessage); /* 此函数包含释放提出报文了的,在非必要时,不需要自己释放 */
for(i = 0; i < 8; i ++)
{
CAN2_DATA[i] = RxMessage.Data[i];
}
CAN_ClearITPendingBit(CAN2,CAN_IT_FMP0); /* 清除挂起中断 */
// CAN2_Send_Msg(CAN2_DATA,8,0x0104);
// SEI();//打开总中断
}
|