Board logo

标题: CAN总线的通信问题 [打印本页]

作者: 加密咖啡    时间: 2006-8-13 10:09     标题: CAN总线的通信问题

我用GZ16做CAN总线通信,但是用汇编的程序调通,不知道为什么,改成C就不行了,以下是我的C程序,请各位大侠指教,小弟在此写过了!急啊!#include <hidef.h> /* for EnableInterrupts macro */
#include <MC68HC908GZ16.h> /* include peripheral declarations */


 extern typedef unsigned char  byte;
 
byte  TEMPCMCR0 ;  
byte  TEMP;
byte   TXFLAG1   ;
byte   TEMPCRFLG ;
byte   TEMPPORTA ; 
byte   TEMPPORTB ;  
byte   TEMPPORTB1;
byte   TEMPDSRRX0;  
byte   FLAG     ;   /*  读数成功标志位 */
byte   TEMPCTFLG ;


int i;


void init_Ports ()
{
    DDRA=0x03;
    DDRB=DDRB&0xF3;
    DDRE=0xFF;
    DDRC=0x3D; 
    PTA=PTA&0x03;  
    PTB=PTB&0xF3;
    PTE=0x00;
    PTC=PTC&0x03;
       TEMPPORTB1=0x00;
    TEMPDSRRX0=0x00;
    TEMPCRFLG= 0x00;
    TEMPCTFLG=0x00;
    FLAG= 0x00;
  
}
 
void init_can ()
 {
   CMCR0=0x01;
   CMCR1=0x00;
   CBTR0=0x01;
   CBTR1=0x58 ;
            
 /***************************INITIAL CAN INTERRUPT**********************/
    CTCR=0x00;
    CIDAC=0x20;   
        
 /****************************initial filter*******************************/
/*设置接受符ID过滤比较码寄存器。因为屏蔽码置为0xFF,所有的为豆浆被忽略,
所以这里的比较码可以置为任意值*/
       
        CIDAR0=0x33;
        CIDAR1=0x55;
        CIDAR2=0x55;
        CIDAR3=0x55;
        
/*设置接受符ID过滤屏蔽码寄存器,因为是测试程序,所有的屏蔽码为都为1,接受所有的数据*/
       
       CIDMR0=0x00; 
       CIDMR1=0xFF;
       CIDMR2=0xFF;
       CIDMR3=0xFF;
      
                                   
     
/************************RECEIVE BUFFER ******************************/
   REC_DLR=0x01;
        
                
/*************************TRANSMISS BUFFER 1*****************************/
          TBPR0=0x11;
          DLR0 =0x01;
          IDR00=0x55;
          IDR10=0x00;
        
/**************************CAN NOMAL WORK*********************************/      
      CMCR0=0x00;   
      CRIER=0x01;  
      CRFLG=0x00;
      TEMPCMCR0=CMCR0;
   while(TEMPCMCR0&0x10==0){
    TEMPCMCR0=CMCR0;
   }
    
 }
  void READDATA()  { 
     
    TEMPPORTA=0x00;
    TEMPPORTA=PTA;
        TEMPPORTA=TEMPPORTA&0xFC; 
        TEMPPORTA=TEMPPORTA>>2;
        TEMPPORTB=0x00;
    TEMPPORTB=PTB;
        TEMPPORTB=TEMPPORTB&0x0C; 
        TEMPPORTB=TEMPPORTB<<4;
        TEMPPORTB=TEMPPORTB&0xC0; 
        TEMPPORTB=TEMPPORTB|TEMPPORTA;  
       
 }
 interrupt void r_isr(){
    DisableInterrupts;
      TEMPDSRRX0= REC_DSR0  ;                                
      FLAG =0x01;
       EnableInterrupts; 
 }
void  t_isr()
{
  for(i=0;i<3;i++) {
  }
     DSR00 =TEMPPORTB;
     
     TXFLAG1=0x00;
  
     TXFLAG1= CTFLG&0x01;
     while( TXFLAG1==0x00) {
      TXFLAG1= CTFLG&0x01;
     }
     for(i=0;i<5;i++) {
  } 
  EnableInterrupts; 
}
         
void CHULI() {
   
    FLAG=0x00;
     PTE=0x00;
     PTC=PTC&0x03;
     TEMP=TEMPDSRRX0;
     TEMP=TEMP&0xF0;
     TEMP=TEMP>>2; 
     PTE=PTE|TEMP;
     TEMPDSRRX0=TEMPDSRRX0&0x0F; 
     TEMPDSRRX0=TEMPDSRRX0<<2; 
     PTC=PTC|TEMPDSRRX0;                                     
}
 void  RECEIVE() {
 for(i=0;i<3;i++) {
  }
 if(FLAG&0x01)
   CHULI() ;
}
 
 void main(void) {
  for(i=0;i<307;i++) {
  }
  DisableInterrupts; /* disable interrupts */
 CONFIG2=0x0A;
 CONFIG1=0x1B;
 init_Ports () ;
  init_can();
  EnableInterrupts;
 for(i=0;i<3;i++) {
  }
  while(1){
    READDATA() ;
  t_isr();
  RECEIVE() ;
 
 }
 
}
        
       


作者: zhwdy81    时间: 2006-8-15 15:36

//控制命令ID18ff0f8a(c7fe1f14)
#define LOCAL_CMD_ADR0 0xc7
#define LOCAL_CMD_ADR1 0xfe
#define LOCAL_CMD_ADR2 0x1f
#define LOCAL_CMD_ADR3 0x14
//状态ID18ff102b(c7fe2056)
#define LOCAL_STA_ADR0 0xc7
#define LOCAL_STA_ADR1 0xfe
#define LOCAL_STA_ADR2 0x20
#define LOCAL_STA_ADR3 0x56

static void Init_MSCAN08(void)
{
CMCR0 = 0x01; //CAN模块为软复位状态
CMCR1 = 0x00; //时钟源为外部晶体/2 2M
//CMCR1 = 0x04; //时钟源为外部晶体/2 2M

CBTR0 = 0x80;
//SJW1,SJW0,10,3个周期同步。100000,20分频,为100KC。10100000 A0H
CBTR1 = 0xfa; //1,3个采样位,0000000,分频为0,波特率为100K

CIDAC = 0x00; //接收滤波为32位滤波,击中事件使用1个字节
//标识符号验收寄存器0~3
CIDAR0 = 0x00; //滤波使它接收一帧08B7D8D2(45BFB1A4)
CIDAR1 = 0x00;
CIDAR2 = 0x00;
CIDAR3 = 0x00;
//标识符屏蔽寄存器0~3
CIDMR0 = 0xFF;
CIDMR1 = 0xFF;
CIDMR2 = 0xFF;
CIDMR3 = 0xFF; //不进行过滤

CMCR0 = 0x00; //把CAN模块设置为数据输入输出状态
//while(CMCR0_SYNCH==0){;} //等待同步

CRIER = 0x01; //CAN接收中断使能
}
//*********************状态CAN发送函数 OK**********************
void CAN_Transmit(void)
{
unsigned char empty;
unsigned char empty0;
empty = CTFLG; //读传送标志寄存器
empty0 = empty&0x01; //屏蔽无用位,保留传送缓冲0状态标志。
if(empty0 !=0) //如果传送缓冲区0为空
{
TB0DLR = 0x08; //设置传送数据长度为8个字节。

TB0DSR0 = CAN_STR0.Byte; //传送本地状态数据
TB0DSR1 = CAN_STR1.Byte;
TB0DSR2 = CAN_STR2.Byte;
TB0DSR3 = CAN_STR3.Byte;
TB0DSR4 = CAN_STR4.Byte;
TB0DSR5 = CAN_STR5.Byte;
TB0DSR6 = CAN_STR6.Byte;
TB0DSR7 = CAN_STR7.Byte;

TB0IDR0 = LOCAL_STA_ADR0; //设置本地ID
TB0IDR1 = LOCAL_STA_ADR1;
TB0IDR2 = LOCAL_STA_ADR2;
TB0IDR3 = LOCAL_STA_ADR3;

TB0TBPR = 0x05; //设置优先级别
CTFLG = 0x01; //启动发送
}
}

//***********************CAN命令执行函数********
void CAN_comm(void)//ID1
{
unsigned char empty;
unsigned char empty0;
empty = CTFLG; //读传送标志寄存器
empty0 = empty&0x04; //屏蔽无用位,保留传送缓冲0状态标志。
if(empty0 !=0) //如果传送缓冲区0为空
{
TB2DLR = 0x08; //设置传送数据长度为8个字节。

TB2DSR0 = CAN_CMD0.Byte; //传送本地状态数据
TB2DSR1 = CAN_CMD1.Byte;
TB2DSR2 = CAN_CMD2.Byte;
TB2DSR3 = CAN_CMD3.Byte;
TB2DSR4 = CAN_CMD4.Byte;
TB2DSR5 = CAN_CMD5.Byte;
TB2DSR6 = CAN_CMD6.Byte;
TB2DSR7 = CAN_CMD7.Byte;

TB2IDR0 = LOCAL_CMD_ADR0; //设置本地ID
TB2IDR1 = LOCAL_CMD_ADR1;
TB2IDR2 = LOCAL_CMD_ADR2;
TB2IDR3 = LOCAL_CMD_ADR3;

TB2TBPR = 0x05; //设置优先级别
CTFLG = 0x04; //启动发送
}
}
//******************** CAN接收中断子程序 OK**********************
void interrupt CAN_Receive(void)
{
volatile unsigned char ID_ADDS0;
volatile unsigned char ID_ADDS1;
volatile unsigned char ID_ADDS2;
volatile unsigned char ID_ADDS3;
ID_ADDS0 = RBIDR0; //读标识符寄存器0(0~3)
ID_ADDS1 = RBIDR1; //读标识符寄存器0(0~3)
ID_ADDS2 = RBIDR2; //读标识符寄存器0(0~3)
ID_ADDS3 = RBIDR3; //读标识符寄存器0(0~3)

if(ID_ADDS0==0xc7 && ID_ADDS1==0xfe && ID_ADDS2==0x01 && ID_ADDS3==0x10)
{
//CAN_SWITCH_COMR0.Byte=RBDSR0; //转存接受缓冲数据段寄存器0(0~7)
CAN_SWITCH_COMR1.Byte=RBDSR1; //转存接受缓冲数据段寄存器1
CAN_SWITCH_COMR2.Byte=RBDSR2; //转存接受缓冲数据段寄存器2
CAN_SWITCH_COMR3.Byte=RBDSR3; //转存接受缓冲数据段寄存器3
CAN_SWITCH_COMR4.Byte=RBDSR4; //转存接受缓冲数据段寄存器4
//CAN_SWITCH_COMR5.Byte=RBDSR5; //转存接受缓冲数据段寄存器5
//CAN_SWITCH_COMR6.Byte=RBDSR6; //转存接受缓冲数据段寄存器6
CAN_SWITCH_COMR7.Byte=RBDSR7; //转存接受缓冲数据段寄存器7
}

else if(ID_ADDS0==0xc7 && ID_ADDS1==0xfe && ID_ADDS2==0x27 && ID_ADDS3==0x16)
{
CAN_FORMER2_COMR0.Byte=RBDSR0;
CAN_FORMER2_COMR1.Byte=RBDSR1;
CAN_FORMER2_COMR2.Byte=RBDSR2;
}

CRFLG = 0x01; //清缓冲满标志(接受标志寄存器)
}
作者: zhwdy81    时间: 2006-8-15 15:37

这是我的 用的好好的啊
作者: xiang1912    时间: 2006-10-19 09:28

zhwdy81,你好!MSCAN08和单片机的时钟源来自同一个晶振吗?





欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0