Hi, good morning,
I'm tryin to setup de flexcan in a MCU52255CAF. I have a problem setting the baud rate in the microcontroller. I've followed the chapter "32 Flexcan from MCF52259RM."
I can't communicate two devices over the can with MCF52259.
I configure the registers with the follow data.
Use external Clock of 25Mhz.
Ftq = 25 / (10 + 1) ; Preescaler: 10.(Eqn32-6)
BitRate : Ftq / ( 1 + 11 + 4) (Eqn32-7)
When I send data over the can, I meassure the wide of 1 bit with the osciloscope, and I get a wide of 25uS.
I change the preescaler, and always I get the same wide, I think that, i'm not configuring correctly the baudrate in the register.
What I'm doing wrong?
You should tell us the exact hex number that you're writing to CANCTRL so we can check your figures. If not you actual initialisation code.
You should also tell us your external crystal frequency, and what you have the internal Fsys running at, in case CLK_SRC is set wrong and you're using Fsys.
I assume by "external clock" you mean the crystal frequency, as there's no separate "external clock" that can be used for CAN on this chip.
Are you following "32.4"? You should only change the clock source when the controller is DISABLED. You should only change anything else in the configuration when the module is in FREEZE mode. The module may be ignoring your writes if you're writing to the registers when it is running. Have you tried reading them back after you've written them?
You are programming a bit rate of 25MHz/(10 * 16) or 156.25 kHz. That isn't a standard baud rate for CAN. The usual rates are 125, 250, 5000 and 1000 kHz. Are you sure that's what you want? If you're getting a 25us bit rate (40 kHz) and are programming 16 quanta/bit, then PRESDIV must be dividing by 39, so PRESDIV must be 38 (0x26).
> Ftq / ( 1 + 11 + 4)
I'd like to see PRESDIV, PSEG1, PSEG2, PROPSEG, RJW and CLK_SRC at a minimum. So what is CANCTRL?
Tom
Hi, Tom, Thanks for your answer.
I want to configure a bitrate of 250kbps. And I'm using the Oscillator connected to pin EXTAL. And its have a 25MHz.
I'm using the code include in the flexcan driver include in the initialization of my project. I attach, the code bellow.
MCF_FlexCAN_CANMCR = MCF_FlexCAN_CANMCR_SOFTRST;
while ((MCF_FlexCAN_CANMCR & MCF_FlexCAN_CANMCR_SOFTRST) != 0x00)
;
MCF_FlexCAN_CANMCR = MCF_FlexCAN_CANMCR_MDIS | MCF_FlexCAN_CANMCR_MAXMB(0xF);
while ((MCF_FlexCAN_CANMCR & MCF_FlexCAN_CANMCR_NOTRDY) !=
MCF_FlexCAN_CANMCR_NOTRDY);
\*---------------------------------------------------------*/
//MCF_FlexCAN_CANCTRL &= ~(MCF_FlexCAN_CANCTRL_CLK_SRC);
MCF_FlexCAN_CANCTRL |= MCF_FlexCAN_CANCTRL_PRESDIV(5)|
MCF_FlexCAN_CANCTRL_RJW(3)|
MCF_FlexCAN_CANCTRL_PSEG1(4)|
MCF_FlexCAN_CANCTRL_PSEG2(3)|
MCF_FlexCAN_CANCTRL_PROPSEG(5);
/* MCF_FlexCAN_CANCTRL |= MCF_FlexCAN_CANCTRL_PRESDIV(10)| // Prescaler seleccionado a 11
MCF_FlexCAN_CANCTRL_RJW(3)| // 3 + 1 TQclock Resynch Jumps
MCF_FlexCAN_CANCTRL_PSEG1(4)| // PSEG1 a 4
MCF_FlexCAN_CANCTRL_PSEG2(3)| // PSEG2 a 3
MCF_FlexCAN_CANCTRL_PROPSEG(5)| // PROPSEG a 5
MCF_FlexCAN_CANCTRL_LOM |
MCF_FlexCAN_CANCTRL_LBUF
MCF_FlexCAN_CANCTRL_CLK_SRC; */
// MBuf Initialization
MCF_FLEXCAN_BUFFERS.MB0.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA LEECTURA.
MCF_FLEXCAN_BUFFERS.MB1.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA LEECTURA.
MCF_FLEXCAN_BUFFERS.MB2.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA LEECTURA.
MCF_FLEXCAN_BUFFERS.MB3.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA LEECTURA.
MCF_FLEXCAN_BUFFERS.MB4.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA LEECTURA.
MCF_FLEXCAN_BUFFERS.MB5.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA LEECTURA.
MCF_FLEXCAN_BUFFERS.MB6.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA LEECTURA.
MCF_FLEXCAN_BUFFERS.MB7.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FLEXCAN_BUFFERS.MB8.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FLEXCAN_BUFFERS.MB9.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FLEXCAN_BUFFERS.MB10.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FLEXCAN_BUFFERS.MB11.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FLEXCAN_BUFFERS.MB12.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FLEXCAN_BUFFERS.MB13.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FLEXCAN_BUFFERS.MB14.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FLEXCAN_BUFFERS.MB15.u16CtrlStat = MB_CTRLSTAT_CODE(0x0); //BUFFERS HABILITADOS PARA ESCRUTURA.
MCF_FlexCAN_RXGMASK = 0xFFFFFFFF;
//MCF_FLEXCAN_BUFFERS.MB1.u16CtrlStat = MB_CTRLSTAT_CODE(0x0);
//MCF_FLEXCAN_BUFFERS.MB1.u32ID.u32ExtID = MB_STANDARD_ID(0x140); /* ID 0x140 */
//MCF_FLEXCAN_BUFFERS.MB1.u16CtrlStat = MB_CTRLSTAT_CODE(0x4);
MCF_FlexCAN_CANMCR &= ~(MCF_FlexCAN_CANMCR_MDIS);
while ((MCF_FlexCAN_CANMCR & MCF_FlexCAN_CANMCR_NOTRDY) != 0x00)
;
I asked:
> You should tell us the exact hex number that you're writing to CANCTRL
You haven't done that. Instead:
//MCF_FlexCAN_CANCTRL &= ~(MCF_FlexCAN_CANCTRL_CLK_SRC);
MCF_FlexCAN_CANCTRL |= MCF_FlexCAN_CANCTRL_PRESDIV(5)|
MCF_FlexCAN_CANCTRL_RJW(3)|
MCF_FlexCAN_CANCTRL_PSEG1(4)|
MCF_FlexCAN_CANCTRL_PSEG2(3)|
MCF_FlexCAN_CANCTRL_PROPSEG(5);
I don't know what CLK_SRC you're using because you've commented out that line.
I have no idea what value you're writing into that register as you're OR-ing the above into whatever was previously in that register.
Which from the results you've been getting, wasn't zero to start with.
If you want to set the register to the above values then get rid of the "|=" or show all the code back to the first one that uses "=" to set the entire register.
Also, since you didn't include the macro sources, I have no idea what those macros are doing. They may be taking raw register bit values or they may be taking the "add one" values. I'm not using the same development environment or compiler that you are. I can't read your header files.
You should find a way to READ the register and then print it out in hex somewhere, or simply examine it in the debugger. Then use the Reference Manual to decode it to see if it is what you want.
(Edit) Explaining what I mean about the macros, the ones I'm using date from 2004, and define the PSEG fields this way:
/* Bit definitions and macros for MCF_CAN_CANCTRL */
#define MCF_CAN_CANCTRL_PROPSEG(x) (((x)&0x00000007)<<0)
#define MCF_CAN_CANCTRL_LOM (0x00000008)
#define MCF_CAN_CANCTRL_LBUF (0x00000010)
#define MCF_CAN_CANCTRL_TSYNC (0x00000020)
#define MCF_CAN_CANCTRL_BOFFREC (0x00000040)
#define MCF_CAN_CANCTRL_SAMP (0x00000080)
#define MCF_CAN_CANCTRL_LPB (0x00001000)
#define MCF_CAN_CANCTRL_CLKSRC (0x00002000)
#define MCF_CAN_CANCTRL_ERRMSK (0x00004000)
#define MCF_CAN_CANCTRL_BOFFMSK (0x00008000)
#define MCF_CAN_CANCTRL_PSEG2(x) (((x)&0x00000007)<<16)
#define MCF_CAN_CANCTRL_PSEG1(x) (((x)&0x00000007)<<19)
#define MCF_CAN_CANCTRL_RJW(x) (((x)&0x00000003)<<22)
#define MCF_CAN_CANCTRL_PRESDIV(x) (((x)&0x000000FF)<<24)
These macros abstract the raw bitfields. But to set PSEG1 to 4 bits, you still have to write "3" in that macro. A different programmer might have thought to make this easier by defining the macros this way:
#define MCF_CAN_CANCTRL_PROPSEG(x) ((((x)-1)&0x00000007)<<0)
#define MCF_CAN_CANCTRL_PSEG2(x) ((((x)-1)&0x00000007)<<16)
#define MCF_CAN_CANCTRL_PSEG1(x) ((((x)-1)&0x00000007)<<19)
#define MCF_CAN_CANCTRL_RJW(x) ((((x)-1)&0x00000003)<<22)
That would have allowed you to use the numbers "6, 5, 4" to get field values "5, 4, 3" which would result in time quanta of "6, 5, 4" adding up to 16 (with the Sync bit) as you want. But unless there's documentation saying which method the programmer followed, you have to look at the macros to be sure it is correct. Luckily you got that bit right.
Tom