我想知道是否有人熟悉任何STM32f10x微控制器?
如果是这样,我在配置 CAN 驱动程序时遇到了一些问题。我可以运行设置为 loop_Back 模式的演示代码,但我无法让 Normal_Mode 工作。
我通读了所有的数据表,除了 CAN_MSR 寄存器中的 INAK 永远不会重置为 0 之外,一切都配置正确。如果需要,我可以提供更多详细信息,但首先我需要知道是否有人使用过 STM32F103 微控制器和 CAN 消息。
我想知道是否有人熟悉任何STM32f10x微控制器?
如果是这样,我在配置 CAN 驱动程序时遇到了一些问题。我可以运行设置为 loop_Back 模式的演示代码,但我无法让 Normal_Mode 工作。
我通读了所有的数据表,除了 CAN_MSR 寄存器中的 INAK 永远不会重置为 0 之外,一切都配置正确。如果需要,我可以提供更多详细信息,但首先我需要知道是否有人使用过 STM32F103 微控制器和 CAN 消息。
您将 Tx 引脚设置为 Out_PP,但应将其配置为备用功能。下面是我在 STM32F107 上的 CAN 初始化代码。我从现有项目中复制粘贴并剥离了它,因此不需要一些东西(就像不是所有的 GPIO 都需要启用)。另请注意,我使用重映射功能将 CAN Rx 和 Tx 引脚放在端口 D 上。
当使用 72 MHz 时钟时,此配置将总线速度设置为 500 kbit/s。
Int HardwareInit(void)
{
Int retval = 0;
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
ADC_InitTypeDef ADC_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
SystemInit();
/* Enable GPIOs clocks */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO, ENABLE);
/* 2 bit for pre-emption priority, 2 bits for subpriority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
CAN_DeInit(CAN1);
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 = ENABLE;
CAN_InitStructure.CAN_RFLM = DISABLE;
CAN_InitStructure.CAN_TXFP = ENABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 8;
CAN_Init(CAN1, &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);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0xFF;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0xFF;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOD, &GPIO_InitStructure);
GPIO_PinRemapConfig(GPIO_Remap2_CAN1 , ENABLE);
return retval;
}
然后可以像这样发送消息:
CanTxMsg TxMessage;
Nat8 mailbox;
TxMessage.StdId = 0x7E5;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.IDE=CAN_ID_STD;
TxMessage.Data[0] = 0x04;
TxMessage.Data[1] = (state) ? 0x01 : 0x00;
TxMessage.Data[2] = 0x00;
TxMessage.Data[3] = 0x00;
TxMessage.Data[4] = 0x00;
TxMessage.Data[5] = 0x00;
TxMessage.Data[6] = 0x00;
TxMessage.Data[7] = 0x00;
TxMessage.DLC = 8;
do
{
mailbox = CAN_Transmit(CAN1, &TxMessage);
}
while (mailbox == CAN_NO_MB);
接收是通过 IRQ 完成的:
CanRxMsg rx_message;
CAN_Receive(CAN1, CAN_FIFO0, &rx_message);
我使用过 STM32F103 微控制器,但我对 CAN 的唯一(小)经验是启用它会导致 USB 无法工作。这两个模块共享一个内存空间。因此,请确保禁用 USB 模块及其时钟(清除 RCC_APB1ENR 的第 23 位)。