飞思卡尔DZ60 MSCAN
2012-05-09 12:20:15| 分类: 单片机 | 标签:飞思卡尔 dz60 mscan |字号 订阅
#define EnableCANReInt() (CANRIER |= 0x01) #define DisableCANReInt() (CANRIER &= ~0x01)
// 2.2 参数宏定义 3/4采样
#define SJW 3 // 同步跳转宽度 (value between 1 and 4 Tq) // 位时间长度(通信频率倒数)计算公式:SYSTEM_CLOCK/BRP/(1+TSEG1+TSEG2)
#define BRP 4 // 波特率预分频器 (Value between 1 and 64) #define TSEG1 11 // 位时间时间段1 (value between 1 and 16 Tq) #define TSEG2 4 // 位时间时间段2 (value between 1 and 8 Tq)
//---------------------------------------------------------------------*
//函数名: CAN_Init * //功 能: 初始化CAN模块 * //参 数: 无 * //返 回: 无 * //说 明: *
// (1)CAN时钟源使用芯片总线时钟,设置CAN通信频率为250KHz * // (2)关闭滤波器,接收CAN总线上所有的报文 * //---------------------------------------------------------------------*
void CAN_Init() {
char sj,p;
char t_seg1, t_seg2;
if(0 == CANCTL1_CANE) // 判断CAN模块是否启动 {
// 未启动系统初始化
CANCTL1_CANE = 1; // 系统初始化后CAN模块默认进入初始化状态 }
else {
CANCTL0_SLPRQ = 1; // CAN模块已经运行 还要确保MSCAN没有等待发送的队列
while(0 == CANCTL1_SLPAK); // 将CAN模块置入睡眠模式
CANCTL0_INITRQ = 1;
while(0 == CANCTL1_INITAK); // 将CAN模块置入初始化模式 }
//设置屏蔽
CANIDAC = 0x00; // 0x00 2x32位滤波器 // 0x10 4x16位滤波器 CANIDMR0 = 0x00; // 0x20 8x8 位滤波器
CANIDMR1 = 0x18; // 所有滤波器(掩码位)都是0位有效 CANIDMR2 = 0xff; // 标准格式下后16位可屏蔽掉 CANIDMR3 = 0xff;
CANIDAR0 = 0x24; CANIDAR1 = 0x20; CANIDAR2 = 0x00; CANIDAR3 = 0x00;
CANIDMR4 = 0x00; // 掩码滤波 CANIDMR5 = 0x18; CANIDMR6 = 0x00; CANIDMR7 = 0x01;
CANIDAR4 = 0x08; // 接收比较屏蔽 CANIDAR5 = 0x80; CANIDAR6 = 0x00;
CANIDAR7 = 0x80; // 接受屏蔽ID
sj = (SJW -1) <<6;
p = (BRP -1); // 设置同步及波特率预分频数
CANBTR0 = (sj | p); // 0b10000001 跳转宽度3Tq 预分频2
//CANBTR0 = 0xc0; // 3/4跳转 32分频
t_seg1 = (TSEG1-1); // 时段1和时段2 的tq个数
t_seg2 = (TSEG2-1)<<4;
CANBTR1 = (t_seg1 | t_seg2); // 0B00100101 每位采一个样本 TSEG2:3Tq时钟周期 TSEG1:6Tq
CANCTL1 = 0xc0; // 使能MSCAN模块,设置为一般运行模式,内部总线时钟源250kbps
// 位时间长度(通信频率倒数)=SYSTEM_CLOCK/BRP/(1+TSEG1+TSEG2)
//CANCTL1_LOOPB=1; // CAN模块设为回环自测模式
CANCTL0 = 0x00; // 返回一般模式运行
while(CANCTL1_INITAK); // 等待回到一般运行模式
while(CANCTL0_SYNCH == 0); // 等待总线时钟同步
CANRIER_RXFIE = 1; // 开接收中断 }
//---------------------------------------------------------------------*
//函数名: CAN_Send_Msg * //功 能: 通过CAN模块发送一个报文 * //参 数: CANMsg *sendMsgBuf 待发送的报文指针 * //返 回: uint8 指示是否成功发送 *
//说 明: 在发数据前,要定义和初始化一个报文变量,类型为CANMsg * //---------------------------------------------------------------------*
uint8 CAN_Send_Msg(uint8 *temp_data, uint8 *temp_id) {
uint8 txEmptyBuf; // 空闲发送缓冲区掩码 uint8 i;
if(dataLen > 8) // 检查数据长度 {
return 0; }
if(0 == CANCTL0_SYNCH) // 检查总线时钟 {
return 0; }
txEmptyBuf = 0; do
{ // 寻找空闲的缓冲器
CANTBSEL = CANTFLG;
txEmptyBuf = CANTBSEL; }
while(!txEmptyBuf); // 写入标识符
////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////标准ID格式//////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
if(0 == IDE) // 标准ID格式 {
//CANTIDR0 = idTemp; CANTIDR0 = temp_id[0]; CANTIDR1 = temp_id[1];
CANTIDR1_SRR = RTR; CANTIDR1_IDE = 0; }
////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////扩展ID格式//////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
else // 扩展格式ID {
CANTIDR0 = temp_id[0]; CANTIDR1 = temp_id[1]; CANTIDR2 = temp_id[2]; CANTIDR3 = temp_id[3];
CANTIDR1_SRR = RTR; // 扩展格式时RTR置位 CANTIDR1_IDE = 1; // 扩展帧
CANTIDR3_RTR = 0; // 0 数据帧 1 远程帧 }
////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////数据帧格式//////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
if(0 == RTR) // 判断是否为数据帧 {
for(i = 0; i < dataLen; i++) // 写入数据帧