关于S12ZVM128的MSCAN配置

 mascan.h

#ifndef MASCAN_H_ 

#define MASCAN_H_

#include "derivative.h"

#include "typedefs.h"

#include "SWLIBS_Typedefs.h"  //定义mascan.h和其包含的头文件

#endif /* MASCAN_H_ */

struct can_msg    //can信号结构体定义

{

    unsigned int id;            //标准帧id

    unsigned char RTR;             //RTR:1位远程帧,0为数据帧

    unsigned char data[8];        //帧数据

    unsigned char len;              //数据长度

    unsigned char prty;             //优先级

};

extern struct can_msg  msg;

extern struct can_msg  RecvMsg;     //头文件声明

void InitCAN(void);

int MSCAN0_Send(struct can_msg msg);

int MSCAN0_Receive(struct can_msg *msg);

void Can0_Send_TX23A_data(void);

void Can0_Send_TX23B_data(void);

void Can0_Send_TX23C_data(void);

void Can0_Send_TX23D_data(void);

void Can0_Send_TX23E_data(void);

void Can0_Receive_RX361_data(struct can_msg *msg);

void Can0_Receive_RX362_data(struct can_msg *msg);

void Can0_Receive_RX363_data(struct can_msg *msg);

void Can0_Receive_RX364_data(struct can_msg *msg);

void Can0_Receive_RX365_data(struct can_msg *msg);

extern int Testdata;                                         //变量的定义

extern unsigned char Useer_LED1;

extern unsigned char Useer_LED2;

extern unsigned char Motor_Run;

extern tFrac16 RequiredSpeed;

extern volatile  uint8_t RotDir;

/*

 * mascan.c

#include <hidef.h>

#include "derivative.h"   //mascan.c包含的头文件

#include "typedefs.h"

#include "SWLIBS_Typedefs.h"

#include "mascan.h"           //该文件运行的头文件

struct can_msg  msg;     //can信号发送接收定义

struct can_msg  RecvMsg;

int Testdata = 60;

unsigned char Useer_LED1 = 0;

unsigned char Useer_LED2 = 0;   //所需要使用的变量定义

unsigned char Motor_Run;

tFrac16 RequiredSpeed;

volatile  uint8_t RotDir;

can功能模块初始化;

CANCTL0寄存器:查询是否进入初始化状态;离开初始化状态,返回正常运行模式

当初始化模式处于有效的时候(INITRQ = 1 和 INITAK = 1)时,除WUPE,INITRQ和SLPRQ外的所有CANCTL0寄存器位都处于复位状态。只要退出初始化模式(INITRQ = 0,INITAK = 0),该寄存器可以再次写入。

 

CANBTR0,CANBTR1寄存器:设置波特率

CANBTR0,CANBTR1:配置MSCAN模块的各种CAN总线计时参数

CANIDMR寄存器:设置相应CAN口滤波器

这个是标识符掩码寄存器,指定标识符寄存器中的哪些相应位与接收过滤比较。我们选择关闭滤波器,全接收。

CANCTL1寄存器:使能MSCAN模块,设置MSCAN时钟源

这个模块提供了MSCAN模块的各种控制位和握手状态报文。

CANRIER寄存器:设置接收中断使能

该寄存器包含用于CANRELG寄存器中描述的中断标志的中断使能位。

128板子外部时钟源8Mhz,配置为内部时钟源为25Mhz(CAN0BTR1 = 0x16)

Bti Time = ×(1 + Time Segment1 + TimeSegment2)

Tsg1 为2个时间量子,Tsg2为7个时间量子,CAN总线时钟为25MHZ

CAN0BTR0_BRP = 4;//预分频因子为5

Bit Time = 2

则MSCAN波特率为500kHz

void InitCAN(void)

{

       CAN0CTL1_CANE = 1;       //mscan使能

       if(CAN0CTL0_INITRQ==0)    //查询是否进入初始化

              CAN0CTL0_INITRQ =1;   //进入初始化状态

       while (CAN0CTL1_INITAK==0); //等待进入初始化状态

       CAN0BTR0_SJW = 1;  //设置同步

       CAN0BTR0_BRP = 4;  //设置波特率,预分频因子为5

       CAN0BTR1 = 0x16;   // Tsg1 为2个时间量子,Tsg2为7个时间量子,CAN总线时钟为25MHZ,MSCAN波特率为500kHz

        //关闭滤波器                 

       CAN0IDMR0 = 0xFF;

       CAN0IDMR1 = 0xFF;

       CAN0IDMR2 = 0xFF;

       CAN0IDMR3 = 0xFF;

       CAN0IDMR4 = 0xFF;

    CAN0IDMR5 = 0xFF;

       CAN0IDMR6 = 0xFF;

       CAN0IDMR7 = 0xFF;     

       CAN0CTL1 = 0xC0;  //MSCAN模块使能,定义MSCAN时钟源为总线时钟          

       CAN0CTL0 = 0x00;   //返回到正常运行模式       

       while(CAN0CTL1_INITAK);     //等到回到一般运行模式

       while(CAN0CTL0_SYNCH==0);   //等待总线时钟同步

       CAN0RIER_RXFIE = 0;       //使能接收中断

}

//发送函数

检查数据长度,检查时钟,寻找空闲缓冲器,写入标识符(CANIDR寄存器),判断帧类型(CANIDR寄存器),写入数据(CANDSR寄存器),写入数据长度(CANDLR寄存器),写入优先级(CANTBPR寄存器),清除发送标志位(CANTFLG寄存器)

标准帧发送

int MSCAN0_Send(struct can_msg msg)

{

       unsigned char send_buf, sp;

       if(msg.len > 8)

    return(FALSE);

       if(CAN0CTL0_SYNCH==0)

    return(FALSE);  //如果发送字节的长度和MSCAN时钟未同步到总线时钟,返回错误值。

       send_buf = 0;

    CAN0TBSEL=CAN0TFLG;   //寻找空闲的缓冲器

    send_buf=CAN0TBSEL;

    CAN0TXIDR0 = (unsigned char)(msg.id>>3);  //写入标识符

    CAN0TXIDR1 = (unsigned char)(msg.id<<5);

    if(msg.RTR)    //RTR:1为远程帧,0为数据帧

    CAN0TXIDR1 |= 0x10;

    for(sp = 0; sp < msg.len; sp++)   //开始写入数据

    *((&CAN0TXDSR0)+sp) = msg.data[sp];

    CAN0TXDLR = msg.len;     //写入数据长度

    CAN0TXTBPR = msg.prty;          //写入优先级

    CAN0TFLG = send_buf;               //清除TXx标志(缓冲器准备发送)

    return(TRUE);

}

CAN接收函数:

MSCAN接收的过程

检查接收标志:CANRFLG寄存器

检查帧模式(标准帧,扩展帧):CANIDR寄存器

读标识符:CANIDR寄存器

判断帧格式(远程帧,数据帧):CANIDR寄存器

读取数据长度:CANDLR寄存器

读取数据:CANDSR寄存器

清楚接收标志位:CANTFLG寄存器

CANIDR寄存器有两种型式:标准帧型式和扩展帧型式

CANDLR寄存器(数据长度寄存器):保存CAN帧的数据长度字段

CANDSR寄存器(数据段寄存器0-7):8个数据段寄存器(每个都带有位DB[7:0])包含将要发送或接收的数据。将要发送或接收的字节数有相应DLR寄存器中的数据长度代码决定。

CANTFLG寄存器(MSACAN发送器标志寄存器):每发送缓冲器空标志在CANTIRER寄存器中都有相应的中断使能位。

int MSCAN0_Receive(struct can_msg *msg)

{

       unsigned char sp2;

       if(!(CAN0RFLG_RXF))   //检测接收标志

    return(FALSE);

       if(CAN0RXIDR1_IDE)    //检测CAN协议报文模式(一般,扩展)标识符号;0为标准格式,1为扩展格式

return(FALSE);

//读标识符号

       msg->id = (unsigned int)(CAN0RXIDR0<<3)|(unsigned char)(CAN0RXIDR1>>5);

       if(CAN0RXIDR1&0x10)

    msg->RTR = TRUE;

       else

    msg->RTR = FALSE;

       msg->len = CAN0RXDLR;          //读取数据长度

       for(sp2 = 0; sp2 < msg->len; sp2++)       //读取数据

    msg->data[sp2] = *((&CAN0RXDSR0)+sp2);

       CAN0RFLG = 0x01;      //清除RXF标志位(缓冲器准备接收)

       return(TRUE);

}

//发送处理函数

//增加发送id

/*******************************ID:0x23A*************************************/

void Can0_Send_TX23A_data(void)   

{

       unsigned char data[8]={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};

       msg.id = 0x23A;   //id名称

       msg.RTR = 0;        //为数据帧

       msg.len = 8;         //数据长度为8

       //给对应的数据赋值

       msg.data[0] = (unsigned char) data[0];

       msg.data[1] = (unsigned char) data[1];

       msg.data[2] = (unsigned char) data[2];

       msg.data[3] = (unsigned char) data[3];

       msg.data[4] = (unsigned char) data[4];

       msg.data[5] = (unsigned char) data[5];

       msg.data[6] = (unsigned char) data[6];

       msg.data[7] = (unsigned char) data[7];

      

       msg.prty=0;   //设置优先级

      

       MSCAN0_Send(msg);   //将以上设置的数据发送出去

}

//CAN接收处理函数:

//增加接收id

/*******************************ID:0x361*************************************/

void Can0_Receive_RX361_data(struct can_msg *msg)

{

       if(msg->id == 0x361)  //对361这个id的数据进行处理

       {

              Motor_Run=msg->data[0];   //对应第0位控制Motor Run

       RequiredSpeed=msg->data[1]*256 + msg->data[2]; //第2,3位控制RequiredSpeed

              RotDir = msg->data[3];

    }

}

因为是做项目的时候的一个总结,在这个开发的过程中也遇到了很多的问题,一开始选用的是一块256的开发板,看网上也没有太多s12z系列芯片的开发内容,查资料花了很多的时间,希望这篇文章对你们有用,有想起来了的会几十更改的。新手,有错请见谅,告诉我及时改错。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
CAN驱动软件设计及功能测试是针对S12ZVM(Motorola 16位微控制器)的CAN总线驱动软件进行设计和测试的过程。这个软件可以实现CAN通讯协议的解析和交互,使得不同的模块和设备可以在CAN总线上进行数据的传递和通讯。 在进行CAN驱动软件设计时,需要首先进行CAN总线控制器的初始化设置,包括波特率的配置、过滤器的设置和中断的处理等。然后需要设计CAN消息的发送和接收功能,包括数据的打包和解析以及错误处理等。另外,还需要考虑到CAN总线的唤醒功能、自动重传机制和错误处理等功能的设计。 在进行功能测试时,需要对CAN驱动软件的各个功能进行测试,包括消息的发送和接收功能、错误处理功能、唤醒功能和中断处理等。测试时需要模拟不同的情况,包括正常的数据传输、异常情况下的错误处理和重传机制等。同时还需要进行对接收到的CAN消息进行解析和验证,确保数据的正确性和可靠性。 在进行CAN驱动软件设计及功能测试时,需要充分考虑到硬件平台的特性和应用场景的需求,保证软件可以稳定可靠地运行并满足实际应用的需求。同时还需要关注软件的性能和资源占用情况,确保软件在有限的资源下能够高效地运行。通过设计和测试CAN驱动软件,可以实现系统中不同模块和设备之间的数据通讯,为实际应用提供可靠的数据交互通道。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值