首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

求助mc9s12dp512 can总线采集信号问题

求助mc9s12dp512 can总线采集信号问题

#include <hidef.h>      /* common defines and macros */
#include <mc9s12dp512.h>     /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dp512"

void Transmission_CAN1(void);
void InitCAN0(void) ;
void InitCAN1(void) ;
void delay(void);
void InitCRG(void);
unsigned char txdata[8];                 //如果要方便观察它们的值可以设为全局变量
unsigned char rxdata[8];                 //现在是局部变量,但也能从BUFFER中观察0X160,0X170附近

void main(void) {
  /* put your own code here */
  InitCRG();                         //这是LOOP BACK模式
  DDRB=0XFF;                         //复位
  PORTB=0xff;                        //初始化方向设置为输入,随后pb的状态将被实际状态代替
  InitCAN0();                          //实际应用时要改到正常模式,并确定硬件连接正确
  InitCAN1();
  
  EnableInterrupts ;                 //CCR中的I位清零
for(;;) {
Transmission_CAN1();
delay();
           } /* wait forever */
  /* please make sure that you never leave this function */
}

  void InitCRG(void) {    //clock and reset generation
  SYNR=0;                 //PLLCLK=2*OCCLK*(SYNR+1)/(REFDIV+1)
  REFDV=0;                //当外部晶振为16M的时侯,PLL的输出频率为32M,单片机为了提高cpu
                          //运行速度,降低外部时钟频率,提高整个系统的电磁兼容能力,采用锁相环技术
  
  CRGFLG=0Xf2;            //清CRG模块的各个标志位
                          //第7位是实时中断标志位。写1,清标志位
                          //第6位是上电复位标志位。写1,清标志位
                          
                          //第4位是PLL锁定状态改变标志位。写1,请标志位。
                          //第1位是自时钟模式中断标志位。写1,清标志位
  PLLCTL=0XF1;            //设置锁相环PLL控制寄存器
                          //第7位是时钟监控使能位。写1,使能对时钟的监控
                          //第6位是PLL使能位。写1,使能PLL
                          //第5位是自动带宽使能位。写1,自动选择带宽
                          //第4位是带宽选择位,在选择了自动带宽时这一位无效
                          //第0位是自时钟模式使能位。写1,在晶振失效时进入自时钟模式
  

   CRGINT=0x00;             //清非法地址复位中断标志位


   while(CRGFLG_LOCK==1)  ;     //等待PLL输出始终达到稳定
  
   CLKSEL= 0XFB;              // 设置总线始终选择寄存器
                            //第7位是总线时钟选择位。写1,总线时钟频率=PLL输出时钟频率/2
                            //第3位是WAIT模式PLL停止位。写1,PLL在WAIT模式下停止工作
                            //第1位是WAIT模式实时中断停止位。写1,实时中断在WAIT模式停止工作
                            //第0位是WAIT模式看门狗停止位。写1,看门狗在WAIT模式停止工作

   COPCTL=0;                   //设置看门狗控制寄存器,为零是禁用看门狗
  
}

   void InitCAN0(void)     //can的初始化主要是对can通道控制寄存器,波特率,id滤波寄存器,接受寄存器等设置
    {
    /*DS上说在设定INITRQ之前最好能先进入睡眠模式以确保安全*/
   
    CAN0CTL0=0x01;             //进入CAN 初始化模式
    while(CAN0CTL1_INITAK==0);  //等待确认进入初始化模式
     
                          
    CAN0CTL1=0X80;            //CAN 使能,选用晶振时钟,频率为16M ,loop back mode
    CAN0BTR1=0X3A;            // One sample per bit,time segment2=4,
                              // time segment1=11;时间量=1+11+4=16
    CAN0BTR0=0xC9;              //Synchronization Jump With=4Tq,Prescaler=10;
                              //得到位速率为100K,  Bit Rate=(Frequence of CANCLK)/(Prescalar*Number of Time Quanta)   
   
   
    CAN0IDAC=0X10;            //验收标志寄存器4X16 bits Identifier Acceptance Filters                                                
   
/*To receive standard identifiers in 32 bit filter mode, it is required to
program the last three bits (AM2 - AM0) in the mask registers CANIDMR1 and CANIDMR5 to "don’t
care". To receive standard identifiers in 16 bit filter mode, it is required to program the last three bits (AM2
- AM0) in the mask registers CANIDMR1, CANIDMR3, CANIDMR5 and CANIDMR7 to "don’t car".  */
   
   
    CAN0IDAR0=0x20;
    CAN0IDMR0=0xff;
   
    CAN0IDAR1=0x00;
    CAN0IDMR1=0Xff;
   
   
    CAN0IDAR2=0X21;
    CAN0IDMR2=0X00;         //此处将Recieve_Filter0只用CAN0IDAR0来判断保报文
                            //优先级,不过每一位都要参与判断
    CAN0IDAR3=0x12;
    CAN0IDMR3=0X00;
   
    CAN0IDAR4=0X00;
    CAN0IDMR4=0X00;
   
    CAN0IDAR5=0x00;
    CAN0IDMR5=0X0f;
                             //此处将Recieve_Filter只用CAN0IDAR0来判断保报文
                             //优先级,不过每一位都要参与判断
    CAN0IDAR6=0X00;
    CAN0IDMR6=0X00;           
   
    CAN0IDAR7=0x00;
    CAN0IDMR7=0X00;   
   
   CAN0CTL0=0x00;               //退出初始化模式,回到正常模式
   while(CAN0CTL1_INITAK==1)  ;

   while(CAN0CTL0_SYNCH==1);
   
   CAN0RFLG=0XC3;               //清CAN STATUS CHANGE INTERRUPT,OVERRUN INTERRUPT,
                                //BUFFER FULL 的标志位
   
  
   CAN0RIER=0x01;               //开RECIEVER FULL 中断
  }
void InitCAN1(void)  
    {
    /*DS上说在设定INITRQ之前最好能先进入睡眠模式以确保安全*/
   
    CAN1CTL0=0x01;             //进入CAN 初始化模式
    while(CAN1CTL1_INITAK==0);   //等待确认进入初始化模式
     
                          
    CAN1CTL1=0X80;            //CAN 使能,选用晶振时钟,频率为16M ,loop back mode
    CAN1BTR1=0X3A;            // One sample per bit,time segment2=4,
                              // time segment1=11;时间量=1+11+4=16
    CAN1BTR0=0xC9;              //Synchronization Jump With=4Tq,Prescaler=10;
                              //得到位速率为100K,  Bit Rate=(Frequence of CANCLK)/(Prescalar*Number of Time Quanta)   
   
   
    CAN1IDAC=0X10;            //4X 16 bits Identifier Acceptance Filters                                                
   
/*To receive standard identifiers in 32 bit filter mode, it is required to
program the last three bits (AM2 - AM0) in the mask registers CANIDMR1 and CANIDMR5 to "don’t
care". To receive standard identifiers in 16 bit filter mode, it is required to program the last three bits (AM2
- AM0) in the mask registers CANIDMR1, CANIDMR3, CANIDMR5 and CANIDMR7 to "don’t car".  */
   
   
    CAN1IDAR0=0x20;         //IDAM1 IDAM0 标识符接受模式
    CAN1IDMR0=0xff;            0     0     2*32
                               0     1     4*16
    CAN1IDAR1=0X00;            1     0     8*8
    CAN1IDMR1=0Xff;            1     1     过滤器关闭
   
    CAN1IDAR2=0X80;
    CAN1IDMR2=0Xff;         //此处将Recieve_Filter0只用CAN0IDAR0来判断保报文
                            //优先级,不过每一位都要参与判断
    CAN1IDAR3=0X00;
    CAN1IDMR3=0Xff;
   
    CAN1IDAR4=0X90;
    CAN1IDMR4=0Xff;
   
    CAN1IDAR5=0X00;
    CAN1IDMR5=0Xff;
                             //此处将Recieve_Filter只用CAN0IDAR0来判断保报文
                             //优先级,不过每一位都要参与判断
    CAN1IDAR6=0Xa0;
    CAN1IDMR6=0Xff;           
   
    CAN1IDAR7=0X00;
    CAN1IDMR7=0Xff;   
   
   CAN1CTL0=0;               //退出初始化模式,回到正常模式
   while(CAN1CTL1_INITAK==1)  ;

   while(CAN1CTL0_SYNCH==1);
  
   CAN1RFLG=0XC3;               //清CAN STATUS CHANGE INTERRUPT,OVERRUN INTERRUPT,
                                //BUFFER FULL 的标志位
   
  
   CAN1RIER=0x00;               //开RECIEVER FULL 中断
  }
void Transmission_CAN1(void/*unsigned char txbuffer,unsigned char ID,unsigned char priority,unsigned char length, unsigned char txdata[8],int index*/)
{
   unsigned char txbuffer;
   unsigned char ID_0,ID_1,ID_2,ID_3;
   unsigned char priority;
   unsigned char length;
   unsigned char txdata[8];
   int index;
                              //以查询方式发送数据
  while(CAN1TFLG==0) ;        //如果BUFFER都是满的,等待
                              
  CAN1TBSEL=CAN1TFLG;           //选择BUFFER
  txbuffer=CAN1TBSEL;           //备份选择的BUFFER,其实也不一定需要,只要以后直接写CAN0TBSEL就好了
  
  ID_0=0x20;                     //把ID 值写入要传送的帧                 
  ID_1=0X79;                        //IDE=0,RTR=0.数据帧,标准格式的标识符
  ID_2=0X21;
  ID_3=0X12;
  //*((unsigned long*)((unsigned long)(&CAN0TXIDR0)))=0x2000;              //不过在本例中IDMR已经设定了只辨识前8位标识符   
  CAN1TXIDR0=ID_0;
  CAN1TXIDR1=ID_1;
  CAN1TXIDR2=ID_2;
  CAN1TXIDR3=ID_3;
  length=0x07;                   //把数据长度写入要传送的帧
  CAN1TXDLR=length;
   priority=0;                   //当有传送缓冲竞争时,此数据帧所写入的缓冲有最高优先级
   CAN1TXTBPR=priority;
                                      
  
   txdata[0]=1;
   txdata[1]=2;
   txdata[2]=3;
   txdata[3]=4;
   txdata[4]=5;
   txdata[5]=6;
   txdata[6]=7;
   txdata[7]=8;
   
   for(index=0;index<=length;index++)
  {
    *(&CAN1TXDSR0+index)=txdata[index];       //把DATA读入帧
  }
  
  CAN1TFLG=txbuffer;                        //开始传送
  
  while((CAN1TFLG&txbuffer)!=txbuffer)  ;     //等待传送结束
                                              //标志位会在传送结束或者ABORT的时候自动清除
                                              //PTM可编程定时器 programmable timer module
  
}

void delay(void) {
int a;
for(a=1000;a>0;a--)  ;
  
}


#pragma TRAP_PROC
void CAN0_Recieve(void)
{
unsigned char length,index;
//unsigned char rxdata[8];
PORTB=0;
//delay();
//PORTB=0XFF;
//delay();
length=(CAN0RXDLR&0X0F);
for(index=0;index<length;index++) {
rxdata[index]=*(&CAN0RXDSR0+index);
CAN0RFLG=0x01;          //清标志
}

}
  以上是一位师兄留下的程序,我现在要用can总线采集轮速信号,大师们行行好,讲一下程序的修改,本人菜鸟,qq:705128816,可以和我联系,多谢!
返回列表