打印

请各位大侠帮忙看看30F6011的CAN 程序

[复制链接]
2454|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
单眼皮的鱼|  楼主 | 2010-7-6 21:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CAN, TE, ce, TI, se
大家好,帮我看看下面的一段程序,为什么和周立功CAN收发器通讯,不能正常收发。
我用的芯片是PIC30F6011,是根据PIC30F6014A的CAN自收发(CAN_Loopback.C)例程,修改的,用到的can通道为CAN2,别的都没用到,只想调试 CAN通讯部分,目的也很简单,见简单调试下30F6011的can通道和周立功收发器的连接。但修改过来后,发现RX和TX上有波形,但就是和周立功收发器不能正常通讯,发送失败总会。。可能是波特率的问题,我这里想用500K的波特率,不知道程序中这样是否对的?芯片用到一个外部8M晶振。
程序如下:
*
* ADDITIONAL NOTES:  
*
* Demo program showing CAN Module working in LoopBack Mode for dsPIC30F6014A Series
*/
#include <p30F6011.h>

#define FCY   32000000               // 32 MHz
#define BITRATE  500000       // 1Mbps
#define NTQ   15       // Number of Tq cycles which will make the
            //CAN Bit Timing .
#define BRP_VAL  ((FCY/(2*NTQ*BITRATE))-1)  //Formulae used for C1CFG1bits.BRP
//---------------------------------------------------------------------
// Buffer Registers for CAN data to be send out in the transmit mode.
unsigned int OutData0[4] = {0x5251, 0x5453, 0x5655, 0x5857};            
unsigned int OutData1[2] = {0x5A59, 0x5C5B};
unsigned int OutData2[4] = {0x6261, 0x6463, 0x6665, 0x6867};            
unsigned int OutData3[2] = {0x6A69, 0x6C6B};
// Intilializing the receive registers to be 0
unsigned int InData0[4] = {0, 0, 0, 0};
unsigned int InData1[2] = {0, 0};
unsigned int InData2[4] = {0, 0, 0, 0};
unsigned int InData3[2] = {0, 0};
//---------------------------------------------------------------------
int main(void)
{

TRISG = 0xCFFD;
TRISD = 0x0000;    // Initialize the PORTD as output
LATD = 0xFFFF;                 // Initially LEDs of dsPICDEM1.1 Plus GP Board are off

//--------------------------------------------------------------------------------------------------------------------
     //Initialization of CAN1 Module and Enabling of CAN1 Interrupts
//初始化CAN1模块和CAN1中断启用
//--------------------------------------------------------------------------------------------------------------------


C1CTRLbits.CANCKS = 1;   // Select the CAN Master Clock . It is equal to Fcy here.
        // equal to Fcy.(Fcy=30Mhz)

C1CFG1bits.SJW=00;    //Synchronized jump width time is 1 x TQ when SJW is equal to 00

C1CFG1bits.BRP = BRP_VAL;  //((FCY/(2*NTQ*BITRATE))-1)  
C1CFG2 = 0x03F5;               // SEG1PH=6Tq, SEG2PH=3Tq, PRSEG=5Tq
                                // Sample 3 times
                                // Each bit time is 15Tq
///Interrupt Section of CAN Peripheral
C1INTF = 0;     //Reset all The CAN Interrupts
IFS1bits.C1IF = 0;     //Reset the Interrupt Flag status register
C1INTE = 0x00FF;               //Enable all CAN interrupt sources
IEC1bits.C1IE = 1;    //Enable the CAN1 Interrupt

//-------------------------------------------------------------------------------------------------------------------
     //Initialization of CAN2 Module and Enabling of CAN2 Interrupts
//初始化CAN2模块和CAN2中断启用
//-------------------------------------------------------------------------------------------------------------------

C2CTRLbits.CANCKS = 1;   // Select the CAN Module Frequency Here CAN Master Clk is
        // equal to Fcy.(Fcy=30Mhz)
C2CFG1bits.SJW=00;       //Synchronized jump width time is 1 x TQ when SJW is equal to 00

C2CFG1bits.BRP = BRP_VAL;  //((FCY/(2*NTQ*BITRATE))-1)  

C2CFG2 = 0x03F5;                // SEG1PH=6Tq, SEG2PH=3Tq, PRSEG=5Tq
                                // Sample 3 times
                                // Each bit time is 15Tq
//CAN2 Interrupt Section
C2INTF = 0;     //Reset all The CAN Interrupts
IFS2bits.C2IF = 0;     //Reset the Interrupt Flag status register
C2INTE = 0x00FF;               //Enable all interrupt sources
IEC2bits.C2IE = 1;    //Enable the CAN2 Interrupt

//-----------------------------------------------------------------------------------------------------------------------
      // Configure Receive registers, Filters and Masks
//接收配置寄存器,过滤器和屏蔽器
//-----------------------------------------------------------------------------------------------------------------------
// We are initializing the Receive Buffer 0 and Receive Buffer 1 for CAN1 and CAN2
//我们为CAN1和CAN2初始化接收缓冲区和接收缓冲区的1, 0

C1RX0CON = C1RX1CON = C2RX0CON = C2RX1CON = 0x0000;  // Receive Buffer1 and 0 Status
               //and Control Register for CAN1 and CAN2

// Acceptance Mask Register0SID and Register1SID associated with Recieve Buffer0
// and Receive Buffer1 for CAN1 and CAN2
C1RXM0SID  = C1RXM1SID  = C2RXM0SID  = C2RXM1SID  = 0x1FFD;

// Acceptance Mask Register0EIDH and Register1EIDH associated with Recieve Buffer0
// and Receive Buffer1 for CAN1 and CAN2
C1RXM0EIDH = C1RXM1EIDH = C2RXM0EIDH = C2RXM1EIDH = 0x0FFF;
// Acceptance Mask Register0EIDL and Register1EIDL associated with Recieve Buffer0
//and Receive Buffer1 for CAN1 and CAN2
C1RXM0EIDL = C1RXM1EIDL = C2RXM0EIDL = C2RXM1EIDL = 0xFC00;

//Initializing of Acceptance Filter n Standard Identifier for CAN1
C1RXF0SID  = 0x0AA8; //CAN1 Receive Acceptance Filter2 SID   
C1RXF2SID  = 0x1555;   //CAN1 Receive Acceptance Filter2 SID
C1RXF2EIDH = 0x0004;   //CAN1 Receive Acceptace  Filter2 Extended Identifier high byte
C1RXF2EIDL = 0x8C00; //CAN1 Receive Acceptance Filter2 Extended identifier low byte
//Initializing of Acceptance Filter n Standard Identifier for CAN2
C2RXF0SID  = 0x0AA8; //CAN2 Receive Acceptance Filter0 SID  
C2RXF2SID  = 0x1555; //CAN2 Receive Acceptance Filter2 SID
C2RXF2EIDH = 0x0004;  //CAN2 Receive Acceptace  Filter2 Extended Identifier high byte
C2RXF2EIDL = 0x8C00; //CAN2 Receive Acceptance Filter2 Extended identifier low byte

//-----------------------------------------------------------------------------------------------------------------------
      // Configure Transmit Registers Buffer 0 and Transmit Buffer 1
//配置发送缓冲寄存器和发送缓冲器0, 1
//-----------------------------------------------------------------------------------------------------------------------
  
C1TX0CON = 0x0003;     // High priority
C1TX0SID = 0x50A8;     // SID
C1TX0EID = 0x0000;     // EID
C1TX0DLC = 0x01C0;  //Select the Data word Length for CAN1 Transmit Buffer0 which is 8 byte  

// Data Field 1,Data Field 2, Data Field 3, Data Field 4 // 8 bytes selected by DLC
C1TX0B1 = OutData0[0];
C1TX0B2 = OutData0[1];
C1TX0B3 = OutData0[2];
C1TX0B4 = OutData0[3];

C1TX1CON = 0x0002;             // High Intermediate priority
C1TX1SID = 0xA855;             // SID  
C1TX1EID = 0x0004;             // EID                  
C1TX1DLC = 0x8DA0;    //Select the Data word Length for CAN1 Transmit Buffer1 which
        // is 4 byte
//Data Field 1, Data Field 2 // 4 bytes selected by DLC
C1TX1B1 = OutData1[0];
C1TX1B2 = OutData1[1];

C2TX0CON = 0x0003;             // High priority
C2TX0SID = 0x50A8;             // SID = 01010101010 (0x2AA)
C2TX0EID = 0x0000;             // EID = 0000000000000000000 (0x00000)
C2TX0DLC = 0x01C0;    //Select the Data word Length for CAN2 Transmit Buffer0 which is
        // 8 byte
//Data Field 1,Data Field 2, Data Field 3, Data Field 4 // 8 bytes selected by DLC
C2TX0B1 = OutData2[0];
C2TX0B2 = OutData2[1];
C2TX0B3 = OutData2[2];
C2TX0B4 = OutData2[3];
  //Configure Transmit registers // Transmit Buffer 0 and Transmit Buffer 1 for CAN2

C2TX1CON = 0x0002;             // High Intermediate priority
C2TX1SID = 0xA855;             // SID = 10101010101 (0x555)
C2TX1EID = 0x0004;             // EID = 1110000000100100011 (0x00123)                  
C2TX1DLC = 0x8DA0;             //Select the Data word Length for CAN1 Transmit Buffer0 which is
        //8 byte   
//Data Field 1, Data Field 2 // 4 bytes selected by DLC

C2TX1B1 = OutData3[0];
C2TX1B2 = OutData3[1];
  
//Change to Loopback Operation Mode from Configuration Mode
// C1CTRLbits.REQOP = 0;
C2CTRLbits.REQOP = 0;
//while(C1CTRLbits.OPMODE != 0);//Wait for CAN1 mode change from Configuration Mode to Loopback mode
while(C2CTRLbits.OPMODE != 0);//Wait for CAN2 mode change from Configuration Mode to Loopback mode

//Enable transmission
//C1TX0CONbits.TXREQ = 1;        
//C1TX1CONbits.TXREQ = 1;
C2TX0CONbits.TXREQ = 1;        
C2TX1CONbits.TXREQ = 1;
while(1)
{
   
   
;     
                           
}                             //end while loop

}        //end main loop
//--------------------------------------------------------------------------------------------------------------------------
           //Interrupt Section for CAN1
//CAN1接收中断
//--------------------------------------------------------------------------------------------------------------------------
void __attribute__((interrupt, no_auto_psv)) _C1Interrupt(void)
{
      
  IFS1bits.C1IF = 0;         //Clear interrupt flag
      if(C1INTFbits.TX0IF)
      {
      
   C1INTFbits.TX0IF = 0;  //If the Interrupt is due to Transmit0 of CAN1 Clear the Interrupt
      }  
      else if(C1INTFbits.TX1IF)
      {
        
  C1INTFbits.TX1IF = 0;   //If the Interrupt is due to Transmit1 of CAN1 Clear the Interrupt
      }  
      if(C1INTFbits.RX0IF)
      {      
        
  C1INTFbits.RX0IF = 0;  //If the Interrupt is due to Receive0 of CAN1 Clear the Interrupt
        InData0[0] = C1RX0B1;
        InData0[1] = C1RX0B2;   //Move the recieve data from Buffers to InData
        InData0[2] = C1RX0B3;
        InData0[3] = C1RX0B4;
        if ((InData0[0]==OutData0[0]) && (InData0[1]==OutData0[1]) && (InData0[2]==OutData0[2]) && (InData0[3]==OutData0[3]))
      
            LATDbits.LATD0 = 0;     // If the data received is same which was transmitted
                                   // turn on the LED
      }
      else if(C1INTFbits.RX1IF)
      {      
        
  C1INTFbits.RX1IF = 0;   //If the Interrupt is due to Receive1 of CAN1 Clear the Interrupt
        InData1[0] = C1RX1B1;   //Move the data received to Indata Registers
        InData1[1] = C1RX1B2;
        if ((InData1[0]==OutData1[0]) && (InData1[1]==OutData1[1]))
      
           LATDbits.LATD1 =0;    //If the data received is same which was transmitted
                                 //turn on the LED
      }
}

//--------------------------------------------------------------------------------------------------------------------------
           //Interrupt Section for CAN2
////CAN2接收中断
//--------------------------------------------------------------------------------------------------------------------------
void __attribute__((interrupt, no_auto_psv)) _C2Interrupt(void)
{
      IFS2bits.C2IF = 0;         // Clear interrupt flag
      if(C2INTFbits.TX0IF)
      
   {
        
  C2INTFbits.TX0IF = 0;
      }  
      else if(C2INTFbits.TX1IF)
      {
        
  C2INTFbits.TX1IF = 0;  
      }  
      if(C2INTFbits.RX0IF)
      {      
      
  C2INTFbits.RX0IF = 0;
        InData2[0] = C2RX0B1;
        InData2[1] = C2RX0B2;
        InData2[2] = C2RX0B3;
        InData2[3] = C2RX0B4;
        if ((InData2[0]==OutData2[0]) && (InData2[1]==OutData2[1]) && (InData2[2]==OutData2[2]) && (InData2[3]==OutData2[3]))        
         
    LATDbits.LATD2 = 0;
      }
      else if(C2INTFbits.RX1IF)
      {      
        
  C2INTFbits.RX1IF = 0;
        InData3[0] = C2RX1B1;
        InData3[1] = C2RX1B2;
        if ((InData3[0]==OutData3[0]) && (InData3[1]==OutData3[1]))
        
           LATDbits.LATD3 = 0;        
      }
}


那位大侠女侠能不能指导下?联系QQ:601568698 帮忙看看?或则能够提供我个30F6011的CAN2通道的CAN通讯程序?简单的就行。。谢谢
沙发
电子三极管| | 2010-7-9 20:53 | 只看该作者
PIC16F877单片机的A/D基准电压设置成Vref+,Vref-作为输入基准, 程序该怎么写
我在论坛发过贴 没人能答复 所以来请教大师
https://bbs.21ic.com/icview-183343-1-1.html

使用特权

评论回复
板凳
headwolf_83| | 2010-7-11 17:50 | 只看该作者
8成是波特率问题。你再好好算算。

使用特权

评论回复
地板
headwolf_83| | 2010-7-11 17:52 | 只看该作者
或者这样,武汉吉阳光电有款USB转CAN的,可以测试波特率,你把这样的类似的设备和CAN节点分别连接,看看每个节点的波特率。如果是公司项目,去申请买一个吧,以后做事情很方便的。ZLG的,CAN转232的设备肯定没这个功能,其它转CAN的,应该有,才比较合理。

使用特权

评论回复
5
yihao470909597| | 2011-12-28 15:23 | 只看该作者
我也遇到和你一样的问题,求解!

使用特权

评论回复
6
XIEYUANBIN| | 2011-12-29 18:44 | 只看该作者
你可以用示波器查看你自己发送的波形,里面最小单位的高电平或低电平就是你的波特率最小单位。500K的周期应该是2微秒。如果不对就说明你自己波特率没设置好

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

5

帖子

1

粉丝