这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 基础知识 » CAN CAN节点的调试问题

共2条 1/1 1 跳转至

CAN CAN节点的调试问题

院士
2006-09-17 18:14:16     打赏
CAN CAN节点的调试问题



关键词: 节点     调试     问题    

院士
2006-12-22 22:43:00     打赏
2楼
问 /*****************************************************
Project : transmit
Date    : 2005-6-16
Comments: CAN发送子程序;
Chip type           : ATmega128L
Clock frequency     : 8.000000 MHz
*****************************************************/
#include <stdio.h>
#include <mega128.h>        
#include <delay.h>

#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)                          
                             
#define unchar unsigned char  
#define unint unsigned int

//SJA1000各寄存器的地址定义;
#define CAN_MODE   *(volatile unsigned char *) 0X1100            //模式寄存器
#define CAN_CMR    *(volatile unsigned char *) 0X1101            //命令寄存器
#define CAN_SR     *(volatile unsigned char *) 0X1102            //状态寄存器
#define CAN_IR     *(volatile unsigned char *) 0X1103            //中断寄存器
#define CAN_IER    *(volatile unsigned char *) 0X1104            //中断使能寄存器
#define CAN_ALC    *(volatile unsigned char *) 0X110B           //仲裁丢失捕捉寄存器
#define CAN_ECC    *(volatile unsigned char *) 0X110C           //错误代码捕捉寄存器
#define CAN_EWLR   *(volatile unsigned char *) 0X110D          //错误报警限额寄存器
#define CAN_RXERR  *(volatile unsigned char *) 0X110E           //RX错误计数寄存器
#define CAN_TXERR  *(volatile unsigned char *) 0X110F            //TX错误计数寄存器
#define CAN_TXB    *(volatile unsigned char *) 0X1110            //发送缓冲器
#define CAN_RXB    *(volatile unsigned char *) 0X1110            //接收缓冲器
#define CAN_RMC    *(volatile unsigned char *) 0X111D            //RX报文计数器
#define CAN_RBSA   *(volatile unsigned char *) 0X111E      //RX缓冲器起始地址寄存器
#define CAN_BTR0   *(volatile unsigned char *) 0X1106            //总线时序寄存器0
#define CAN_BTR1   *(volatile unsigned char *) 0X1107            //总线时序寄存器1
#define CAN_OCR    *(volatile unsigned char *) 0X1108            //输出控制寄存器
#define CAN_CDR    *(volatile unsigned char *) 0X111F            //时钟分频寄存器
#define CAN_ACR0   *(volatile unsigned char *) 0X1110            //验收代码寄存器0
#define CAN_ACR1   *(volatile unsigned char *) 0X1111            //验收代码寄存器1
#define CAN_ACR2   *(volatile unsigned char *) 0X1112            //验收代码寄存器2
#define CAN_ACR3   *(volatile unsigned char *) 0X1113            //验收代码寄存器3
#define CAN_AMR0   *(volatile unsigned char *) 0X1114            //验收屏蔽寄存器0
#define CAN_AMR1   *(volatile unsigned char *) 0X1115            //验收屏蔽寄存器1
#define CAN_AMR2   *(volatile unsigned char *) 0X1116            //验收屏蔽寄存器2
#define CAN_AMR3   *(volatile unsigned char *) 0X1117            //验收屏蔽寄存器3       

  
#define CAN_0   *(volatile unsigned char *) 0X1110            
#define CAN_1   *(volatile unsigned char *) 0X1111            
#define CAN_2   *(volatile unsigned char *) 0X1112            
#define CAN_3   *(volatile unsigned char *) 0X1113           
#define CAN_4   *(volatile unsigned char *) 0X1114            
#define CAN_5   *(volatile unsigned char *) 0X1115            
#define CAN_6   *(volatile unsigned char *) 0X1116            
#define CAN_7   *(volatile unsigned char *) 0X1117                  
#define CAN_8   *(volatile unsigned char *) 0X1118           
#define CAN_9   *(volatile unsigned char *) 0X1119            
#define CAN_10  *(volatile unsigned char *) 0X111a      //直接往地址中写入要发送的标准帧的11个字节;    

void CAN_INI(void);

// Get a character from the USART1 Receiver
#pragma used+
char getchar1(void)
{
char status1,data;
while (1)
      {
      while (((status1=UCSR1A) & RX_COMPLETE)==0);
      data=UDR1;
      if ((status1 & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
         return data;
      };
}
#pragma used-

// Write a character to the USART1 Transmitter
#pragma used+
void putchar1(char c)
{
while ((UCSR1A & DATA_REGISTER_EMPTY)==0);
UDR1=c;
}
#pragma used-

void main(void)
{
//unchar i;  
//unchar *p;
//unchar status;   
//static unchar transmit[11]={8,0,0,8,7,6,5,4,3,2,1};  
SPH=0x07;
SPL=0xFF;           //设置AVR堆栈为SP=0X0FFF;
MCUCR=0x80;         //允许访问外部的SRAM;
XMCRA=0X00;
XMCRB=0X00;

//////////////////////////////////////////////
CAN_INI();         //调用CAN初始化程序;    
//////////////////////////////////////////////
printf("CAN_SR_2=%x\n",CAN_SR);  //读总线状态;
//////////////////////////////////////////////
#asm("nop");  

while(1)
    {
       do
         {
            printf("\nCAN_SR_3=%x\n",CAN_SR);    
          }while((CAN_SR&0x04)!=0x04);  //等待总线状态正常;
    #asm("nop");
    printf("CAN_SR_4=%x\n", CAN_SR);  
    CAN_0=0x08;  
    #asm("nop");    
    printf("CAN_SR_5=%x\n", CAN_SR);  
    CAN_1=0x00;
    #asm("nop");
    printf("CAN_SR_6=%x\n", CAN_SR);
    CAN_2=0x00;  
    #asm("nop");
    printf("CAN_SR_7=%x\n", CAN_SR);
    CAN_3=0x01;  
    #asm("nop");  
    printf("CAN_SR_8=%x\n", CAN_SR);
    CAN_4=0x02;
    #asm("nop");  
    printf("CAN_SR_9=%x\n", CAN_SR);
    CAN_5=0x03;
    #asm("nop");
    printf("CAN_SR_10=%x\n", CAN_SR);
    CAN_6=0x04;
    #asm("nop");     
    printf("CAN_SR_11=%x\n", CAN_SR);  
    CAN_7=0x05;
    #asm("nop");
    //printf("CAN_SR_12=%x\n", CAN_SR);
    CAN_8=0x06;
    #asm("nop");
    printf("CAN_SR_13=%x\n", CAN_SR);
    CAN_9=0x07;
    #asm("nop");
    printf("CAN_SR_14=%x\n", CAN_SR);
    CAN_10=0x08;
    #asm("nop");
    printf("CAN_SR_15=%x\n", CAN_SR);
/////////////////////////////////////////////////////////     
    CAN_CMR=0X01;     //启动发送;
/////////////////////////////////////////////////////////   
    printf("\nCAN_SR_16=%x\n", CAN_SR);
    #asm("nop");    
    delay_ms(1);    
    #asm("nop");      //发送后延时循环;
////////////////////////////////////////////////////////    
    };  
}  

void CAN_INI(void)
{
  // MCUCR=0X80;      //允许外部存储器扩展,以便对SJA1000初始化;
  #asm("cli");           //全局中断禁止;
  #asm("nop");
  CAN_MODE=0x09;      //复位,单滤波器模式;用标准帧;
  CAN_CDR=0X88;       //采用Peli CAN; Clock out 不允许;   
  #asm("nop");  
  CAN_ACR0=0X00;
  CAN_ACR1=0X00;
  CAN_ACR2=0X00;
  CAN_ACR3=0X00;       //对验收代码寄存器进行设置;
  CAN_AMR0=0XFF;
  CAN_AMR1=0XFF;
  CAN_AMR2=0XFF;
  CAN_AMR3=0XFF;       //对验收屏蔽寄存器进行设置;滤波11位ID和1位RTR标志,数据位不参加滤波;
                          //由设置可知AMR不进行任何屏蔽;
  CAN_BTR0=0X03;
  CAN_BTR1=0XFF;       //设置波特率为80kbps,晶振为16M;   
  CAN_OCR=0XAA;        //设置输出控制寄存器;  
#asm("nop");   
  CAN_RBSA=0X00;       //设置接收缓冲起始地址为0X00;
  CAN_RXERR=0X00;      //设置RX错误计数寄存器为0X00;
  CAN_TXERR=0X00;      //设置TX错误计数寄存器为0X00;
  CAN_ECC=0X00;        //设置错误代码捕捉寄存器为0X00;
  CAN_MODE=0X08;      //进入SJA1000的操作模式;   
  #asm("nop");
  #asm("sei");             //开AVR全局中断;
  printf("CAN_SR_1=%x\n", CAN_SR);   
  #asm("nop");  
}
    这是我用Atmega128和SJA1000搭的一个CAN节点的发送程序;
    AVR和SJA1000的初始化都正常,现在的问题是:
         在发送报文前,SJA1000的状态寄存器的值为:0X04(总线开启,发送缓冲器状态为释放)
         在启动发送命令,发完一帧11个字节的标准帧报文后,状态寄存器的值变为:0X00(总线开启,发送缓冲器锁定)
         循环发送报文时,状态寄存器的值却已变为:0XF4(总线关闭,发送缓冲器状态为释放)
   
    为什么在发送第二条报文时总线就会关闭呢???????????
    搞不清楚是怎么回事,请各位多多指教!!!!!!!!!!!!!!

    wilson-pj@163.com


1: 也许你有错误帧!? 2: 继续请教chinawei97    CAN_CMR=0X01;     //启动发送;
    在我启动发送后,读总线状态变成0X00正常吗?应该是一个什么状态???它意味着:
         总线状态开启;    错误状态正常;
         发送状态空闲;    接收状态空闲;
         发送完成状态 完成;     发送缓冲器状态 锁定;
         数据溢出状态 未溢;     接收缓冲器状态 空;
    
    延时后再发送相同的帧时,总线就关闭了。但是若将程序复位后再发送时,总线状态就变为0XF4,总线关闭了!!!!
3: 回复主题:CAN节点的调试问题总线上有其他节点吗? 4: 请教coleflyer   总线上没有其它的节点。
   再发送报文的每一个字节时我都打印出SJA1000的状态寄存器的值结果直到置位发送命令前都还正常,值未0X04. 置位发送命令后总线状态寄存器的值就变为0X00。

共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]