Сообщения микроконтроллера STM32F103 CAN - PullRequest
2 голосов
/ 01 июня 2011

Мне интересно, знаком ли кто-нибудь с какими-либо микроконтроллерами STM32f10x?

Если это так, у меня возникли некоторые проблемы при настройке драйвера CAN.Я могу запустить демонстрационный код, который установлен в режим loop_Back, но я не могу заставить работать Normal_Mode.

Я прочитал все таблицы данных, и все настроено правильно, кроме INAK в регистре CAN_MSR, никогдасбрасывает на 0. Я могу предоставить более подробную информацию, если это необходимо, но сначала мне нужно узнать, есть ли кто-то, кто работал с микроконтроллером STM32F103 и сообщениями CAN.

Ответы [ 2 ]

2 голосов
/ 15 июля 2011

Вы устанавливаете вывод Tx как Out_PP, но вместо этого он должен быть настроен как альтернативная функция. Ниже мой код инициализации для CAN на STM32F107. Я скопировал и удалил его из существующего проекта, так что некоторые вещи не нужны (например, не все GPIO должны быть включены). Также обратите внимание, что я использовал функцию remap для установки контактов CAN Rx и Tx на порт D.

Эта конфигурация устанавливает скорость шины на 500 кбит / с при использовании тактовой частоты 72 МГц.

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);
2 голосов
/ 01 июня 2011

Я работал с микроконтроллерами STM32F103, но мой единственный (небольшой) опыт работы с CAN состоял в том, что его включение приводило к тому, что USB не работал. Два модуля совместно используют пространство памяти. Поэтому убедитесь, что вы отключили USB-модуль и часы к нему (очистите бит 23 RCC_APB1ENR).

...