Board logo

标题: 请教9s12DG128CAN发送一直不能发送完毕问题 [打印本页]

作者: renxiaoyao    时间: 2008-5-19 15:38     标题: 请教9s12DG128CAN发送一直不能发送完毕问题

请教9s12DG128CAN发送一直不能发送完毕问题
我调试CAN,当两个或者三个单片机都接在CAN总线上时,通信良好,没有问题,可是当我仅有一个单片机时,同样的程序,就不行了,总是停留在while ((CAN0TFLG & txbuffer) != txbuffer);跳不出这个循环,不知道,为什么,但是用示波器发现,canh和canl也重复的发送一样的数据,示波器检测can0tx和can0rx也全部都有信号,好像发送缓存器不会为空。很怪啊,请求帮助,谢谢!
void initialcan(void) {
CAN0CTL0 = 0x01; /* Enter Initialization Mode
*
* 0b00000001
* ||||||||__ Enter Initialization Mode
* |||||||___ Sleep Mode Request bit
* ||||||____ Wake-Up disabled
* |||||_____ Time stamping disabled
* ||||______ Synchronized Status
* |||_______ CAN not affected by Wait
* ||________ Receiver Active Status bit
* |_________ Received Frame Flag bit
*/

while(CAN0CTL1_INITAK!=1); /* Wait for Initialization Mode acknowledge
* INITRQ bit = 1
*/

CAN0CTL1 = 0x80; /* Enable MSCAN module and not LoopBack Mode
*
* 0b10100000
* ||||||||__ Initialization Mode Acknowledge
* |||||||___ Sleep Mode Acknowledge
* ||||||____ Wake-up low-pass filter disabled
* |||||_____ Unimplemented
* ||||______ Listen Only Mode disabled
* |||_______ notLoop Back Mode enabled
* ||________ Ext Osc/Xtal as Clock Source
* |_________ MSCAN Module enabled
*/

CAN0BTR0 = 0x43; /* Synch Jump = 2 Tq clock Cycles
*
* 0b01000011
* ||||||||__
* |||||||___\
* ||||||____ |
* |||||_____ |_ CAN Clock Prescaler = 4
* ||||______ |
* |||_______ |
* ||________/
* |_________>- SJW = 2
*/

CAN0BTR1 = 0x14; /* Set Number of samples per bit, TSEG1 and TSEG2 (bit=187.5k)
*
* 0b00010100
* ||||||||__
* |||||||___|
* ||||||____|- TSEG1 = 5
* |||||_____|
* ||||______
* |||_______\_ TSEG2 = 2
* ||________/
* |_________ One sample per bit
*/

CAN0IDAC = 0x10; /* Set four 16-bit Filters
*
* 0b00010000
* ||||||||__
* |||||||___\_ Filter Hit Indicator
* ||||||____/
* |||||_____ Unimplemented
* ||||______
* |||_______>- Four 16-bit Acceptance Filters
* ||________
* |_________>- Unimplemented
*/

/* note Acceptance Filters neither Acceptance Filter is accorded with,message in receivebuffer will pass */

CAN0IDAR0 = 0; //|\ 16 bit Filter 0
CAN0IDMR0 = 0 ; //| \__ Accepts Standard Data Frame Msg
CAN0IDAR1 = 0; //| / with ID 0x100 ?
CAN0IDMR1 = 0; //|/

CAN0IDAR2 = 0; //|\ 16 bit Filter 1
CAN0IDMR2 = 0; //| \__ Accepts Standard Data Frame Msg
CAN0IDAR3 = 0; //| / with ID 0x000
CAN0IDMR3 = 0; //|/

CAN0IDAR4 = 0x84; //|\ 16 bit Filter 2
CAN0IDMR4 = 0x0f; //| \__ Accepts Standard Data Frame Msg
CAN0IDAR5 = 0x7E; //| / with ID 0x000
CAN0IDMR5 = 0x00; //|/

CAN0IDAR6 = 0; //|\ 16 bit Filter 3
CAN0IDMR6 = 0; //| \__ Accepts Standard Data Frame Msg
CAN0IDAR7 = 0; //| / with ID 0x000
CAN0IDMR7 = 0; //|/

CAN0CTL0 = 0x00; /* Exit Initialization Mode Request */
while ((CAN0CTL1&0x01) != 0){}; /* Wait for Normal Mode */
while(!(CAN0CTL0&0x10)); //note program always stop here
CAN0RFLG = 0xC3; /* Reset Receiver Flags
*
* 0b11000011
* ||||||||__ Receive Buffer Full Flag
* |||||||___ Overrun Interrupt Flag
* ||||||____
* |||||_____>- Transmitter Status Bits
* ||||______
* |||_______>- Receiver Status Bits
* ||________ CAN Status Change Interrupt Flag
* |_________ Wake-Up Interrupt Flag
*/

CAN0RIER = 0x01; /* Enable Receive Buffer Full Interrupt
*
* 0b00000001
* ||||||||__ Receive Buffer Full Int enabled
* |||||||___ Overrun Int disabled
* ||||||____
* |||||_____>- Tx Status Change disabled
* ||||______
* |||_______>- Rx Status Change disabled
* ||________ Status Change Int disabled
* |_________ Wake-Up Int disabled
*/

}
//-------------------------------sendframe-----------------------
int CAN0SendFrame(unsigned long id, unsigned char priority, unsigned char length, unsigned char *txdata ){


unsigned char index;
unsigned char txbuffer = {0};


if (!CAN0TFLG) /* Is Transmit Buffer full?? */
return 1;

CAN0TBSEL = CAN0TFLG; /* Select lowest empty buffer */
txbuffer = CAN0TBSEL; /* Backup selected buffer */

/* Load Id to IDR Registers */
*((unsigned long *) ((unsigned long)(&CAN0TXIDR0)))= id;

for (index=0;index<length;index++) {
*(&CAN0TXDSR0 + index) = txdata[index]; /* Load data to Tx buffer
* Data Segment Registers
*/
}

CAN0TXDLR = length; /* Set Data Length Code */
CAN0TXTBPR = priority; /* Set Priority */
CAN0TFLG = txbuffer; /* Start transmission */
while ((CAN0TFLG & txbuffer) != txbuffer); /* Wait for Transmission
* completion
*/
return 0;
}


作者: 大大的天空    时间: 2008-5-20 16:47

原因:

CAN总线发送数据帧包括7个不通的位场组合,即帧起始、仲裁场、控制场、数据场、CRC场、应答场、帧结束。其中数据场的长度可以为零。需要软件编程的有仲裁场,控制场,数据场。帧起始,CRC,应答场,帧结束由硬件完场。

帧起始标志数据帧和远程帧的起始,由一个单独的“显性”位组成。只有当总线空闲时,才允许站开始发送。所有站必须同步与首先发送信息站的帧起始前沿。

仲裁场包括11位标识符(标准格式)和远程发送请求位(RTR)。ID标识符的前7位不能全为隐性(至少有一个0)

控制场6个位,两个保留位,4个长度位。

数据场0~8个字节。每个字节8个位,首先发送高位。

CRC场,冗余码。由CAN控制器硬件自动生成。

应答场,长度包括两个位。包含应答间隙(ACK Slot)和应答界定符(ACK Delimiter),在应答场里,发送站发送两个“隐性”位。 如果接收器正确接收到有效报文时, 接收器就会在应答间隙(发送ACK信号期间)向发送器发送一“显性”位写入发送器的“隐性”位来做出回答。在应答间隙期间内,发送器需要至少收到一个CAN节点的的应答信号才认为是发送的数据被正确接收,否则认为数据丢失,自动重发数据。这些过程都由硬件完成无需设置。

如果想要单节点调试,则需把 CAN0CTL1 = 0x80; /* Enable MSCAN module and not LoopBack Mode 设置成为自循环模式。此时可以单节点调试。

不知道解释清楚没。


作者: chiusir    时间: 2008-9-5 13:46

请教9s12DG128CAN发送一直不能发送完毕问题
我调试CAN,当两个或者三个单片机都接在CAN总线上时,通信良好,没有问题,可是当我仅有一个单片机时,同样的程序,就不行了,总是停留在while ((CAN0TFLG & txbuffer) != txbuffer);跳不出这个循环,不知道,为什么,但是用示波器发现,canh和canl也重复的发送一样的数据,示波器检测can0tx和can0rx也全部都有信号,好像发送缓存器不会为空。很怪啊,请求帮助,谢谢!

-------------------------------
你这个程序我在自己的板子上试过,基本可以通讯的,即使使用一个单片机的两路CAN也是可以的,不过也就是能跑起来而已,有待完善。不知道你是否是漏掉了CAN BUS两端的两个120欧姆匹配电阻?

我出售MSCAN应用节点--淘宝店:http://shop36265907.taobao.com,欢迎交流!

[此贴子已经被作者于2008-9-5 13:48:48编辑过]






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