2015-09-18 12:58 AM
Hi,
I have difficulties to enable CAN module on STM32F I did not face problems with CAN module on STM32F1, STM32F2, STM32F4, but now I'm stuck on STM32F0. 1. First, I'm confused from the peripheral library examples. System core clock is configured at 48MHz, AHB and APB have DIV1, but in CAN initialization function is stated that CAN is clocked at 36MHz. Why?/* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 2;
2. Second, this is my CAN initialization function. Is there something wrong or missing?
(I'm not using interrupts).
CanTxMsg TxMessage = {0};
static void CAN_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CAN GPIOs configuration **************************************************/
/* Enable GPIO clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
/* Connect CAN pins to AF7 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_4);
/* Configure CAN RX and TX pins */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* NVIC configuration *******************************************************/
//NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;
//NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;
//NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//NVIC_Init(&NVIC_InitStructure);
/* CAN configuration ********************************************************/
/* Enable CAN clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
/* CAN register init */
CAN_DeInit(CAN);
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE;
CAN_InitStructure.CAN_ABOM = DISABLE;
CAN_InitStructure.CAN_AWUM = DISABLE;
CAN_InitStructure.CAN_NART = DISABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = DISABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
/* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */
CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 2;
/* CAN Baudrate = 1MBps (May be CAN clocked at 48 MHz) */
//CAN_InitStructure.CAN_BS1 = CAN_BS1_6tq;
//CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
//CAN_InitStructure.CAN_Prescaler = 4;
CAN_Init(CAN, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
/* Transmit Structure preparation */
TxMessage.StdId = 0x321;
TxMessage.ExtId = 0x01;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 1;
/* Enable FIFO 0 message pending Interrupt */
//CAN_ITConfig(CANx, CAN_IT_FMP0, ENABLE);
}
3. I need to use USB together with the CAN bus. What consideration must take in the source code for proper END point settings to not mess with last the 256 bytes of USB memory?
#stm32f042-can-usb
2015-09-18 05:45 AM
The 36 MHz comment is a hold-over from the APB clock on the STM32F1 device.
The CAN clock in all cases is dependent on the APB clock of the bus it's attached too, you divide down from there, and across the bit quanta.2015-09-18 06:54 AM
Thanks for the reply.
1. So, in the given example (in peripheral examples for STM32F072) CAN will not work at 1mbps, because APB is clocked 48MHz, but CAN bit-timming is for 36MHz APB (1+9+8)*2 = 36. 2. Is there anything wrong with PIN settings? 3. What about the shared memory (last 256 bytes) between CAN and USB. Please note that I'm using STM32F042C6T6.2015-09-18 06:56 AM
Thanks for the reply.
1. So, in the given example (in peripheral examples for STM32F072) CAN will not work at 1mbps, because APB is clocked 48MHz, but CAN bit-timming is for 36MHz APB (1+9+8)*2 = 36. 2. Is there anything wrong with PIN settings? 3. What about the shared memory (last 256 bytes) between CAN and USB. Please note that I'm using STM32F042C6T6.2015-09-18 08:04 AM
Look, I'm not using F0 parts, and I don't have any boards using the F042 with CAN interfaces.
You'll have to use the Prescaler and Bit Quanta settings to get the rates you want. You'll have to change them, or the APB clocks to get to specific speeds/timings. The timings would appear to get you 1 Mbps assuming a 36 MHz APB clock, so either reconfigure you system or PLL settings to get a 36 MHz APB clock, or refactor the prescaler and quanta to get 1 MBps from a 48 MHz clock.2015-09-18 09:43 AM
Thanks for your attention.
Problem solved. It was the hardware not the software. Also, about my 3th problem, I found that just must be careful with endpoint's addresses defined in usb_conf.h to not cross 768 byte boundary.