📄 sja1000.c
字号:
#include "STC89C51RC_RD_PLUS.H"
#include <absacc.h> //用到XBYTE
#include <intrins.h> //用到_nop_();
//宏定义
#define TRUE 1
#define FALSE 0
#define CAN_MODE_BASICCAN 0
#define CAN_MODE_PELICAN 1
#define CAN_CONF_TIMEOUT 10 //10ms
#define CAN_MODE CAN_MODE_PELICAN //第一步设置CAN_MODE,选择BasicCan,还是PeliCan?
#define CAN_CONTROL_SET_BAUDRATE 100 //在CAN_Control函数中用到
#define CAN_CONTROL_SET_ACR 101
#define CAN_CONTROL_SET_AMR 102
#define CAN_CONTROL_SET_SLEEP 103
//STC内部EEPROM使用有关的宏定义
#define ISP_Byte_Read 1
#define ISP_Byte_Program 2
#define ISP_Sector_Erase 3
#define Wait_Time 2; // 3 对应5M时钟 , 2 对应10M时钟 ,1 对应20M时钟, 0 对应40M时钟
#define SECTOR1_BTR0_H 0x20 //第一扇区首地址,存放BTR0 注意不同的STC单片机首地址不一样。
#define SECTOR1_BTR0_L 0x00
#define SECTOR1_BTR1_H 0x20 //第一扇区第二个地址,存放BTR1
#define SECTOR1_BTR1_L 0x01
#define SECTOR2_ACR0_H 0x22 //第二扇区首地址, 存放ACR0
#define SECTOR2_ACR0_L 0x00
#define SECTOR2_ACR1_H 0x22 //第二扇区第二个地址,存放ACR1
#define SECTOR2_ACR1_L 0x01
#define SECTOR2_ACR2_H 0x22 //第二扇区第三个地址,存放ACR2
#define SECTOR2_ACR2_L 0x02
#define SECTOR2_ACR3_H 0x22 //第二扇区第四个地址,存放ACR3
#define SECTOR2_ACR3_L 0x03
#define SECTOR3_AMR0_H 0x24 //第三扇区首地址, 存放AMR0
#define SECTOR3_AMR0_L 0x00
#define SECTOR3_AMR1_H 0x24 //第三扇区第二个地址,存放AMR1
#define SECTOR3_AMR1_L 0x01
#define SECTOR3_AMR2_H 0x24 //第三扇区第三个地址,存放AMR2
#define SECTOR3_AMR2_L 0x02
#define SECTOR3_AMR3_H 0x24 //第三扇区第四个地址,存放AMR3
#define SECTOR3_AMR3_L 0x03
#define RX_BUFF_LEN 32 // CAN接收缓冲区大小
#define TX_BUFF_LEN 32 // CAN发送缓冲区大小
//CAN用到的缓冲区
unsigned char idata RX_BUFF[RX_BUFF_LEN]; // 接收缓冲区 0~RX_BUFF_LEN-1
unsigned char idata TX_BUFF[TX_BUFF_LEN]; // 发送缓冲区 0~TX_BUFF_LEN-1
unsigned int idata TX_Buff_Head = 0; // 头指针,写入
unsigned int idata TX_Buff_Tail = 0; // 尾指针,读出
unsigned int idata RX_Buff_Head = 0; //
unsigned int idata RX_Buff_Tail = 0; //
//UART用到的缓冲区
#define UART_RX_Buff_LEN 24
#define UART_TX_Buff_LEN 24
unsigned char idata UART_RX_Buff[UART_RX_Buff_LEN]; // 接收缓冲区
unsigned char idata UART_TX_Buff[UART_TX_Buff_LEN]; // 发送缓冲区
unsigned int idata UART_RX_Buff_Head = 0; // 头指针,写入
unsigned int idata UART_RX_Buff_Tail = 0; // 尾指针,读出
unsigned int idata UART_TX_Buff_Head = 0; //
unsigned int idata UART_TX_Buff_Tail = 0; //
#define SJA_REG_BaseADD 0x1000 //这么选择的原因? P2^6=1? 应该与片选有关
#define REG_MODE XBYTE[SJA_REG_BaseADD + 0x00] //内部控制寄存器
#define REG_CMR XBYTE[SJA_REG_BaseADD + 0x01] //命令寄存器
#define REG_SR XBYTE[SJA_REG_BaseADD + 0x02] //状态寄存器
#define REG_IR XBYTE[SJA_REG_BaseADD + 0x03] //中断寄存器
#define REG_IR_ABLE XBYTE[SJA_REG_BaseADD + 0x04] //中断使能寄存器
//05保留 不用管
#define REG_BTR0 XBYTE[SJA_REG_BaseADD + 0x06] //总线定时寄存器0
#define REG_BTR1 XBYTE[SJA_REG_BaseADD + 0x07] //总线定时寄存器1
#define REG_OCR XBYTE[SJA_REG_BaseADD + 0x08] //输出控制寄存器
#define REG_TEST XBYTE[SJA_REG_BaseADD + 0x09] //测试寄存器
//0a保留 不用管
#define REG_ALC XBYTE[SJA_REG_BaseADD + 0x0b] //仲裁丢失捕捉寄存器
#define REG_ECC XBYTE[SJA_REG_BaseADD + 0x0c] //错误代码捕捉寄存器
#define REG_EMLR XBYTE[SJA_REG_BaseADD + 0x0d] //错误报警限制寄存器
#define REG_RXERR XBYTE[SJA_REG_BaseADD + 0x0e] //RX 错误计数寄存器
#define REG_TXERR XBYTE[SJA_REG_BaseADD + 0x0f] //TX 错误计数寄存器
#define REG_ACR0 XBYTE[SJA_REG_BaseADD + 0x10]
#define REG_ACR1 XBYTE[SJA_REG_BaseADD + 0x11]
#define REG_ACR2 XBYTE[SJA_REG_BaseADD + 0x12]
#define REG_ACR3 XBYTE[SJA_REG_BaseADD + 0x13]
#define REG_AMR0 XBYTE[SJA_REG_BaseADD + 0x14]
#define REG_AMR1 XBYTE[SJA_REG_BaseADD + 0x15]
#define REG_AMR2 XBYTE[SJA_REG_BaseADD + 0x16]
#define REG_AMR3 XBYTE[SJA_REG_BaseADD + 0x17]
#define REG_RxBuffer0 XBYTE[SJA_REG_BaseADD + 0x10]
#define REG_RxBuffer1 XBYTE[SJA_REG_BaseADD + 0x11]
#define REG_RxBuffer2 XBYTE[SJA_REG_BaseADD + 0x12]
#define REG_RxBuffer3 XBYTE[SJA_REG_BaseADD + 0x13]
#define REG_RxBuffer4 XBYTE[SJA_REG_BaseADD + 0x14]
#define REG_TxBuffer0 XBYTE[SJA_REG_BaseADD + 0x10]
#define REG_TxBuffer1 XBYTE[SJA_REG_BaseADD + 0x11]
#define REG_TxBuffer2 XBYTE[SJA_REG_BaseADD + 0x12]
#define REG_TxBuffer3 XBYTE[SJA_REG_BaseADD + 0x13]
#define REG_TxBuffer4 XBYTE[SJA_REG_BaseADD + 0x14]
#define REG_DataBuffer1 XBYTE[SJA_REG_BaseADD + 0x15]
#define REG_DataBuffer2 XBYTE[SJA_REG_BaseADD + 0x16]
#define REG_DataBuffer3 XBYTE[SJA_REG_BaseADD + 0x17]
#define REG_DataBuffer4 XBYTE[SJA_REG_BaseADD + 0x18]
#define REG_DataBuffer5 XBYTE[SJA_REG_BaseADD + 0x19]
#define REG_DataBuffer6 XBYTE[SJA_REG_BaseADD + 0x1a]
#define REG_DataBuffer7 XBYTE[SJA_REG_BaseADD + 0x1b]
#define REG_DataBuffer8 XBYTE[SJA_REG_BaseADD + 0x1c]
#define REG_RBSA XBYTE[SJA_REG_BaseADD + 0x1e] //RX缓冲器起始地址寄存器
#define REG_CDR XBYTE[SJA_REG_BaseADD + 0x1f] //时钟分频寄存器
#define REG_Receive_Counter XBYTE[SJA_REG_BaseADD + 0x1d] //RX信息计数器(RMC)
sbit CAN_RST = P4^0; //复位控制
sbit CAN_INT= P3^2; //中断脚
struct CAN_CANConfig {
unsigned char Mode; //bit0: 0:basicCAN 1:peleican
//bit1: 0: 双滤波 1:单滤波
//bit2: 0: 标准帧 1:扩展帧
unsigned char BTR0; //波特率
unsigned char BTR1; //波特率
unsigned char ACR0; //验收代码
unsigned char ACR1; //验收代码
unsigned char ACR2; //验收代码
unsigned char ACR3; //验收代码
unsigned char AMR0; //屏蔽代码
unsigned char AMR1; //屏蔽代码
unsigned char AMR2; //屏蔽代码
unsigned char AMR3; //屏蔽代码
unsigned char EFF0; //发送识别码,标准帧只用前两个
unsigned char EFF1; //发送识别码,标准帧只用前两个
unsigned char EFF2; //发送识别码,标准帧只用前两个
unsigned char EFF3; //发送识别码,标准帧只用前两个
};
struct CAN_CANConfig CANConfig;
#define RESET_SJA1000() {CAN_RST = 0; _nop_(); CAN_RST = 1;}
#define ON_CAN_INT() {EX0 = 1;}
#define OFF_CAN_INT() {EX0 = 0;}
//函数声明
bit send(unsigned char S_Data);
bit Serial(void);
void Delay1ms(unsigned int i);
bit CAN_Init(void);
/*
unsigned char EEPROM_Read(unsigned char AddrH,unsigned char AddrL);
void EEPROM_Write(unsigned char AddrH,unsigned char AddrL,unsigned char Data);
void Sector_Erase(unsigned char AddrH,unsigned char AddrL);
*/
/******************************************************************
延时1ms
*/
void Delay(unsigned int i)
{
while (i--)
{
};
}
/*
返回实际读取到的数据
*/
unsigned int CAN_Read(unsigned char *Buf,unsigned int MaxNum)
{
unsigned int Count = 0;
OFF_CAN_INT();
while (MaxNum--)
{
if (RX_Buff_Tail == RX_Buff_Head)
{//没有数据了
break;
}
*Buf++ = RX_BUFF[RX_Buff_Tail++];
if(RX_Buff_Tail == RX_BUFF_LEN )
RX_Buff_Tail = 0; // 指针循环
Count++;
}
ON_CAN_INT();
return Count;
}
/*
返回实际读取到的数据
*/
unsigned int UART_Read(unsigned char *Buf,unsigned int MaxNum)
{
unsigned int Count = 0;
ES = 0;
while (MaxNum--)
{
if (UART_RX_Buff_Tail == UART_RX_Buff_Head)
{//没有数据了
break;
}
*Buf++ = UART_RX_Buff[UART_RX_Buff_Tail++];
if(UART_RX_Buff_Tail == UART_RX_Buff_LEN )
UART_RX_Buff_Tail = 0; // 指针循环
Count++;
}
ES = 1;
return Count;
}
bit UART_Send(unsigned char *DataBuf,unsigned int Num)
{
unsigned int len;
bit Flag = 0;
unsigned char i;
//计算发送缓冲区的剩余大小
do {
ES = 0;
if( UART_TX_Buff_Head < UART_TX_Buff_Tail)
{
len = UART_TX_Buff_Tail - UART_TX_Buff_Head;
}
else
{
len =UART_TX_Buff_LEN - UART_TX_Buff_Head + UART_TX_Buff_Tail;
}
ES = 1;
if (len >= Num)
{//有空间发送多余的数据
break;
}
Delay(100);
i++;
} while(i< 200);
if (i>199)
{
return FALSE;
}
//讲数据放到发送缓冲区
ES = 0;
if( UART_TX_Buff_Head == UART_TX_Buff_Tail)
Flag = 1;
for(len=0; len<Num; len++)
{
UART_TX_Buff[UART_TX_Buff_Head++]=DataBuf[len];
if(UART_TX_Buff_Head == UART_TX_Buff_LEN )
UART_TX_Buff_Head = 0; // 指针循环
}
ES = 1;
if (Flag == 1)
{
TI = 1;
}
}
/****************************************************************************
发送函数
参数:*Buf是某个数组名。这个数组一般是xdata型的。例如a[20],CAN_Send(a,20)。Num是发送数据的个数(小于160)。
返回:
注:"如果缓冲区可以容纳这么多直接填充,如果缓冲区满的话等待之.发送前把发送中断直接打开"
*/
bit CAN_Send(unsigned char *DataBuf,unsigned int Num)
{
unsigned char i;
unsigned int len;
unsigned char *p;
//计算发送缓冲区的剩余大小
i = 0;
do {
OFF_CAN_INT(); //关闭CAN中断
if( TX_Buff_Head < TX_Buff_Tail)
{
len = TX_Buff_Tail - TX_Buff_Head;
}
else
{
len =TX_BUFF_LEN - TX_Buff_Head + TX_Buff_Tail;
}
ON_CAN_INT();
if (len >= Num)
{//有空间发送多余的数据
break;
}
Delay(10);
i++;
} while(i< 200);
if (i>199)
{
return FALSE;
}
//讲数据放到发送缓冲区
OFF_CAN_INT();
for(len=0; len<Num; len++)
{
TX_BUFF[TX_Buff_Head++]=DataBuf[len];
if(TX_Buff_Head == TX_BUFF_LEN )
TX_Buff_Head = 0; // 指针循环
}
i = REG_SR;
p = (unsigned char xdata *)(SJA_REG_BaseADD + 0x15);
if ((i & 0x04) == 0x04)
{//发送缓冲区处于释放状态时,可以将部分数据发送出去
i = 0;
do {
p[i] = TX_BUFF[TX_Buff_Tail++];
i++;
if(TX_Buff_Tail == TX_BUFF_LEN )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -