论坛风格切换切换到宽版
  • 2754阅读
  • 2回复

请做过CAN总线的高手给我看看,我的程序错在什么地方 [复制链接]

上一主题 下一主题
离线张雄
 
发帖
85
只看楼主 倒序阅读 0楼 发表于: 2008-03-27
我做了个can总线智能节点,但是就是发送不了数据,请教高手看看我的程序有何问题,谢谢哈
程序部分仅仅是用来发送的,单片机用的stc89c52rc, 但是keil中呢,没有该款单片机的型号的,所以我选的at89c51,不知道这样是不是合适的, sja1000的复位端/rst与p2.3连,/cs与p2.0相连,下面是程序

#include <reg51.h>
#define   mode   0xfe00;         // sja1000方式寄存器
#define   cmr     0xfe01;         // sja1000命令寄存器
#define   sr     0xfe02;         // sja1000状态寄存器
#define   ir     0xfe03;         // sja1000中断寄存器
#define   ier     0xfe04;         // sja1000验收代码寄存器 ;中断使能寄存器
#define   acr     0xfe10;         // sja1000验收代码寄存器
#define   amr     0xfe14 ;         // sja1000验收屏蔽寄存器
#define   btr0   0xfe06 ;         // sja1000总线定时寄存器0
#define   btr1   0xfe07;         // sja1000总线定时寄存器1
#define   ocr     0xfe08 ;         // sja1000输出控制寄存器
#define   rbsa   0xfe1e ;         // sja1000接收缓存器起始地址寄存器
#define   cdr     0xfe1f;         // sja1000时钟分频寄存器
#define   alc     0xfe0b;         // sja1000丢失仲裁捕获寄存器
#define   ecc     0xfe0c;         // sja1000错误代码捕获寄存器
#define   cantxb   0xfe10;         // sja1000发送缓冲区首址
#define   canrxb   0xfe10 ;         // sja1000接收缓冲区首址
#define   rxerr   0xfe0e;       // sja1000接收错误寄存器
#define   txerr   0xfe0f ;       // sja1000发送错误寄存器
sbit acc0 = acc^0;
sbit acc1 = acc^1;
sbit acc2 = acc^2;
sbit acc3 = acc^3;
sbit acc4 = acc^4;
sbit acc5 = acc^5;
sbit acc6 = acc^6;
sbit p23   = p2^3;         // sja1000复位端
unsigned   char xdata *psja1000;

// 子函数定义
void   inisja1000(void); // sja1000初始化子程序
void   tdata(void);   // 发送数据子程序


main(void)   {
unsigned long wait;
p23=0;       // sja1000复位引脚拉低,进入复位状态
for(wait=0;wait<40000;wait++)//低电平延迟,以便复位
;
p23=1;               // sja1000复位引脚拉高
inisja1000();
while(1)
  {
  tdata();
for(wait=0;wait<30000;wait++)
;
}

} //main

void inisja1000(void) {  
do
  {
  psja1000 = mode;
  *psja1000 = 0x09;
  }
while(acc0 == 0);   // 进入复位模式,对sja1000进行初始化

psja1000 = cdr;
*psja1000 = 0x88;   // 选择pelican模式,关闭时钟输出(clkout)

psja1000 = ier;
*psja1000 = 0x01;   // 中断允许寄存器开放发送中断、溢出中断和错误警告中断

psja1000 = amr;   // 接收屏蔽寄存器
*psja1000 = 0xff;
psja1000++;
*psja1000 = 0xff;
psja1000++;
*psja1000 = 0xff;
psja1000++;
*psja1000 = 0xff;


psja1000 = acr;   // 接收代码寄存器
*psja1000 = 0xff;
psja1000++;
*psja1000 = 0xff;
psja1000++;
*psja1000 = 0xff;
psja1000++;
*psja1000 = 0xff;


psja1000 = btr0; // 总线定时寄存器
*psja1000 = 0x31;
psja1000 = btr1;
*psja1000 = 0x1c;

psja1000 = ocr;   // 输出控制寄存器
*psja1000 = 0xaa;

psja1000 = rbsa;   // 接收缓存器起始地址寄存器
*psja1000 = 0x00;

psja1000 = txerr;   // 发送错误计数寄存器
*psja1000 = 0x00;

psja1000 = ecc;   // 错误代码捕捉寄存器,清除错误代码捕捉寄存器
acc = *psja1000;

psja1000 = mode;   // 设置双滤波接收方式,并返回工作状态
*psja1000 = 0x08;

} // inisja1000

void   tdata(void) {
   

do {
  psja1000 = sr;
  acc = *psja1000;
  }
while(acc4 ==1);     // 判断是否正在接收正在接收则等待

do {
  psja1000 = sr;
  acc = *psja1000;
  }
while(acc3 ==0);   // 判断上次发送是否完成未完成则等待发送完成

  do {
  psja1000 = sr;
  acc = *psja1000;
  }  
while(acc2 ==0); // 判断发送缓冲区是否锁定锁定则等待
 
psja1000 = cantxb;   // sja1000 发送缓存区首址
*psja1000 =0x84;
psja1000++;
*psja1000 =0xf3;
psja1000++;
*psja1000 =0xff;
psja1000++;   // 29 id
*psja1000 =0xff;
psja1000++;
*psja1000 =0xf0;

psja1000++;
*psja1000 =0x12;
psja1000++;
*psja1000 =0x34;
psja1000++;     // 数据
*psja1000 =0x56;
psja1000++;
*psja1000 =0x78;


psja1000 = cmr;
*psja1000 =0x01;       // 发送数据
} // tdata

请高手给我看看吧
离线bd7bq
发帖
1491
只看该作者 1楼 发表于: 2008-03-28
对can不了解.
加上
sfr auxr=0x8e;
auxr=0x02;
看看,stc默认使用内部的1k xram.
离线张雄
发帖
85
只看该作者 2楼 发表于: 2008-04-04
此问题已经解决,谢谢大家