完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
您好,我在DSIC33 EP512MU810编译器上遇到的一些问题是XC16 GCC V1.31,当我启动PIC并发送CAN消息时,CAN控制器总是在一些消息(50…500)之后停止接收数据,在C1RxFul1中不再设置任何比特,在C1INTF中不再设置INT标志,也没有错误计数。ER是递增的,并且没有设置错误INT标志,CAN控制器似乎已经死了。但是传入的消息仍然正确地被确认。这与波特率、定时设置和ID-过滤器无关。如果CAN触发器仅被配置为接收,则其行为相同。同样的行为也在不同的板上。从PIC WorkFink发送数据。函数“Chan-RCVI消息”被称为每一个MS,传入的测试消息具有100ms的周期。当问题发生时,我在CFG模式中手动设置CAN控制器,并返回正常模式,而不做任何操作。介于两者之间,它又开始重复了一段时间。在将CAN控制器从我的代码初始化到数据表中的示例时,我看不出有什么不同。我不知道,有人能帮助我吗?最好是:我没有许可,附加文件????
以上来自于百度翻译 以下为原文 Hello, i have some problems with the ECAN on a dsPIC33EP512MU810 compiler is XC16-gcc V1.31 When i start the pic and send can-messages to it, the Can-controller always stops receiving data after some messages (50...500), no more bit in C1RXFUL1 is set, no more Int-Flag is set in C1INTF, also no err-counter is incremented and no error-int-flag is set, the can-controller seems to be dead. but incoming messages are still correctly acknowledged. this is independent from Baudrate, timing-settings and ID-filters. if the Can-contoller is only configured for receive, its the same behaviour. The same behaviour is also on different Boards. Sending Data from the pic works fine. the function "can_rcv_message" is called every ms, the incoming test-messages have a cycle of 100ms. when the problem occures and i set the can-controller manually in cfg-mode and back in normal-mode, without doing anything in between, it starts receving again for some time. I can't see any difference in initializing the can-controller from my code to the examples in the datasheet. i have no more idea, can anyone help me? best regards Karl PS: i have no permission, to attach files ??? /* * File: can1.c * Author: k0017150 * * Created on 12. September 2017, 15:34 */ #include "system.h" #define _CAN1_ 1 #include "can1.h" #undef _CAN1_ #define NUM_OF_ECAN_BUFFERS 32 #define RX_BUF_NR 8 #define OPMODE_CFG 0x04 #define OPMODE_RUN 0x00 static unsigned int ecan1msg_buf_tx[NUM_OF_ECAN_BUFFERS][8] __attribute__((aligned(NUM_OF_ECAN_BUFFERS * 16))); static unsigned int ecan1msg_buf_rx[NUM_OF_ECAN_BUFFERS][8] __attribute__((aligned(NUM_OF_ECAN_BUFFERS * 16))); static int can_is_init; static UNS32 can_rcv_counter,can_send_counter,can_int_counter; static can_message_struct dbg_cms; static void can1_start(void) // just for test { C1CTRL1bits.REQOP = OPMODE_CFG; while(C1CTRL1bits.OPMODE != OPMODE_CFG); C1CTRL1bits.REQOP = OPMODE_RUN; while(C1CTRL1bits.OPMODE != OPMODE_RUN); } void can1_init(void) { _TRISF2=0; // tx ->output RPOR8bits.RP98R=0x0E; //TX -> RF3 RP99 _TRISF3=1; // rx ->input RPINR26bits.C1RXR=0x63; //RX -> RA2 RPI18 // Set up the ECAN1 module to operate at 500 kbps. The ECAN module should be first placed in configuration mode. C1CTRL1 = 0; C1CTRL1bits.REQOP = OPMODE_CFG; while(C1CTRL1bits.OPMODE != OPMODE_CFG); C1CTRL1bits.WIN = 0; C1CTRL1bits.CANCKS = 1; // bit ist invers zu datenblatt! C1CFG1 = 0; C1CFG1bits.BRP = 4; //Fcy=50MHz, 1Bit=10Tq=2µs n = Tq[ns]/40-1 C1CFG1bits.SJW = 1; //SyncJumpWitdh = 1Tq C1CFG2 = 0; C1CFG2bits.SEG2PH = 2; // PhaseSeg2 = 2TQ C1CFG2bits.SEG2PHTS = 1; // PhaseSeg2 = free programmable C1CFG2bits.SAM = 1; // 1 sample at samplepoint C1CFG2bits.SEG1PH = 2; // PhaseSeg1 = 3TQ C1CFG2bits.PRSEG = 2; // PropagationSeg = 3Tq C1FCTRL = 0; C1FCTRLbits.FSA = 0x1F; // no fifo C1FCTRLbits.DMABS = 0x06; // 32 buffer /* Assign 32x8word Message Buffers for ECAN1 in device RAM. This example uses DMA0 for TX DMA1 for RX. */ DMA0CONbits.SIZE = 0x0; DMA0CONbits.DIR = 0x1; DMA0CONbits.AMODE = 0x2; DMA0CONbits.MODE = 0x0; DMA0REQ = 70; DMA0CNT = 7; DMA0PAD = (volatile unsigned int)&C1TXD; DMA0STAL = (unsigned int) &ecan1msg_buf_tx; DMA0STAH = (unsigned int) &ecan1msg_buf_tx; DMA0CONbits.CHEN = 0x1; /* Configure Message Buffer 0 for Transmission and assign priority */ C1TR01CONbits.TXEN0 = 0x1; C1TR01CONbits.TX0PRI = 0x3; DMA1CONbits.SIZE = 0x0; DMA1CONbits.DIR = 0x0; DMA1CONbits.AMODE = 0x2; DMA1CONbits.MODE = 0x0; DMA1REQ = 34; DMA1CNT = 7; DMA1PAD = (volatile unsigned int)&C1RXD; DMA1STAL = (unsigned int) &ecan1msg_buf_rx; DMA1STAH = (unsigned int) &ecan1msg_buf_rx; DMA1CONbits.CHEN = 0x1; C1CTRL1bits.WIN = 1; // Clear Window Bit to Access ECAN Control Registers C1FMSKSEL1bits.F0MSK=0x0; // Select Acceptance Filter Mask 0 for Acceptance Filter 0 // C1RXM0SIDbits.SID = 0x7F8; // Configure Acceptance Filter Mask 0 register to mask SID<2:0> * Mask Bits (11-bits) : 0b111 1111 1000 // Configure Acceptance Filter 0 to match standard identifier (11-bits): 0b011 1010 xxx with the mask setting, message with SID range 0x1D0-0x1D7 accepted C1RXM0SIDbits.SID = 0x000; //test ohne filter C1RXF0SIDbits.SID = 0x01D0; // Acceptance Filter 0 to check for Standard Identifier C1RXM0SIDbits.MIDE = 0x1; C1RXF0SIDbits.EXIDE= 0x0; C1BUFPNT1bits.F0BP = RX_BUF_NR; /* Acceptance Filter 0 to use Message Buffer RX_BUF_NR to store message */ C1FEN1bits.FLTEN0=0x1; /* Filter 0 enabled for Identifier match with incoming message */ C1CTRL1bits.WIN = 0; /* Clear Window Bit to Access ECAN Control Registers */ C1CTRL1bits.REQOP = OPMODE_RUN; /* At this point the ECAN1 module is ready to transmit a message. Place the ECAN module in Normal mode. */ while(C1CTRL1bits.OPMODE != OPMODE_RUN); C1RXFUL1 = C1RXFUL2 = C1RXOVF1 = C1RXOVF2 = 0x0000; can_is_init=1; } INT16 can1_rcv_message(can_message_struct *cms) { UNS16 result=0; if(can_is_init){ result = C1RXFUL1 & (1< C1INTFbits.RBIF=0; can_rcv_counter++; cms->id = (ecan1msg_buf_rx[RX_BUF_NR][0]>>2) & 0x7ff; cms->dlc = ecan1msg_buf_rx[RX_BUF_NR][2]&0x0f; cms->data[0]=(BYTE)(ecan1msg_buf_rx[RX_BUF_NR][3]&0xff); cms->data[1]=(BYTE)((ecan1msg_buf_rx[RX_BUF_NR][3]>>8)&0xff); cms->data[2]=(BYTE)(ecan1msg_buf_rx[RX_BUF_NR][4]&0xff); cms->data[3]=(BYTE)((ecan1msg_buf_rx[RX_BUF_NR][4]>>8)&0xff); cms->data[4]=(BYTE)(ecan1msg_buf_rx[RX_BUF_NR][5]&0xff); cms->data[5]=(BYTE)((ecan1msg_buf_rx[RX_BUF_NR][5]>>8)&0xff); cms->data[6]=(BYTE)(ecan1msg_buf_rx[RX_BUF_NR][6]&0xff); cms->data[7]=(BYTE)((ecan1msg_buf_rx[RX_BUF_NR][6]>>8)&0xff); C1RXFUL1 &= (~(1< }else{ can_int_counter++; } } return(result); } INT16 can1_send_message(can_message_struct *cms) { int cnt=0,erg=0; if(can_is_init){ // std-id ecan1msg_buf_tx[0][0] = (cms->id << 2)&0x1ffc; // ext-id ecan1msg_buf_tx[0][1] = 0x0000; //dlc ecan1msg_buf_tx[0][2] = (cms->dlc)&0x0f; /* Write message data bytes */ ecan1msg_buf_tx[0][3] = (UNS16)cms->data[0] + (((UNS16)cms->data[1]) << 8); ecan1msg_buf_tx[0][4] = (UNS16)cms->data[2] + (((UNS16)cms->data[3]) << 8); ecan1msg_buf_tx[0][5] = (UNS16)cms->data[4] + (((UNS16)cms->data[5]) << 8); ecan1msg_buf_tx[0][6] = (UNS16)cms->data[6] + (((UNS16)cms->data[7]) << 8); /* Request message buffer 0 transmission */ C1TR01CONbits.TXREQ0 = 0x1; /* The following shows an example of how the TXREQ bit can be polled to check if transmission is complete. */ do{ erg=C1TR01CONbits.TXREQ0; }while((erg == 1) && (cnt++ < 30000)); erg=!erg; C1INTFbits.TBIF=0; } if(erg) can_send_counter++; return(erg); } void can1_setup(void) { int ic,l,ready=0,nab=1; if(can_is_init==0){ init_page("LA61","ecan1","ESC=end space=send"); text(1,1,COLOR_NORMAL,"CAN not available !"); get_ch(); return; } do{ if(nab){ init_page("LA61","ecan1","ESC=end space=send"); nab=0; } l=3; text(1,l++,COLOR_NORMAL,"TxCounter: %06lu",can_send_counter); text(1,l++,COLOR_NORMAL,"TxErr: %d",C1TR01CONbits.TXERR0); text(1,l++,COLOR_NORMAL,"TxReq: %d",C1TR01CONbits.TXREQ0); text(1,l++,COLOR_NORMAL,"tx-err-cnt: %05d",C1EC>>8); l++; text(1,l++,COLOR_NORMAL,"RxCounter: %06lu",can_rcv_counter); text(1,l++,COLOR_NORMAL,"RxIntCounter: %06lu",can_int_counter); text(1,l++,COLOR_NORMAL,"C1RXFUL1: 0x%04X",C1RXFUL1); text(1,l++,COLOR_NORMAL,"C1RXOVF1: 0x%04X",C1RXOVF1); text(1,l++,COLOR_NORMAL,"rx-err-cnt: %05d",C1EC&0xff); text(1,l++,COLOR_NORMAL,"C1INTF: 0x%04X",C1INTF); l++; text(1,l++,COLOR_NORMAL,"rx-tel: 0x%03X-%d-0x%02X 0x%02X 0x%02X 0x%02X",dbg_cms.id,dbg_cms.dlc,dbg_cms.data[0],dbg_cms.data[1],dbg_cms.data[2],dbg_cms.data[3]); ic=get_ch_or_fail(); switch(ic){ case FN_Esc: ready=1; break; case 'i': can1_start(); nab=1; break; case ' ': { can_message_struct cms; cms.id = 0x182; cms.dlc = 3; cms.data[0]++; cms.data[1]++; cms.data[2]++; can1_send_message(&cms); } break; case 'r': break; } }while(!ready); } |
|
相关推荐
4个回答
|
|
可能是DMA勘误表吗?也就是说,由于错误,缓冲区不能(或可以)在DMA空间中。
以上来自于百度翻译 以下为原文 Could it be the DMA errata? i.e. buffers can't (or can) be in DMA space due to errata. |
|
|
|
嗨,这是你的第一个罐头设计还是以前做过其他的?要检查的一件事是已知的用于DSPIC33 EP512MU810 CAN模块的勘误表:http://WW1.Microchip .com /…EVICEDOC/8000 526G.PDF.有几个问题被记录在案。请检查这些问题与您使用的CAN,看看是否有任何这些问题可能有关。请描述您的硬件(收发器,你使用?)电缆长度?当做
以上来自于百度翻译 以下为原文 Hi, Is it your first CAN design or did you do some others before ? One thing to check are the known errata for dsPIC33EP512MU810 CAN module : http://ww1.microchip.com/...eviceDoc/80000526g.pdf There are several issues which are documented. Please check these issues against your usage of CAN to see if any of these issues could be related. Please describe your hardware (which transceiver do you use ?). Length of cable ? Regards |
|
|
|
嗨,我有20年的经验,但这是第一次在PIC上实现。达里奥你给了我一个决定的提示:我已经阅读了关于CAN总线的勘误表,但问题是DMA模块。有时,当总线仲裁器在OffjType中保存总线时,RCV中断会丢失。我已经将DMA优先级设置为MAX,现在它从200000个消息开始工作。
以上来自于百度翻译 以下为原文 Hi, i have experience with can since 20 years, but this is the first implementation on a pic. Dario you gave me the deciding hint: i have read the errata concerning the can-bus, but the problem was the dma-module. Sometimes can-rcv-interrupts are lost, when the bus-arbiter holds the bus in OFF_state. I have set the dma-priority to max and now it works since 200000 Messages. thanks a lot regards Karl |
|
|
|
|
|
|
|
只有小组成员才能发言,加入小组>>
5161 浏览 9 评论
1999 浏览 8 评论
1928 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3171 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2226 浏览 5 评论
731浏览 1评论
613浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
503浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
629浏览 0评论
527浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 21:45 , Processed in 1.319159 second(s), Total 85, Slave 68 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号