MCP2515调试笔记(一)

MCP2515调试笔记(一)MSP430 MCP2515 调试笔记 一 nbsp nbsp nbsp nbsp MCP 是 MricoChip 公司生产的一款独立 CAN 控制器 相比恩智浦公司的 SJA1000 它的主要特点是与微控制器之间通过 SPI 方式进行数据交换而不是 SJA1000 的并行方式 这样可以大大减少引脚数量 但在一定程度上也增加了软件的编写复杂度 nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp nbsp 本次调试的硬件环境 MSP430F169 MCP2

MSP430 + MCP2515调试笔记(一)

        MCP是MricoChip 公司生产的一款独立CAN控制器,相比恩智浦公司的SJA1000,它的主要特点是与微控制器之间通过SPI方式进行数据交换而不是SJA1000的并行方式,这样可以大大减少引脚数量,但在一定程度上也增加了软件的编写复杂度。        

        本次调试的硬件环境:MSP430F169+MCP2515+TJA1050,调试助手为瑞士Kvaser的USBCANII。软件环境为:IAR5.30.1,Kvaser CanKing5.0.2。由于之前已经将MSP430与MCP2515之间的SPI通信调通(包括硬件外设和软件模拟两种方式),因此本次调试目的主要为:调通MCP2515的发送功能。

主要程序步骤如下:

1、初始化时钟     ClockInt();

 BCSCTL2 |= SELM1 + DIVS1 + DIVS0 + SELS; // MCLK为XT2,8MHz; SMCLK为XT2,8分频,1MHz

2、初始化SPI外设  SPIInt();

 U0CTL= CHAR + SYNC + MM + SWRST; // 8位SPI, 主机模式 U0TCTL= CKPL + SSEL1 + SSEL0 + STC; // 子时钟,1MHz;3线模式 下降沿准备,上升沿输出

其中,SPI的时钟设置这块,MSP430的手册上有一定的问题,必须根据MCP32515的SPI时钟来进行匹配,最好用示波器同时读取SCK和SDA两个数据进行观察后确定。

3、MCP2515软复位  MCP2515_SoftReset();

4、进入配置模式,配置MCP2515的CAN通信波特率为100KHz;

 MCP2515_WriteReg(CANCTRL,OPMOD_CONFIG); //config mode 配置模式 / /PRSEG + SJW + PS1 + PS2 = 1 + 2 + 3 + 4; MCP2515_WriteReg(MCP_CNF1, 0x03); // SJW = 1*TO; BRP=3 TQ = 2*(BRP+1)/FOSC MCP2515_WriteReg(MCP_CNF2, 0x91); // PS1 = 3*TQ; RSEG= 2*T MCP2515_WriteReg(MCP_CNF3, 0x03); // PS2 = 4*TQ; MCP2515_WriteReg(MCP_TXRTSCTRL , 0x00); //Disable RTS PINs MCP2515_WriteReg(CANCTRL, OPMOD_NORMAL); //config mode 普通模式

5、初始化发送寄存器

 MCP2515_InitCANBuffers(); //清空14个发送寄存器1+4+1+8

6、写14个发送寄存器 

 MCP2515_WriteReg(MCP_TXB0CTRL,0x03); //设置为发送最高优先级 MCP2515_WriteReg(MCP_TXB0SIDH,0xff); // SID10--SID3 MCP2515_WriteReg(MCP_TXB0SIDL,0x00); //SID2--SID0 MCP2515_WriteReg(MCP_TXB0DLC, 8); // 发送数据长度为8 字节 MCP2515_WriteReg(MCP_TXB0D0,0x01); // 发送的数据88 MCP2515_WriteReg(MCP_TXB0D1,0x02); // 发送的数据88 MCP2515_WriteReg(MCP_TXB0D2,0x03); // 发送的数据88 MCP2515_WriteReg(MCP_TXB0D3,0x04); // 发送的数据88 MCP2515_WriteReg(MCP_TXB0D4,0x05); // 发送的数据88 MCP2515_WriteReg(MCP_TXB0D5,0x06); // 发送的数据88 MCP2515_WriteReg(MCP_TXB0D6,0x07); // 发送的数据88 MCP2515_WriteReg(MCP_TXB0D7,0x08); // 发送的数据88

7、等待发送完毕

while((MCP2515_ReadReg(MCP_TXB0CTRL) & 0x08) == 0x08); //等待发送完毕

在上述步骤中,有以下几个注意点:

1、在SPI调通的基础上,MCP软复位后要对读取CANSTAT寄存器的值以保证系统在复位后默认进入了配置模式,如果不放心,可以对CANSTAT写OPMOD_CONFIG。

2、根据数据手册CNF1、CNF2、CNF3、MCP_TXRTSCTRL必须在配置模式下才能修改。

由于MCP的竞争使用的是8MHz,CAN的波特率选择100KHz,因此需要对8MHz进行

预分频,BRP=3 ,TQ =2*(BRP+1)/FOSC = 1us。一个时钟周期相当于10个TQ。为此将

SJW=1 ,PRSEG = 2,PS1=3,PS3=4。

这里犯了个低级错误,在对CNF写的时候由于直接用复制粘贴,导致波特率设置错误,最后还是通过示波器一位一位的比对才发现波特率设置错误,经校查才发现CNF3写成了CNF1,浪费了一晚上的时间,但是对CAN的数据链路层有了更深的了解,比如在数据位如果大于等于连续5个相同位的情况,CAN控制器将自动添加一个相反位,接收时自动摈弃掉,这也是为了区分帧头和帧尾。

3、第7步中的程序原来写成如下:

     MCP2515_RTS(0x01);//请求发送

     temp= MCP2515_ReadReg(MCP_TXB0CTRL);

     while((temp & 0x08) == 0x08); //等待发送完毕

    发现发送数据时只能发送一次,之后一直在做while循环,temp的值一直是11,TXB0CTRL寄存器中标志数据缓冲区的位bit 3 TXREQ一直为1。数据虽然已经发出去,但是程序显示该位并未清零。

    经仔细分析,上述程序的写法有误,temp是一个临时变量,执行temp= MCP2515_ReadReg(MCP_TXB0CTRL);后该值保持不变,而该语句直接在请求发送语句之后,我们知道数据发送是要一定时间的,当数据还未发送完毕,TXREQ的值自然为1,此时如果去读temp的值,则必然为1,与时while循环一直跳不出来。但是如果改成现在的形式,将查询TXREQ值的语句放在while循环中,则只要缓冲区发送完毕,便能查询到TXREQ值为0,可以跳出循环。根本的原因是微控制器和can控制器未能很好的同步。

     

     总结:经过一天多的时间才将该模块正式调通,期间碰到的两个低级错误浪费了大把时间,主要原因还是程序编写的粗心和对程序逻辑理解的不深刻造成的。希望以后引以为戒编程时切忌图快,逻辑必须要清晰。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/212615.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午7:39
下一篇 2026年3月18日 下午7:40


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号