📄 mcp2510.c
字号:
/************************************************************************************\
MCP2510 CAN总线试验演示程序2003.10
\************************************************************************************/
//#include "44b.h"
#include "inc/EXIO.h"
#include "inc/MCP2510.h"
/********************** MCP2510 Pin *********************************/
#define MCP2510_CS 0x4 //EXIO2
/********************** MCP2510 Instruction *********************************/
#define MCP2510INSTR_RESET 0xc0 //复位指令
#define MCP2510INSTR_READ 0x03 //读取指令
#define MCP2510INSTR_WRITE 0x02 //写入指令
#define MCP2510INSTR_RTS 0x80 //request to send,发送请求指令
#define MCP2510INSTR_RDSTAT 0xa0 //read status,读取状态指令
#define MCP2510INSTR_BITMDFY 0x05 //bit modify,修改位指令
#define GPHDAT (*(volatile unsigned char *)0x56000074)
#define FILTER_MASK 0x1f
//#define MCP2510_Enable() do{CLREXIOBIT(MCP2510_CS);}while(0)
//#define MCP2510_Disable() do{SETEXIOBIT(MCP2510_CS); hudelay(1);}while(0)
#define MCP2510_Enable() GPHDAT=GPHDAT&0x7fe
#define MCP2510_Disable() GPHDAT=GPHDAT|0x01
void MCP2510_Reset()
{
MCP2510_Enable();//打开MCP2510
//SendSIOData(MCP2510INSTR_RESET);
SPISend ( MCP2510INSTR_RESET, 0 );
MCP2510_Disable();//关闭MCP2510
}
/*单字节写入函数*/
void MCP2510_Write(int address, int value)
{
MCP2510_Enable();//打开MCP2510
//SendSIOData(MCP2510INSTR_WRITE);
//SendSIOData((unsigned char)address);
//SendSIOData((unsigned char)value);
SPISend ( MCP2510INSTR_WRITE, 0 ); //发送写指令
SPISend ((unsigned char)address, 0 ); //指定寄存器地址
SPISend ((unsigned char)value, 0 ); //写入数据
MCP2510_Disable();
}
/*************************************************************************\
读取函数
arg:address,寄存器地址
*************************************************************************/
unsigned char MCP2510_Read(int address)
{
unsigned char result;
MCP2510_Enable(); //开启MCP2510
//SendSIOData(MCP2510INSTR_READ);
//SendSIOData((unsigned char)address);
//SendSIOData(0);
//result=ReadSIOData();
SPISend ( MCP2510INSTR_READ, 0 ); //发送读取指令
SPISend ( (unsigned char)address, 0 ); //指定寄存器地址
SPISend ( 0, 0 );
result=SPIRecv (0); //接收数据
MCP2510_Disable(); //关闭MCP2510
return result;
}
/*************************************************************************\
读取状态函数
*************************************************************************/
unsigned char MCP2510_ReadStatus()
{
unsigned char result;
MCP2510_Enable(); //开启MCP2510
//SendSIOData(MCP2510INSTR_RDSTAT);
SPISend ( MCP2510INSTR_RDSTAT, 0 );//读取状态
//SendSIOData(0);
SPISend ( 0, 0 ); //为何发送空命令
//result=ReadSIOData();
result=SPIRecv (0); //接受状态数据
MCP2510_Disable(); //关闭MCP2510
return result;
}
/***************************修改位指令函数**********************************\
arg: address,寄存器地址;mask,屏蔽位;data,修改数据
*****************************************************************************/
void MCP2510_WriteBits( int address, int data, int mask )
{
MCP2510_Enable();
//SendSIOData(MCP2510INSTR_BITMDFY);
//SendSIOData((unsigned char)address);
//SendSIOData((unsigned char)mask);
//SendSIOData((unsigned char)data);
SPISend ( MCP2510INSTR_BITMDFY, 0 ); //发送位修改指令
SPISend ((unsigned char)address, 0 ); //设置寄存器地址
SPISend ((unsigned char)mask, 0 ); //发送屏蔽位
SPISend ((unsigned char)data, 0 ); //修改数据
MCP2510_Disable();
}
/*************************MCP2510波特率设置函数******************\
arg: andrate,波特率; IsBackNormal,是否环回测试
****************************************************************/
void MCP2510_SetBandRate(CanBandRate bandrate, BOOL IsBackNormal)
{
//
// Bit rate calculations.
//
//Input clock fre=16MHz
// In this case, we'll use a speed of 125 kbit/s, 250 kbit/s, 500 kbit/s.
// If we set the length of the propagation segment to 7 bit time quanta,
// and we set both the phase segments to 4 quanta each,
// one bit will be 1+7+4+4 = 16 quanta in length.
//
// setting the prescaler (BRP) to 0 => 500 kbit/s.
// setting the prescaler (BRP) to 1 => 250 kbit/s.
// setting the prescaler (BRP) to 3 => 125 kbit/s.
//
// If we set the length of the propagation segment to 3 bit time quanta,
// and we set both the phase segments to 1 quanta each,
// one bit will be 1+3+2+2 = 8 quanta in length.
// setting the prescaler (BRP) to 0 => 1 Mbit/s.
// Go into configuration mode
MCP2510_Write(MCP2510REG_CANCTRL, MODE_CONFIG);//MCP2510控制寄存器设置,参见MCP2510手册P52
switch(bandrate){
case BandRate_125kbps:
MCP2510_Write(CNF1, SJW1|BRP4); //Synchronization Jump Width Length =1 TQ,参见MCP2510手册P39
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2510_Write(CNF3, SEG4);// Phase Seg 2 = 4
break;
case BandRate_250kbps:
MCP2510_Write(CNF1, SJW1|BRP2); //Synchronization Jump Width Length =1 TQ
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2510_Write(CNF3, SEG4);// Phase Seg 2 = 4
break;
case BandRate_500kbps:
MCP2510_Write(CNF1, SJW1|BRP1); //Synchronization Jump Width Length =1 TQ
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG4<<3)|SEG7); // Phase Seg 1 = 4, Prop Seg = 7
MCP2510_Write(CNF3, SEG4);// Phase Seg 2 = 4
break;
case BandRate_1Mbps:
MCP2510_Write(CNF1, SJW1|BRP1); //Synchronization Jump Width Length =1 TQ
MCP2510_Write(CNF2, BTLMODE_CNF3|(SEG3<<3)|SEG2); // Phase Seg 1 = 2, Prop Seg = 3
MCP2510_Write(CNF3, SEG2);// Phase Seg 2 = 1
break;
}
if(IsBackNormal){ //是否环回测试
//Enable clock output
MCP2510_Write(CLKCTRL, MODE_NORMAL | CLKEN | CLK1);//设置MCP2510控制寄存器,使能时钟输出,P52
}
}
/*******************************************\
* 序列读取MCP2510数据 *
\*******************************************/
void MCP2510_SRead( int address, unsigned char* pdata, int nlength )
{
int i;
MCP2510_Enable(); //开启MCP2510
//SendSIOData(MCP2510INSTR_READ);
SPISend ( MCP2510INSTR_READ, 0 ); //发送读命令
//SendSIOData((unsigned char)address);
SPISend ((unsigned char)address, 0 ); //发送地址信息
for (i=0; i<nlength; i++) {
//SendSIOData(0);
SPISend (0, 0);
//*pdata=ReadSIOData();
*pdata=SPIRecv(0); //读取数据
pdata++;
}
MCP2510_Disable(); //关闭MCP2510
}
/*******************************************\
* 序列写入MCP2510数据 *
\*******************************************/
void MCP2510_Swrite(int address, unsigned char* pdata, int nlength)
{
int i;
MCP2510_Enable(); //开启MCP2510
//SendSIOData(MCP2510INSTR_WRITE);
SPISend (MCP2510INSTR_WRITE, 0); //发送写命令
//SendSIOData((unsigned char)address);
SPISend ((unsigned char)address, 0); //发送寄存器地址
for (i=0; i < nlength; i++) {
//SendSIOData((unsigned char)*pdata);
SPISend ((unsigned char)*pdata, 0); //写入数据
pdata++;
}
MCP2510_Disable(); //关闭MCP2510
}
/*******************************************\
* 读取MCP2510 CAN总线ID *
* 参数: address为MCP2510寄存器地址*
* can_id为返回的ID值 *
* 返回值 *
* TRUE,表示是扩展ID(29位) *
* FALSE,表示非扩展ID(11位) *
\*******************************************/
BOOL MCP2510_Read_Can_ID( int address, U32* can_id)
{
U32 tbufdata;
unsigned char* p=(unsigned char*)&tbufdata;
MCP2510_SRead(address, p, 4); //读取ID
*can_id = (tbufdata<<3)|((tbufdata>>13)&0x7); //取出ID的高8位和低3位
*can_id &= 0x7ff;
if ( (p[MCP2510LREG_SIDL] & TXB_EXIDE_M) == TXB_EXIDE_M ) { //是否扩展标志符
*can_id = (*can_id<<2) | (p[MCP2510LREG_SIDL] & 0x03);
*can_id <<= 16;
*can_id |= tbufdata>>16;
return TRUE;
}
return FALSE;
}
/***********************************************************\
* 读取MCP2510 接收的数据 *
* 参数: nbuffer为第几个缓冲区可以为3或者4 *
* can_id为返回的ID值 *
* rxRTR表示是否是RXRTR *
* data表示读取的数据 *
* dlc表示data length code *
* 返回值 *
* TRUE,表示是扩展总线 *
* FALSE,表示非扩展总线 *
\***********************************************************/
BOOL MCP2510_Read_Can(U8 nbuffer, BOOL* rxRTR, U32* can_id, U8* data , U8* dlc)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -