标题:
求助:两块飞思卡尔开发板间的CAN通信
[打印本页]
作者:
cyberwang0
时间:
2010-3-21 12:33
标题:
求助:两块飞思卡尔开发板间的CAN通信
这个问题已经困扰我很久了,希望这里有达人能够为我指点迷津!!
硬件环境:两块飞思卡尔S12XDP512、DB9线一根、BDM仿真盒
软件环境:CW 4.7
如下是我的程序,分为node1_rx和node2_tx
发送部分:
unsigned short ID2=0x16d; //这是我要发送报文的ID
const unsigned char Data2[] = "who";
const unsigned char DataLenth2 = 3;
void delay(int num)
{
int i,j;
for(i=num;i>0;i--)
for(j=0;j<200;j++);
}
void caninit(void)
{
CAN0CTL1 |= (1 << 7); //MSCAN12模块使能
//初始化模式请求,并判断初始化应答位,INITACK为1则CAN模块已进入初始化
CAN0CTL0 |= (1 << 0); // INITRQ=1,初始化请求
//等待应答
while ((CAN0CTL1 & (1<<0)) == 0)
{
}
CAN0CTL1 &= 0xbf; //MSCAN12时钟源选择外部晶振fmscan=16M
CAN0BTR0 = 0xc7; //同步跳转宽度为1,预分频因子为8
CAN0BTR1 = 0xa3; //将位速率设置成 250 kbps
CAN0IDAC = 0x00; //两个32位验收过滤器
CAN0CTL0 &= ~(1<<0); //INITRQ=0,退出初始化模式
//等待应答
while ((CAN0CTL1 | (1<<0)) == 1)
{
}
CAN0TIER = 0x07; //设置中断方式
}
unsigned char GetSNDBUF(void)
{
unsigned char bufbit = 0xFF; //空闲区号
//查找空闲的发送缓冲区
if ((CAN0TFLG & (1 << 0)) != 0)
{ //发送缓冲区0空
bufbit = 0;
}
else if ((CAN0TFLG & (1 << 1)) != 0)
{ //发送缓冲区1空
bufbit = 1;
}
else if ((CAN0TFLG & (1 << 2)) != 0)
{ //发送缓冲区2空
bufbit = 2;
}
return bufbit;//返回空闲区号
}
//CANSND1DFRM:CAN发送1帧数据-----------------------------------------------*
//功 能:CAN发送1帧数据(数据长度<=8) *
//参 数:ID---报文标识符 *
// DataBUF---报文数据区首址 *
// LEN---报文数据长度 *
//返 回:INT8U CANsnd1DFrm --- 发送成功与否标志, *
// =0,没有空闲发送缓冲区,发送不成功;=1,发送成功 *
//说明:在发送数据之前,先查询是否有空闲发送缓冲区,若无则不能发送,返回0 *
//-------------------------------------------------------------------------*
unsigned char CANSND1DFRM(unsigned short ID,unsigned char * DataBUF, unsigned char LEN)
{
unsigned char i;
unsigned char * addr; //发送缓冲区
unsigned char BufNum = 0xFF; //空闲的发送缓冲区号
BufNum = GetSNDBUF(); //查找空闲的发送缓冲区
if (BufNum == 0xFF) //若返回0xff,则没有空闲的发送缓冲区
return 0; //没有空闲的发送缓冲区,发送不成功,返回0
switch(BufNum)
{
case 0:
CAN0TBSEL |= (1<<0); //选中发送缓冲区0
break;
case 1:
CAN0TBSEL |= (1<<1); //选中发送缓冲区1
break;
case 2:
CAN0TBSEL |= (1<<2); //选中发送缓冲区2
break;
default:
break;
}
addr=(unsigned char *)(&CAN0TXIDR0); //获得发送前台缓冲区首地址
//---------------------------------------------------------------------
//将报文按CAN格式进行封装并存入空闲发送缓冲区等待发送
addr[0]=ID>>3;
addr[1]=ID<<5;
addr[2]=0;
addr[3]=0;
for(i = 0; i < LEN; i++)
addr[i+4] = DataBUF
; //数据赋值
addr[12] = LEN; //数据长度
//---------------------------------------------------------------------
//发送缓冲区相应TXE位写1清除该位来通知MSCAN12发送数据
switch(BufNum)
{
case 0:
CAN0TFLG |= (1<<0); //发送缓冲区0准备就绪
break;
case 1:
CAN0TFLG |= (1<<1); //发送缓冲区1准备就绪
break;
case 2:
CAN0TFLG |= (1<<2); //发送缓冲区2准备就绪
break;
default:
break;
}
return (1); //数据成功写入空闲缓冲区,返回1
}
void main (void)
{
caninit();
DDRB=0xff;
PORTB=0xff;
EnableInterrupts;
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 39 can_node1_tx_int()
{
CAN0TFLG=0xff;
CANSND1DFRM(ID2,(unsigned char *)(Data2),DataLenth2);
}
在另一块单片机里写入如下接收程序:
byte data0,data1,data2,data3,data4,data5,data6,data7,len;
void delay(int num)
{
int i,j;
for(i=num;i>0;i--)
for(j=0;j<200;j++);
}
void set_rx_id(unsigned short ID)
{
unsigned char id4,id3,id2,id1;
id4=ID>>3;
id3=ID<<5;
CAN0IDAR0=id4;
CAN0IDAR1=id3;
}
void caninit(void)
{
CAN0CTL1 |= (1 << 7); //MSCAN12模块使能
//初始化模式请求,并判断初始化应答位,INITACK为1则CAN模块已进入初始化
CAN0CTL0 |= (1 << 0); // INITRQ=1,初始化请求
//等待应答
while ((CAN0CTL1 & (1<<0)) == 0)
{
}
CAN0CTL1 &= 0xbf; //MSCAN12时钟源选择外部晶振fmscan=16M
CAN0BTR0 = 0xc7; //同步跳转宽度为1,预分频因子为8
CAN0BTR1 = 0xa3; //将位速率设置成 250 kbps
CAN0IDAC = 0x00; //两个32位验收过滤器
set_rx_id(0x16d);
CAN0IDAR4 = 0x00;
CAN0IDAR5 = 0x00;
CAN0IDAR6 = 0x00;
CAN0IDAR7 = 0x00;
CAN0IDMR0 = 0x00; //给接收验证屏蔽寄存器0-1赋值
CAN0IDMR1 = 0x00;
CAN0IDMR2 = 0x00;
CAN0IDMR3 = 0x00;
CAN0IDMR4 = 0x00;
CAN0IDMR5 = 0x00;
CAN0IDMR6 = 0x00;
CAN0IDMR7 = 0x00;
CAN0CTL0 &= ~(1<<0); //INITRQ=0,退出初始化模式
//等待应答
while ((CAN0CTL1 | (1<<0)) == 1)
{
}
CAN0RIER = 0x01; //设置中断方式
}
void main(void)
{
caninit();
DDRB=0xff;
PORTB=0xff;
EnableInterrupts;
while(1);
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 38 can_node2_rx_int()
{
CAN0CTL0_RXFRM=1;
data0=CAN0RXDSR0;
data1=CAN0RXDSR1;
data2=CAN0RXDSR2;
data3=CAN0RXDSR3;
data4=CAN0RXDSR4;
data5=CAN0RXDSR5;
data6=CAN0RXDSR6;
data7=CAN0RXDSR7;
len=CAN0RXDLR;
PORTB=~PORTB;
delay(3000);
CAN0RFLG_RXF=1;
}
当发送部分写入第一块板子里后,通过中断发送一个报文,ID为0x16d,是标准的11位
接收部分同样接收该ID的报文。
但是始终无法接收到,到底错在哪里?
望达人不惜赐教!!
作者:
zy20803118
时间:
2010-3-25 09:32
大哥,我问两个问题:
1.nod2中断程序里CAN0RXDSR0是XD系列单片机才有的吗?我用的是MC9S12DP256,貌似没见过这几个寄存器
2.set_rx_id子程序里id3,id4是啥呢?
3.退出初始化模式那while循环语句里逻辑判断好像有误(是否是照搬的S12例程里的呢)?
其他的问题暂时不说了,感觉问题不少啊,呵呵
作者:
zy20803118
时间:
2010-3-25 09:33
大哥,我问两个问题:
1.nod2中断程序里CAN0RXDSR0是XD系列单片机才有的吗?我用的是MC9S12DP256,貌似没见过这几个寄存器
2.set_rx_id子程序里id3,id4是啥呢?
3.退出初始化模式那while循环语句里逻辑判断好像有误(是否是照搬的S12例程里的呢)?
其他的问题暂时不说了,感觉问题不少啊,呵呵
作者:
zy20803118
时间:
2010-3-25 09:36
大哥,我问两个问题:
1.nod2中断程序里CAN0RXDSR0是XD系列单片机才有的吗?我用的是MC9S12DP256,貌似没见过这几个寄存器
2.set_rx_id子程序里id3,id4是啥呢?
3.退出初始化模式那while循环语句里逻辑判断好像有误(是否是照搬的S12例程里的呢)?
其他的问题暂时不说了,感觉问题不少啊,呵呵
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0