SJA1000初始化成功!当想发送数据的时候,先检测了状态寄存器,REG_STATUS寄存器 = 0x44,第四位为0,表示正在发送,可我还没发送呢?所以在下面标记 1 的循环里跳不出来,原因是出在标记 2 的地方。 既然SJA1000初始化成功,那还出现这个问题,真是想了几天都没想不通。只能麻烦一下高手们了。下面附了小弟的程序,挺长,真是麻烦大家了。 #include <reg51.h> #include "SJA_BCANCONF.H" #include <string.h> void delay(unsigned int t); bit Sja_1000_Init(void); sbit LED = P1^0; unsigned char data send_data[10] = {0xaa,0x08,2,3,4,5,6,7,8,9};
main() { while(Sja_1000_Init()); while(1) { while(BCAN_DATA_WRITE(send_data));/*老是跳不出来*/ while(BCAN_CMD_PRG(0x01)); delay(1000); LED = ~LED; } }
/************************************************************************ * delay() * 延时函数 *************************************************************************/ void delay(unsigned int t) { unsigned char i; while(t--) { for(i=0;i<125;i++); } }
/************************************************************************ * Sja_1000_Init() * SJA1000初始化 *************************************************************************/ bit Sja_1000_Init(void) { if(BCAN_CREATE_COMMUNATION()) //通信测试; return 1; if(BCAN_ENTER_RETMODEL()) //申请进入复位模式 return 1; if(BCAN_SET_BANDRATE()) //设置波特率为50K return 1; if(BCAN_SET_OBJECT(0xaa,0xFF)) //设置ACK、AMR return 1; if(BCAN_SET_OUTCLK(0xaa,0x48)) //设置输出方式禁止clkout return 1; if(BCAN_QUIT_RETMODEL()) //退出复位状态 return 1; SJA_BCANAdr = REG_CONTROL; //送控制寄存器地址 *SJA_BCANAdr |= 0x0A; //开放错误中断和接收中断 return 0; }
/************************************************************************ *函数原型: bit BCAN_CREATE_COMMUNATION(void) * *参数说明: 无 * *返回值: * * 0 ; 表示SJA1000接口正常 * * 1 ; 表示SJA1000与处理器接口不正常 * * * *说明:该函数用于检测CAN控制器的接口是否正常 * ************************************************************************/ bit BCAN_CREATE_COMMUNATION(void) { SJA_BCANAdr=REG_TEST; //访问测试寄存器 *SJA_BCANAdr =0xaa; //写入测试值 if(*SJA_BCANAdr == 0xaa) { return 0; //读测试正确 } else { return 1; } }
/************************************************************************ *函数原型: bit BCAN_ENTER_RETMODEL(void) * *参数说明: 无 * *返回值: * * 0 ; 表示成功进入复位工作模式 * * 1 ; 表示不能进入复位工作模式 * * * *说明: CAN控制器进入复位工作模式 * ************************************************************************/ bit BCAN_ENTER_RETMODEL(void) { unsigned char TempData; SJA_BCANAdr = REG_CONTROL; //访问地址指向控制寄存器 TempData= *SJA_BCANAdr; //保存原始值 *SJA_BCANAdr=(TempData|0x01); //置位复位请求 if((*SJA_BCANAdr&0x01) == 1) { return 0; } else { return 1; } }
/************************************************************************ *函数原型: bit BCAN_QUIT_RETMODEL(void) * *参数说明: 无 * *返回值: * * 0 ; 表示成功退出复位工作模式 * * 1 ; 表示不能退出复位工作模式 * * * *说明: CAN控制器退出复位工作模式 * ************************************************************************/ bit BCAN_QUIT_RETMODEL(void) { unsigned char TempData; SJA_BCANAdr = REG_CONTROL; //访问地址指向控制寄存器 TempData = *SJA_BCANAdr; //保存原始值 *SJA_BCANAdr=(TempData&0xfe); //清除复位请求 if((*SJA_BCANAdr&0x01) == 0) { return 0; // } else { return 1; //退出成功 }
}
/************************************************************************ ;*函数原型: bit BCAN_SET_BANDRATE(unsigned char CAN_ByteRate) * ;*参数说明: R7 波特率(Kbit/s) BTR0 BTR1 * ;* 50Kbit/s 0xC9 0xA7 * ;*返回值: * ;* 0 ;波特率设置成功 * ;* 1 ;波特率设置失败 * ;* * ;*说明:设置CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为12MHZ, * ;* 其它晶体的频率的值的波特率,需自己计算 。该子程序只能用于 * ;* 复位模式 * ;************************************************************************/
bit BCAN_SET_BANDRATE(void) { unsigned char BTR0_num,BTR1_num; BTR0_num = 0xC9; BTR1_num = 0xA7; //将波特率的的预设值装入sja1000的总线定时器 SJA_BCANAdr=REG_BTR0; //访问地址指向总线定时寄存器0 *SJA_BCANAdr=BTR0_num; //写入参数 if(*SJA_BCANAdr != BTR0_num) //校验写入值 { return 1; } SJA_BCANAdr=REG_BTR1; //访问地址指向总线定时寄存器0 *SJA_BCANAdr=BTR1_num; //写入参数 if(*SJA_BCANAdr != BTR1_num) //校验写入值 { return 1; }
return 0; }
/************************************************************************ ;*函数原型: BCAN_SET_OBJECT * *参数说明: * * BCAN_ACR:存放验收代码寄存器(ACR)的参数设置 * * BCAN_AMR:存放接收屏蔽寄存器(AMR)的参数设置 * ;*返回值: * ;* 0 ;通信对象设置成功 * ;* 1 ;通信对象设置失败 * ;* * ;*说明:设置CAN节点的通讯对象,允许接收的报文ID号的高8位(D10--D3) 。 * ;* 允许接收的报文,是由AMR和ACR共同决定的. * ;* 满足以下条件的ID号的报文才可以被接收 * ;*[(ID.10-ID.3)≡(AC.7-AC.0)]||(AM.7-AM.0)≡11111111 * ;* 该子程序只能用于复位模式 * * ;************************************************************************/ bit BCAN_SET_OBJECT(unsigned char BCAN_ACR,unsigned char BCAN_AMR) { SJA_BCANAdr=REG_ACR; //访问地址指向验收代码寄存器(ACR) *SJA_BCANAdr=BCAN_ACR; //写入参数 if(*SJA_BCANAdr != BCAN_ACR) //校验写入值 { return 1; } SJA_BCANAdr=REG_AMR; //访问地址指向验收屏蔽寄存器(AMR) *SJA_BCANAdr=BCAN_AMR; //写入参数 if(*SJA_BCANAdr != BCAN_AMR) //校验写入值 { return 1; }
return 0; }
/************************************************************************ ;*函数原型: bit BCAN_SET_OUTCLK (unsigned char Out_Control, * unsigned char Clock_Out); * ;*参数说明: * * Out_Control:存放输出控制寄存器 (OC) 的参数设置 * * Clock_Out:存放时钟分频寄存器 (CDR) 的参数设置 * * * ;*返回值: * ;* 0 ;设置成功 * ;* 1 ;设置失败 * ;* * ;*说明:设置SJA1000的输出模式和时钟分频 。该子程序只能用于复位模式 * * ;************************************************************************/ bit BCAN_SET_OUTCLK (unsigned char Out_Control, unsigned char Clock_Out) { SJA_BCANAdr=REG_OCR ; //访问地址指向输出控制寄存器 *SJA_BCANAdr=Out_Control; //写入参数 if(*SJA_BCANAdr != Out_Control) //校验写入值 { return 1; } SJA_BCANAdr=REG_CDR; //访问地址指向输出控制寄存器 *SJA_BCANAdr=Clock_Out; //写入参数 return 0; }
/************************************************************************ *函数原型: bit BCAN_DATA_WRITE(unsigned char *SendDataBuf)* *参数说明: 特定帧各式的数据? * *返回值: * * 0 ; 表示将数据成功的送至发送缓冲区 * * 1 ; 表示上一次的数据正在发送, * * ; 表示发送缓冲区被锁定,不能写入数据 * * ; 表示写入数据错误 * *说明: 将待发送特定帧各式的数据,送入SJA1000发送缓存区中,然后启动 * * SJA1000发送。 * * 特定帧格式为:开始的两个字节存放 '描述符' ,以后的为数据 * * 描述符包括11位长的ID(标志符)\1位RTR\4位描述数据长度的DLC共16位 * * * *注:本函数的返回值仅指示,将数据正确写入SJA1000发送缓存区中与否。 * * 不指示SJA1000将该数据正确发送到CAN总线上完毕与否 * ************************************************************************/ bit BCAN_DATA_WRITE(unsigned char *SendDataBuf) { unsigned char TempCount; SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器 if((*SJA_BCANAdr&0x08) == 0) //判断上次发送是否完成 { return 1; //???????? 总是进来,此时的STATUS = 0x44 ?????????? }
if((*SJA_BCANAdr&0x04)==0) //判断发送缓冲区是否锁定 { return 1; }
SJA_BCANAdr = REG_TxBuffer1; //访问地址指向发送缓冲区1 if((SendDataBuf[1]&0x10)==0) //判断RTR,从而得出是数据帧还是远程帧 { TempCount =(SendDataBuf[1]&0x0f)+2; //输入数据帧 }
else { TempCount =2; //远程帧 }
memcpy(SJA_BCANAdr,SendDataBuf,TempCount); return 0; }
/************************************************************************ *函数原型: bit BCAN_CMD_PRG(unsigned char cmd) * *参数说明: cmd:sja1000运行的命令字 * * 01:发送请求 * * 02:中止发送 * * 04:释放接收缓冲区 * * 08:清除超载状态 * * 0x10:进入睡眠状态 * * * *返回值: * * 0 ; 表示命令执行成功 * * 1 ; 表示命令执行失败 * * * *说明: 执行sja1000命令 * ************************************************************************/ bit BCAN_CMD_PRG(unsigned char cmd) { SJA_BCANAdr=REG_COMMAND; //访问地址指向命令寄存器 *SJA_BCANAdr=cmd; //启动命令字 switch(cmd) { case TR_CMD: //发送请求命令 return 0; break; case AT_CMD: //夭折发送命令 SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器 if((*SJA_BCANAdr & 0x20)==0)//判断是否正在发送 { return 0; } else { return 1; } break; case RRB_CMD: //释放接收缓冲区 SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器 if((*SJA_BCANAdr & 0x01)==1)//判断是否释放成功 { return 1; } else { return 0; } break; case COS_CMD: //清除超载状态 SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器 if((*SJA_BCANAdr & 0x02)==0)//判断清除超载是否成功 { return 0; } else { return 1; } break; case GTS_CMD: //进入睡眠状态命令 return 0; break; default: return 1; break; }
}
|