Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: stm32f107vct непонятки с CAN, ч.2
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
kulpanov
Всем привет, проблема с CAN, кто сталкивался с проблемой подскажите.
Модуль Barracuda на stm32f107vc от TerraElectronica.
Среда Eclipse(gcc)+jLink. Пытаюсь запустить CAN.
Скажу сразу для МК без ОС делаю, что то впервые.
Поначалу всё шло успешно, код дернутый с их примера Web-сервера
успешно передавал данные из порта в порт: CAN1->CAN2, CAN2->CAN1.
Но вот дальше данные идтить отказываются!
Поясню: подключаю IXXAT usb-to-can, ноль эмоций. Т.е. порты друг другу данные шлют ixxat их не видит.
Сам ixxat данные послать не может.
Со скоростью CAN разобрался, помогли примеры из IAR, кстати примеры из IAR также успешно пересылают данные и ixxat также их не видит.
Если эту железку воткнуть в рабочую CAN сеть - вся сеть начинает глючить.
Сам ixxat рабочий, пакеты от CAN-приводов и иных контроллеров ловит/передаёт изумительно. От barracuda отказывается.
В terre ничего вразумительного не говорят.
Сам не электронщик, и очень не хочется думать, что дело в проводах. Но если это так. подскажите как terru [CENSORED] схватить.
Я думаю что примеры кода у всех одни и те-же, я их практически не правил, но если надо выложу.

Собственно help me!
KiLLD0WN
Попробуйте CAN_H с CAN_L поменять местами... Встречался с подобной проблемой, в документации на плату неточность обозначения подключения CAN.
SasaVitebsk
Работал с stm32f107 + IXXAT.
Плата самодельная. Всё работало.
Если IXXAT подключён неверно, то светодиоды светятся красным. Иначе зелёным с подмаргиванием в момент посылки.
Сам IXXAT вызывает кучу нареканий. Прогу, под него, писали свою. Если что-то включено не так, то работать не будет.
Зелёным светится, по моему даже если нет передачи и когда скорость неверная. Главное чтобы скомутировано было верно.
При себе сейчас нет - пишу по памяти.
kulpanov
Менял CAN_H и CAN_L. не то.

>Плата самодельная. Всё работало.
APB1 clock на сколько Mhz задавали?
Кварц задающий на сколько ставили?
Судя по всему там неточность в тактировании CAN. копаем.
klen
2_kulpanov
примеры для ТерраэЭлектрониковких Барракуды и Махаона писал я. задача примераов стояла так - проверить передачу данных CAN1 <-> CAN2 и исправность микросхем и правильность монтааж. с CAN писал первый раз(были непонятки с фильтрами - здесь народ подяснил что я не так делаю, спасибо), тоесть может чтото еще нужно дописывать чтоб работало понастоящему. не стоит этот код воспинимать как образец. для меня CAN неактуален - медленный, нераспространенный, поэтому нет времени разабратся по полной и написать качественные "дрова" для компонентного использования.

когда разберетесь обязательно описательное эссе и код в студию. а то такие вопросы у всех всплывают в начале 'творческого пути'. нада это фиксировать для всех.

Ваше письмо я получил, его переслали из терры. здесь отвечаю.
garry_
У вас скорее всего по другому настроена скорость, так сам на себя работае а на другие адаптеры нет
вот рабочий вариант
CODE
/*
*  predefined baud rates (recommended by CiA)
*  16Mhz CAN clock for STM32F103xx (ARM Cortex M3 core)
*
*   Tbit = (TS1 + TS2 +3)(BRP +1)/Fcan
*   TS1, TS2, BRP - corresponding fields of CAN_BTR register
*/
#define BCI_1M_bt0    0x01
#define BCI_1M_bt1    0x14

#define BCI_800K_bt0  0x01
#define BCI_800K_bt1  0x16

#define BCI_500K_bt0  0x01
#define BCI_500K_bt1  0x1c

#define BCI_250K_bt0  0x03
#define BCI_250K_bt1  0x1c

#define BCI_125K_bt0  0x07
#define BCI_125K_bt1  0x1c

#define BCI_50K_bt0   0x13
#define BCI_50K_bt1   0x1c

#define BCI_20K_bt0   0x31
#define BCI_20K_bt1   0x1c

#define BCI_10K_bt0   0x63
#define BCI_10K_bt1   0x1c

void CANSetBaud( unsigned char bt0, _unsigned char bt1)
{    
      CAN->BTR = (u32) ( ((_u32) bt1 << 16) | ((u32) bt0) );
}


Собственно help me!
[/quote]
kulpanov
to klen: собственно к вам претензий нет, я плату не у вас покупал, вам кстати за сборку тулсов для eclipse отдельное спасибо, без шуток.
Вопрос к терре, на который они ответит не могут, никак, сделали железку как работает не знают, общается только сама с собой!.

> У вас скорее всего по другому настроена скорость
Это то я осознал, дело действительно в частоте задания для CAN, частота не попадает ни в одну рабочую. Я уж перебор всех доступных частот CAN перебрал, IXXAT не фиксирует ничего.

Пока дозрели до перепайки кварца с 25 на 16 mhz - без толку, но мне об этом сложно говорить я совсем не железячник.
Тут люди на my.st.com пишут:
Carsten Schumann> With a APB of 36 MHZ you are out of the specs for the CAN controller which needs 8 MHz clock (or a multiple of that). Try using 32 MHz APB clock (= SystemClock 64MHz) and you will be fine.
Кто можь подксажет как таку частоту сделать?
garry_
Кварц 8 мгц, настройки pll
CODE
void SysClk_Config(void) // RCC_Configuration
{  
    ErrorStatus HSEStartUpStatus;
      
    RCC_DeInit(); //set default
    // 1. Clocking the controller from internal HSI RC (8 MHz)
      RCC_HSICmd(ENABLE);
      while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY) == RESET); // wait until the HSI is ready
      RCC_SYSCLKConfig(RCC_SYSCLKSource_HSI);

    // 2. Enable ext. high frequency OSC
    RCC_HSEConfig(RCC_HSE_ON);                         // Enable HSE
      HSEStartUpStatus = RCC_WaitForHSEStartUp();     // Wait till HSE is ready
    if(HSEStartUpStatus == SUCCESS)
   {
#ifdef  VECT_TAB_FLASH  
        // 5. Init Embedded Flash
        // Zero wait state, if 0 < HCLK 24 MHz
        // One wait state, if 24 MHz < HCLK 56 MHz
        // Two wait states, if 56 MHz < HCLK 72 MHz
        // Flash wait state
       FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait state  
       FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
//        FLASH_HalfCycleAccessCmd(FLASH_HalfCycleAccess_Disable); // Half cycle access
#endif     
       RCC_HCLKConfig(RCC_SYSCLK_Div1);// HCLK = SYSCLK = 64MHz  
       RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK   = 64MHz
        RCC_PCLK1Config(RCC_HCLK_Div4); // PCLK1 = HCLK/4  = 16MHz
       RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_8); // HCLK = PLLCLK = 8MHz * 8 = 64 MHz  
        RCC_PLLCmd(ENABLE); // Enable PLL  
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)// Wait till PLL is ready
        {
        }
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source
        while(RCC_GetSYSCLKSource() != 0x08) // Wait till PLL is used as system clock source
        {
        }
    }
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);     //Enable AFIO clock (PCLK2)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);    //Enable GPIOA clock (PCLK2)
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);    //Enable GPIOB clock (PCLK2)
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);    //Enable GPIOC clock (PCLK2)
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//Enable USART1 clock (PCLK2)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); //Enable SPI1 clock (PCLK2)

      RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //Enable USART3 clock (PCLK1)
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);      //Enable CAN clock (PCLK1)
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // TIM2 clock enable(PCLK1)
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); // TIM3 clock enable(PCLK1)
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); // TIM4 clock enable(PCLK1)
}

, настройка скорости кан выше
Axel
Если интересуют настрйки без использования ST-шных либов, то вот мои (кварц 12 MHz):
CODE
static void RCC_Config()
{
FLASH->ACR |= FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY_1; //flash latency = 2 wait states
RCC->CR = RCC_CR_HSEON;

RCC->CFGR = RCC_CFGR_MCO_PLL | RCC_CFGR_USBPRE | RCC_CFGR_PLLMULL9 | RCC_CFGR_PLLXTPRE |
RCC_CFGR_PLLSRC | RCC_CFGR_PPRE2_DIV2 | RCC_CFGR_PPRE1_DIV2;

while (!(RCC->CR & RCC_CR_HSERDY));
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY));
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & (RCC_CFGR_SWS_HSE | RCC_CFGR_SWS_PLL)) != RCC_CFGR_SWS_PLL);
//Enable clocking of the peripherals
RCC->APB2ENR = RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN |
RCC_APB2ENR_USART1EN | RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN;
RCC->APB1ENR = RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN | RCC_APB1ENR_TIM4EN | RCC_APB1ENR_USART2EN |
RCC_APB1ENR_CANEN | RCC_APB1ENR_BKPEN | RCC_APB1ENR_PWREN;
RCC->AHBENR = RCC_AHBENR_FLITFEN | RCC_AHBENR_CRCEN | RCC_AHBENR_DMA1EN;
PWR->CR |= PWR_CR_DBP;
}


/*
Parameters:
u8 quantum number
u32 baud rate
u8 tseg1
u8 tseg2
u8 sjw
*/
void CAN_HwSetup(u8 *param)
{
u32 bpr;
u8 tseg1, tseg2, sjw;

CAN->MCR = (CAN_MCR_NART | CAN_MCR_INRQ | CAN_MCR_TXFP); // init mode, disable auto. retransmission
CAN->IER = (CAN_IER_FMPIE0 | CAN_IER_TMEIE); // FIFO 0 msg pending, Transmit mbx empty


if(!param) // 1Mb by default
{
bpr = 2;
tseg1 = 12;
tseg2 = 5;
sjw = 4;
}
else
{
bpr = (36000000 / param[4]) / (param[0] + ((u32)param[1] << 8) + ((u32)param[2] << 16) + ((u32)param[3] << 24));
tseg1 = param[5];
tseg2 = param[6];
sjw = param[7];
}

CAN->BTR = bpr | (((u32)tseg1 -1) << 16) | (((u32)tseg2 - 1) << 20) | (((u32)sjw - 1) << 24);
}
SasaVitebsk
Надёргал из проекта.
Писал на скорую руку - использовал библиотеки stm. Собственно там и ч/з регистры ничего сложного нет. Когда работал - там всё понятно было.
И фильтра там красиво сделаны.

CODE

#define OSC 8000000L // Частота кварца
#define CCLK (OSC*9) // Частота ядра контроллера
#define PCLK (CCLK/2) // Частота переферии

...
void RCC_Configuration(void)
{

/* GPIO clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO |
RCC_APB2Periph_GPIOA |
RCC_APB2Periph_GPIOB |
RCC_APB2Periph_GPIOC |
RCC_APB2Periph_GPIOD |
RCC_APB2Periph_GPIOE, ENABLE);

/* CAN1 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
/* CAN2 Periph clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);

/* TIM2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

/* ADCCLK = PCLK2/8 */
RCC_ADCCLKConfig(RCC_PCLK2_Div8);

/* Enable ADC1 and GPIOC clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

/* Enable DMA1 clock */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

}


void GPIO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/* Configure CAN1 pin: RX */
GPIO_InitStructure.GPIO_Pin = CAN1_GPIO_Pin_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(CAN1_GPIO, &GPIO_InitStructure);

/* Configure CAN1 pin: TX */
GPIO_InitStructure.GPIO_Pin = CAN1_GPIO_Pin_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(CAN1_GPIO, &GPIO_InitStructure);

/* Configure CAN2 pin: RX */
GPIO_InitStructure.GPIO_Pin = CAN2_GPIO_Pin_RX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(CAN2_GPIO, &GPIO_InitStructure);

/* Configure CAN2 pin: TX */
GPIO_InitStructure.GPIO_Pin = CAN2_GPIO_Pin_TX;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(CAN2_GPIO, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOA, &GPIO_InitStructure);

}

...
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
....

void CAN_Config(void)
{
/* CAN register init */
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 = 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_InitStructure.CAN_BS1 = CAN_BS1_3tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
CAN_InitStructure.CAN_Prescaler = 16; // 250 кбит
CAN_Init(CAN1, &CAN_InitStructure);

/* CAN filter 0 init */
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh= (PCAN_ID_PC1>>13) & 0xffff;
CAN_FilterInitStructure.CAN_FilterIdLow= (PCAN_ID_PC1<<3) & 0xffff;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0780;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);

/* transmit */
TxMessage.StdId = 0;
TxMessage.ExtId = 0;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 1;

}


void Init_RxMes(CanRxMsg *RxMessage)
{
uint8_t i = 0;

RxMessage->StdId = 0x00;
RxMessage->ExtId = 0x00;
RxMessage->IDE = CAN_ID_STD;
RxMessage->DLC = 0;
RxMessage->FMI = 0;
for (i = 0;i < 8;i++)
RxMessage->Data[i] = 0x00;
}


kulpanov
Всем большое спасибо за помощь, в след. раз пригодится, мне или еще кому. Пока актуальность пропала. Такое бывает.
klen
Цитата(kulpanov @ Mar 17 2011, 09:36) *
Всем большое спасибо за помощь, в след. раз пригодится, мне или еще кому. Пока актуальность пропала. Такое бывает.

так что? заработало? или CAN потерял актуальность? или весь проект потерял актуальность?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.