0
\$\begingroup\$

I am very confused with the following scenario. I am using a PIC microcontroller, and I am transmitting a continuous sequence of messages. According to CAN protocol I need to give some time before I transmit the next message.

To solve this problem I started checking for the Tx buffer is full or free before transmitting. But my only problem is I can't continuously be in the while loop checking for the flag as there can be a possibility the bus is not available, and it can never come out of the while loop. How do I avoid this tricky situation? The microcontroller I am using is in the dsPIC family.

\$\endgroup\$
9
  • \$\begingroup\$ Wait until either the buffer is free or a certain time has elapsed since entering the loop. \$\endgroup\$
    – JimmyB
    Dec 8 '16 at 14:17
  • \$\begingroup\$ Could you not do other tasks while you're waiting for the buffer? \$\endgroup\$
    – user28910
    Dec 8 '16 at 14:18
  • \$\begingroup\$ I am not clear how much time i should wait. \$\endgroup\$
    – rajesh
    Dec 8 '16 at 14:19
  • 2
    \$\begingroup\$ Learn about how interrupts works.. \$\endgroup\$
    – m.Alin
    Dec 8 '16 at 14:28
  • 2
    \$\begingroup\$ You are essentially asking how to write microcontroller programs. This scenario is nothing unique to CAN. In situations like these, you have a few options: polling, interrupts or DMA. DMA is usually the best solution but there might not be hardware support on it for the specific peripheral. Interrupts should only be used as a necessary evil when you have critical real-time requirements - they come with numerous disadvantages. The option left is polling, which can be done by a single check or a repeated check, depending on program design. \$\endgroup\$
    – Lundin
    Dec 9 '16 at 8:07
2
\$\begingroup\$

The CAN standard doesn't require you wait. The CAN hardware controller takes care of collisions.

Perhaps your own CAN protocol needs delay in-between messages? You did not specify the application.

If you need to know if the message left the CAN controller you use, check the manual. There is a status bit or interrupt option when the message actually left.

Lastly, there should be no while (1) loops in embedded design. Execute your main loop forever, and your sending routine can check if the message left (and do what you need to do), then immediately return to the main loop so other functions can execute. Read on using a state machine style of programming, which is great practice, unless you use real-time OS like FreeRTOS.

\$\endgroup\$
3
  • \$\begingroup\$ I would suggest you post a schematic, not a frizzy thing. It appears from your question you do not have a CAN controller, if not the structure of your code will be different then if you have one. The controller takes care of the acknowledge, filters, etc for you. You might read the Bosh speck on CAN 2.0 or later. I notice you send a continuous stream of messages, but nothing about the required ACK did I miss something or you just using the CAN physical layer. CAN cannot work without an acknowledge to its message, that is part of the protocol. \$\endgroup\$
    – Gil
    Feb 14 at 19:11
  • \$\begingroup\$ @Gil did you really mean to comment on this answer or on the question? Also, since OP mentions a check for "transmit buffer is full", I am pretty sure there is a CAN controller there. In fact, dsPIC has CAN FD controller, if I am not mistaken. \$\endgroup\$
    – Maple
    Oct 18 at 20:45
  • \$\begingroup\$ On the question. I have come across CAN done without a controller such as the MPC2515. The schematic would answer that and many other questions. \$\endgroup\$
    – Gil
    Oct 18 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.