这是我调试成功的自检测程序Pelican模式下的 硬件和你的差不多cs接P2.7 Rst接P2.0希望对你有用
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//描述: &
// CAN自收发程序 &
// CAN主要参数: PeliCAN模式,扩展帧EFF模式 &
// 29位标示码结构: &
// 发送数据结构:计数结果,0x02,0x03,0x04,0x05,0x06,0x07,0x08 &
// 接收数据结构: 待显示数据+其它7个字节的数据 &
// 本节点的地址: 0x11,0x22,0x33,0x00;可以接收全部节点的数据 &
// 目的节点地址:0x01,0x02,0x03,0x00;可以被能接收全部节点数据的节点接收 &
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//对管脚分配进行了定义
//对子函数进行了声明
# define uchar unsigned char
# define uint unsigned int
#define N_can 13 //N_can代表一帧字节数
bit TXD_flag = 0; //若TXD_flag=1,要求发送处理
bit RXD_flag = 0; //RXD_flag=0说明无数据可以接收,RXD_flag=1说明有数据可以接收
unsigned char xdata CAN_SJA_BaseAdr; //定义SJA1000的片选基址
unsigned char xdata *SJA_CS_Point;
unsigned char xdata CAN_SJA_BaseAdr _at_ 0x7E00; //定义SJA1000的片选基址
unsigned char xdata *SJA_CS_Point ; //指针指向空
/*P1 口分配*/
/*P2 口分配*/
sbit SJA_RST = P2^0;//SJA1000复位管脚
/*CAN总线SJA1000寄存器地址定义(用的是PeliCAN模式,扩展帧EFF模式)*/
uchar xdata MODR _at_ 0x7E00; // 模式寄存器
uchar xdata CMR _at_ 0x7E01; // 命令寄存器
uchar xdata SR _at_ 0x7E02; // 状态寄存器
uchar xdata IR _at_ 0x7E03; // 中断寄存器
uchar xdata IER _at_ 0x7E04; // 中断使能寄存器
uchar xdata BTR0 _at_ 0x7E06; // 总线定时寄存器0 ;总线波特率的选择
uchar xdata BTR1 _at_ 0x7E07; // 总线定时寄存器1 ;总线波特率的选择
uchar xdata OCR _at_ 0x7E08; // 输出控制寄存器
uchar xdata ACR _at_ 0x7E10;//16;
uchar xdata ACR1 _at_ 0x7E11;//17;
uchar xdata ACR2 _at_ 0x7E12;//18;
uchar xdata ACR3 _at_ 0x7E13;//19; // 接收代码(0x16_0x19);接收过滤位的选择*******复位模式
uchar xdata AMR _at_ 0x7E14;//20;
uchar xdata AMR1 _at_ 0x7E15;//21;
uchar xdata AMR2 _at_ 0x7E16;//22;
uchar xdata AMR3 _at_ 0x7E17;//23; // 掩码(0x20_0x23); 接收过滤位的选择*******复位模式
uchar xdata CDR _at_ 0x7E1F;//31; // 时钟分频器
uchar xdata ALC _at_ 0x7E0B;//11; // 仲裁丢失捕捉寄存器
uchar xdata ECC _at_ 0x7E0C;//12; // 误码捕捉寄存器
uchar xdata TXERR _at_ 0x7E0F;//15; //发送错误计数器
uchar xdata TBSR0 _at_ 0x7E10;//16;
uchar xdata TBSR1 _at_ 0x7E11;//17;
uchar xdata TBSR2 _at_ 0x7E12;//18;
uchar xdata TBSR3 _at_ 0x7E13;//19;
uchar xdata TBSR4 _at_ 0x7E14;//20;
uchar xdata TBSR5 _at_ 0x7E15;//21;
uchar xdata TBSR6 _at_ 0x7E16;//22;
uchar xdata TBSR7 _at_ 0x7E17;//23;
uchar xdata TBSR8 _at_ 0x7E18;//24;
uchar xdata TBSR9 _at_ 0x7E19;//25;
uchar xdata TBSR10 _at_ 0x7E1A;//26;
uchar xdata TBSR11 _at_ 0x7E1B;//27;
uchar xdata TBSR12 _at_ 0x7E1C;//28; // 发送缓冲器首地址(0x16_0x28)
uchar xdata RBSR0 _at_ 0x7E10;//16;
uchar xdata RBSR1 _at_ 0x7E11;//17;
uchar xdata RBSR2 _at_ 0x7E12;//18;
uchar xdata RBSR3 _at_ 0x7E13;//19;
uchar xdata RBSR4 _at_ 0x7E14;//20;
uchar xdata RBSR5 _at_ 0x7E15;//21;
uchar xdata RBSR6 _at_ 0x7E16;//22;
uchar xdata RBSR7 _at_ 0x7E17;//23;
uchar xdata RBSR8 _at_ 0x7E18;//24;
uchar xdata RBSR9 _at_ 0x7E19;//25;
uchar xdata RBSR10 _at_ 0x7E1A;//26;
uchar xdata RBSR11 _at_ 0x7E1B;//27;
uchar xdata RBSR12 _at_ 0x7E1C;//28;// 接收缓冲器首地址(0x16_0x28)
extern void CAN_init(void);
extern void CAN_Tx_data(void);
#include <ADUC812.H>
#include <stdio.h>
#include <intrins.h>
#include <can_selfdef.h>
unsigned char Send_CAN_Info_ID[5]={0x88,0x00,0x00,0x2a,0x00};//扩展帧,8个字节数据,发送数据到ID为00000540的节点
unsigned char Send_CAN_Data[8]={0x23,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
unsigned char RX_buffer[13]; //接收的13个字节数据、
//unsigned char TX_buffer[13]={0x88,0x11,0x22,0x33,0x44,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88} ; //接收的13个字节数据
//unsigned char data rcv_data[8];
unsigned char j=0;
bit flag_sec,rcv_flag,err_flag; //发送,接收,错误中断标志
extern void CAN_Rx_display(void);
extern void CAN_Rx_data( void );
/******************************************************************************/
/* serial_init: initialize serial interface */
/******************************************************************************/
void Serial_Init (void)
{
SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr
PCON |= 0x00 ;//SMOD=1
TMOD &= 0x0F; /*清TMOD高4位 */
TMOD |= 0x20 ; //方式控制:GATE=0;C/T=0;M1M0=10; timer 1, mode 2, 8-bit reload
TH1 = 0xfd ; //Baud: fosc=11.0592MHz ,9600
TL1 = 0xfd ;
TR1 = 1 ; // 启动timer 1 run
TI = 1;
//EA=1;
//ES = 1;
}
char _getkey ()
{
char c;
while (!RI)
c = SBUF;
RI = 0;
return (c);
}
//putchar (basic version): expands '\n' into CR LF */
char putchar (char c)
{
if (c == '\n')
{
while (!TI);
TI = 0;
SBUF = 0x0d;
}
while (!TI);
TI = 0;
return (SBUF = c);
}
///////////////////////////////////////////////
//函数:ex0_int
//说明:中断服务程序
//入口:无
//返回:无
///////////////////////////////////////////////
//***********************************************************
void ex0_int(void) interrupt 0 using 1
{
if(IR&0x01) //产生了接收中断
{
rcv_flag=1;
CAN_Rx_data();
}
if(IR&0x04) //产生了错误中断
{ err_flag=1; }
}
///////////////////////////////////////////////
//函数:main
//说明:主函数
//入口:无
//返回:无
///////////////////////////////////////////////
void main(void)
{
//CPU初始化
SJA_RST = 0;//CAN总线复位管脚,复位有效
Serial_Init();
PX0=1; //外部中断0高优先级
IT0=1; //设置INT0为下降沿中断
EX0=1; //使能INT0中断
EA=1;
SJA_CS_Point=&CAN_SJA_BaseAdr; //设置SJA1000的片选地址
printf( "SJA1000 Init Start!\n");
CAN_init( ); //SJA1000初始化,对 SJA1000寄存器的读写是采用外部寄存器寻址方式,所以不需要程序单独控制片选有效无效
CAN_Tx_data();
printf(" \n \n");
CAN_Rx_display();
while(1);
}
//*********************CAN子函数***********************
void CAN_init( void )
{
uchar i;
uchar bdata Judge;
uchar ACRR[4];
uchar AMRR[4];
ACRR[0] = 0x11;
ACRR[1] = 0x22;
ACRR[2] = 0x33;
ACRR[3] = 0x44;//接收代码寄存器,节点1
AMRR[0] = 0xff;
AMRR[1] = 0xff;
AMRR[2] = 0xff;
AMRR[3] = 0xff;//接收屏蔽寄存器。 只接收主机发送的信息
do
{// .0=1---reset MODRe,进入复位模式,以便设置相应的寄存器
//防止未进入复位模式,重复写入
MODR = 0x09;
Judge = MODR ;
printf( " Judge= %x \n",Judge);
}
while( !(Judge & 0x01) );//等待进入复位模式
CDR = 0x88;// CDR.3=1--时钟关闭, .7=0---basic CAN, .7=1---Peli CAN
BTR0 = 0x00;
BTR1 = 0x14;//总线波特率设定 1000Kbps
printf( " BTR0 = %x \n",BTR0);
printf( " BTR1 = %x \n",BTR1);
IER = 0x01; // .0=1--接收中断使能; .1=0--关闭发送中断使能
OCR = 0xaa; // 配置输出控制寄存器
printf( " OCR = %x \n",OCR);
CMR = 0x04; //释放接收缓冲器
printf( " CMR = %x \n",CMR);
ACR = ACRR[0];
ACR1 = ACRR[1];
ACR2 = ACRR[2];
ACR3 = ACRR[3];//初始化标示码
for(i=0;i<4;i++)
{
printf( " ACR = %x \n" ,ACRR[i]);
}
AMR = AMRR[0];
AMR1 = AMRR[1];
AMR2 = AMRR[2];
AMR3 = AMRR[3];//初始化掩码
for(i=0;i<4;i++)
{
printf( " AMR = %x \n" ,AMRR[i]);
}
do
{//确保进入自接收模式
MODR = 0x04;
Judge = MODR;
printf( " MODR= %x \n",MODR);
}
while( !(Judge & 0x04) );
printf( "SJA1000 Init finish !\n");
printf( "SJA1000 OK !\n");
}
///////////////////////////////////////////////
//函数:CAN_Tx_display
//说明:发送数据串口显示
//入口:无
//返回:无
///////////////////////////////////////////////
void CAN_Tx_display(void)
{
printf( " TBSR5 = %x \n", TBSR5);
printf( " TBSR6 = %x \n", TBSR6);
printf( " TBSR7 = %x \n", TBSR7);
printf( " TBSR8 = %x \n", TBSR8);
printf( " TBSR9 = %x \n", TBSR9);
printf( " TBSR10 = %x \n", TBSR10);
printf( " TBSR11 = %x \n", TBSR11);
printf( " TBSR12 = %x \n", TBSR12);
}
///////////////////////////////////////////////
//函数:can_txd
//说明:发送扩展数据帧
//入口:无
//返回:无
///////////////////////////////////////////////
void CAN_Tx_data(void)
{
uchar state;
uchar TX_buffer[ N_can ] ; //N_can=13,TX_buffer数组为待传送的数据帧
//初始化标示码头信息
TX_buffer[0] = 0x88; //.7=0--扩展帧;.6=0--数据帧; .0-.3=100--数据长度为8字节
TX_buffer[1] = 0x11; //本节点地址
TX_buffer[2] = 0x22;
TX_buffer[3] = 0x33;
TX_buffer[4] = 0x44;
//初始化发送数据单元
TX_buffer[5] = 0x11; //1
TX_buffer[6] = 0x22; //2
TX_buffer[7] = 0x33; //3
TX_buffer[8] = 0x44; //4
TX_buffer[9] = 0x55; //5
TX_buffer[10] = 0x66; //6
TX_buffer[11] = 0x77; //7
TX_buffer[12] = 0x88; //8
//初始化数据信息
EA = 0; //关中断
//查询SJA1000是否处于接收状态,当SJA1000不处于接收状态时才可继续执行
do
{
state = SR; //SR为SJA1000的状态寄存器
printf( "NO.1!\n");
}
while( state & 0x10 ); //SR.4=1 正在接收,等待
//查询SJA1000是否处于发送完毕状态
do
{
state = SR;
printf( "NO.2!\n");
}
while(!(state & 0x08)); //SR.3=0,发送请求未处理完,等待直到SR.3=1
//查询发送缓冲器状态
do
{
state = SR;
printf( "NO.3!\n");
}
while(!(state & 0x04)); //SR.2=0,发送缓冲器被锁。等待直到SR.2=1
//将待发送的一帧数据信息存入SJA1000的相应寄存器中
TBSR0 = TX_buffer[0];
TBSR1 = TX_buffer[1];
TBSR2 = TX_buffer[2];
TBSR3 = TX_buffer[3];
TBSR4 = TX_buffer[4];
TBSR5 = TX_buffer[5];
TBSR6 = TX_buffer[6];
TBSR7 = TX_buffer[7];
TBSR8 = TX_buffer[8];
TBSR9 = TX_buffer[9];
TBSR10 = TX_buffer[10];
TBSR11 = TX_buffer[11];
TBSR12 = TX_buffer[12];
CAN_Tx_display();
CMR = 0x10; //置位自发送接收请求
EA = 1; //重新开启中断
}
///////////////////////////////////////////////
//函数:CAN_Rx_display
//说明:接收数据串口显示
//入口:无
//返回:无
///////////////////////////////////////////////
void CAN_Rx_display(void)
{
printf( " RBSR5 = %x \n", RBSR5);
printf( " RBSR6 = %x \n", RBSR6);
printf( " RBSR7 = %x \n", RBSR7);
printf( " RBSR8 = %x \n", RBSR8);
printf( " RBSR9 = %x \n", RBSR9);
printf( " RBSR10 = %x \n", RBSR10);
printf( " RBSR11 = %x \n", RBSR11);
printf( " RBSR12 = %x \n", RBSR12);
}
///////////////////////////////////////////////
//函数:CAN_Rx_data
//说明:接收数据函数,在中断服务程序中调用
//入口:无
//返回:无
///////////////////////////////////////////////
void CAN_Rx_data( void )
{
uchar state;
if(rcv_flag)
{ //接收数据帧
RX_buffer[0] = RBSR0;
RX_buffer[1] = RBSR1;
RX_buffer[2] = RBSR2;
RX_buffer[3] = RBSR3;
RX_buffer[4] = RBSR4;
RX_buffer[5] = RBSR5;
RX_buffer[6] = RBSR6;
RX_buffer[7] = RBSR7;
RX_buffer[8] = RBSR8;
RX_buffer[9] = RBSR9;
RX_buffer[10] = RBSR10;
RX_buffer[11] = RBSR11;
RX_buffer[12] = RBSR12;
rcv_flag = 0; //接收标志置位,以便进入接收处理程序
CMR = 0X04; //CMR.2=1--接收完毕,释放接收缓冲器
state = ALC; //释放仲裁随时捕捉寄存器(读该寄存器即可)
state = ECC; //释放错误代码捕捉寄存器(读该寄存器即可)
}
IER = 0x01; // IER.0=1--接收中断使能
EA = 1; //重新开启CPU中断
} |