STM32F103 微控制器 CAN 消息

发布于 2024-11-10 18:39:15 字数 232 浏览 5 评论 0原文

我想知道是否有人熟悉 STM32f10x 微控制器?

如果是这样,我在配置 CAN 驱动程序时遇到了一些问题。我可以运行设置为loop_Back模式的演示代码,但我无法让Normal_Mode工作。

我通读了所有数据表,除了 CAN_MSR 寄存器中的 INAK 从未重置为 0 之外,所有内容都配置正确。如果需要,我可以提供更多详细信息,但首先我需要知道是否有人使用过 STM32F103 微控制器和 CAN 消息。

I am wondering if anyone is familiar with any STM32f10x micro-controllers?

If so, I am having some problems configuring a CAN driver. I can run the demo code, which is set to a loop_Back mode, but I cannot get Normal_Mode to work.

I read through all the data sheets, and everything is configured correctly except the INAK in the CAN_MSR register never resets to 0. I can provide more detail if needed, but first I need to know if there is someone who has worked with a STM32F103 microcontroller and CAN messages.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

感悟人生的甜 2024-11-17 18:39:15

您将 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);

You set the Tx pin as Out_PP, but it should be configured as Alternate Function instead. Below is my init code for CAN on an STM32F107. I copy-pasted and stripped it from an existing project so some stuff is not needed (like not all GPIOs need to be enabled). Also note I used the remap function to put the CAN Rx and Tx pins on port D.

This configuration sets the bus speed to 500 kbit/s when using a 72 MHz clock.

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;
}

Sending a message can then be done like this:

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);

Receiving is done via IRQ:

CanRxMsg rx_message;
CAN_Receive(CAN1, CAN_FIFO0, &rx_message);
贩梦商人 2024-11-17 18:39:15

我曾使用过 STM32F103 微控制器,但我对 CAN 的唯一(少量)经验是启用它会导致 USB 无法工作。两个模块共享内存空间。因此,请确保禁用 USB 模块及其时钟(清除 RCC_APB1ENR 的位 23)。

I've worked with STM32F103 microcontrollers but my only (small) experience with CAN was that enabling it caused USB not to work. The two modules share a memory space. So make sure you disable the USB module and the clock to it (clear bit 23 of RCC_APB1ENR).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文