打印
[AVR单片机]

有调试MCP2510 CAN总线的大侠吗?。。需要一个调试通过的CAN总线程序

[复制链接]
1827|2
手机看帖
扫描二维码
随时随地手机跟帖
沙发
qin552011373| | 2013-4-20 09:31 | 只看该作者
你可以先调试  遇到问题再来这里  自然会有人帮你

使用特权

评论回复
板凳
zhao3462910|  楼主 | 2013-5-8 09:55 | 只看该作者
qin552011373 发表于 2013-4-20 09:31
你可以先调试  遇到问题再来这里  自然会有人帮你
#include "MCP2510.h"
#include "config.h"

#define uint unsigned int
#define uchar unsigned char
#define ulong unsigned long

uchar com_recv[20];
uchar com_len=0;
uchar k=0;
uint com_js=0,com_fs=0;
uchar Rdata[20];

void Put_Char(uchar ch);

//************************************SPI写子程序*******************************
void SPISendByte(uchar Cmd)
{
uchar i,Status=0;
CANCSDW;
DelayUs(50);
for (i=0;i<8;i++)
{ //in...
CANSCKDW;
DelayUs(5);
if((Cmd&0x80)==0x80) //高位先出
CANSIUP;
else
CANSIDW;
DelayUs(5);
CANSCKUP;
Cmd=Cmd<<1;
DelayUs(10);
}
}
//************************************SPI读程序*********************************
unsigned int SPIRecvByte(void)
{
uchar i,Status=0;
CANCSDW;
for (i=0;i<8;i++)
{ //in...

CANSCKUP;
DelayUs(5);

Status=Status<<1;

if (CHKSO)
{
Status |=0x01;
}
else
{
Status &=0xFE;
}

DelayUs(5);
CANSCKDW;
DelayUs(5);
}

return (Status);
}

//********************************MCP复位程序************************************
void MCP2510_Reset(void)
{
CANCSDW;
SPISendByte(0xc0);
CANCSUP;
}
//*******************************CAN读数据**************************************
uchar CAN_Read_SS(uchar address)
{
uchar ret;
CANCSUP;
DelayUs(4);

SPISendByte(0x03);
SPISendByte(address);
ret = SPIRecvByte();

CANCSUP;
return ret;
}
//********************************CAN写数据*************************************
void CAN_Write_SS(uchar address,uchar Value)
{
CANCSUP;
DelayUs(4);
SPISendByte(0x02);
SPISendByte(address);
SPISendByte(Value);

CANCSUP;
DelayUs(5);
}

//***********读取 MCP2510的状态(包括发送接收中断标志位和各请求发送位)*********
uchar MCP2510_ReadStatus()
{
uchar result;
CANCSDW;
SPISendByte(0xa0);
result = SPIRecvByte();
CANCSUP;
return result;
}
//******************************************************************************
/*--- 修改寄存器的值 ---*/
//mask为掩码
void CAN_Set_Var(uchar address,uchar mask,uchar dat)
{
CANCSUP;
DelayUs(10);
CANCSDW;

SPISendByte(0x05);
SPISendByte(address);//64页
SPISendByte(mask);
SPISendByte(dat);

CANCSUP;
}
/*******************************************************************************************************
检测是否发送完毕,是否已经可以进行发送
*******************************************************************************************************/
unsigned char mcp_transmit_busy(unsigned send_buf)
{
unsigned char temp;
switch(send_buf)
{
case 0:
{
temp=MCP2510_ReadStatus();//读取当前的MCP2510发送状态
if(temp&0x04)
{
return 1;
}
return 0;
break;
}
case 1:
{
temp=MCP2510_ReadStatus();//读取当前的MCP2510发送状态
if(temp&0x10)
{
return 1;
}
return 0;
break;
}
case 2:
{
temp=MCP2510_ReadStatus();//读取当前的MCP2510发送状态
if(temp&0x40)
{
return 1;
}
return 0;
break;
}
}
}
//******************************CAN初始化***************************************
void Init_Can()
{
unsigned char i,j,a;
CANCSDW;
MCP2510_Reset();
DelayMs(10);
CANCSUP;

//设置为配置模式
CAN_Set_Var(0x0F,0xE0,0x80);

//TJA1050 最低波特率为60K
//设置通信的速率 16M 晶振 125k
CAN_Write_SS(0x2A, 0x03);
CAN_Write_SS(0x29, 0xB9);
CAN_Write_SS(0x28, 0x04);

//0x00 仅接收标准或扩展标识符
//0x60 关闭接收所有数据
CAN_Write_SS(0x60,0x60); //接收缓冲器0 接收所有数据报文

//滤波
CAN_Write_SS(0x00,0);
CAN_Write_SS(0x01,0);
CAN_Write_SS(0x02,0);
CAN_Write_SS(0x03,0);

//屏蔽
CAN_Write_SS(0x20,0);
CAN_Write_SS(0x21,0);
CAN_Write_SS(0x22,0);
CAN_Write_SS(0x23,0);

//接收数据产生中断
CAN_Write_SS(0x2B,0x01); //接收缓冲器0 满中断使能

//回环模式
CAN_Set_Var(0x0F,0xE0,0x40);
//工作模式
//CAN_Set_Var(0x0F,0xE0,0);

a = TXB0CTRL;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 14; j++)
{
CAN_Write_SS(a, 0);
a++;
}
a += 2; // 我们不清 CANSTAT 和 CANCTRL
}
// 并且两个接收缓冲区清零.
CAN_Write_SS(RXB0CTRL, 0);

}
//*******************************************************************************
//////////////////////////////CAN发送部分////////////////////////////////////////

void CAN_Send_End()
{
uchar i;
for(i=1;i<com_len;i++)
{
CAN_Write_SS(0x30+i,com_recv[i]);
}

CAN_Set_Var(0x30,com_recv[0],com_recv[0]);

do
{
i = CAN_Read_SS(0x30);// 读发送缓存0控制寄存器
i = i & 0x08; // 观察发送请求位
}while(i);
}

/*--- 中断的定义 ---*/
//*********************************CAN接收中断入口******************************
#pragma interrupt_handler int1_isr:3
void int1_isr(void)//CAN
{
uchar Sta_Int,i;
Sta_Int = CAN_Read_SS(0x2C); /* 读中断标志寄存器 */
CAN_Write_SS(0x2C,0x00); /* 清除所有中断标志位 */

/*--- 如果为接收缓冲器0中断 ---*/
if(Sta_Int & 0x01)
{
for(i=0;i<14;i++)
{
Put_Char(CAN_Read_SS(0x60+i));
}

com_fs=com_fs+14;
}
}
//******************************************************************************
void Put_Char(uchar ch)
{
//while ( !( UCSRA & (1<<UDRE)) ) ;
UDR = ch;
//while(TI==0);
//TI = 0;
}
//*******************主程序***************
void main(void)
{
WakeUp();
Init_Can();
com_len=0;
MCP2510_Reset();

CANCSDW; // CS片选拉低
DelayUs(5);
SPISendByte(0x02); // 写指令
SPISendByte(0x66); // 写地址
SPISendByte(0x18); // 写数据

CANCSUP;
DelayUs(5);


CANCSUP;
DelayUs(1);
CANCSDW; // 片选拉低
SPISendByte(0xa0); // 写空操作,产生SCK时钟
ret = SPIRecvByte(); // 读数据

CANCSUP;
NOP();
DelayUs(1);

while(1)
{

DelayMs(1);
CANCSUP;
DelayUs(1);
CANCSDW; // 片选拉低

SPISendByte(0xa0); // 读指令
//SPISendByte(0x66); // 地址
//SPISendByte(0x00); // 写空操作,产生SCK时钟
ret = SPIRecvByte(); // 读数据

CANCSUP;
NOP();
DelayUs(1);
}
}

调试了一段时间,遇到了问题,我是mega16+MCP2515..用的模拟SPI。。在测试回环模式时候,我写入数据之后,然后在读数据。。SCK,cs,SI.SO引脚上都有波形。但是读处理的全不是FF。。不知道什么原因?源程序代码如上:


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:物联网改变世界,提高生活品质!

342

主题

1189

帖子

6

粉丝