kulpanov
Mar 12 2011, 15:44
Всем привет, проблема с 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
Mar 12 2011, 23:59
Попробуйте CAN_H с CAN_L поменять местами... Встречался с подобной проблемой, в документации на плату неточность обозначения подключения CAN.
SasaVitebsk
Mar 13 2011, 21:55
Работал с stm32f107 + IXXAT.
Плата самодельная. Всё работало.
Если IXXAT подключён неверно, то светодиоды светятся красным. Иначе зелёным с подмаргиванием в момент посылки.
Сам IXXAT вызывает кучу нареканий. Прогу, под него, писали свою. Если что-то включено не так, то работать не будет.
Зелёным светится, по моему даже если нет передачи и когда скорость неверная. Главное чтобы скомутировано было верно.
При себе сейчас нет - пишу по памяти.
kulpanov
Mar 14 2011, 06:02
Менял CAN_H и CAN_L. не то.
>Плата самодельная. Всё работало.
APB1 clock на сколько Mhz задавали?
Кварц задающий на сколько ставили?
Судя по всему там неточность в тактировании CAN. копаем.
2_kulpanov
примеры для ТерраэЭлектрониковких Барракуды и Махаона писал я. задача примераов стояла так - проверить передачу данных CAN1 <-> CAN2 и исправность микросхем и правильность монтааж. с CAN писал первый раз(были непонятки с фильтрами - здесь народ подяснил что я не так делаю, спасибо), тоесть может чтото еще нужно дописывать чтоб работало понастоящему. не стоит этот код воспинимать как образец. для меня CAN неактуален - медленный, нераспространенный, поэтому нет времени разабратся по полной и написать качественные "дрова" для компонентного использования.
когда разберетесь обязательно описательное эссе и код в студию. а то такие вопросы у всех всплывают в начале 'творческого пути'. нада это фиксировать для всех.
Ваше письмо я получил, его переслали из терры. здесь отвечаю.
garry_
Mar 14 2011, 10:02
У вас скорее всего по другому настроена скорость, так сам на себя работае а на другие адаптеры нет
вот рабочий вариант
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
Mar 14 2011, 12:45
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_
Mar 14 2011, 13:09
Кварц 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)
}
, настройка скорости кан выше
Если интересуют настрйки без использования 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
Mar 14 2011, 21:15
Надёргал из проекта.
Писал на скорую руку - использовал библиотеки 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
Mar 17 2011, 06:36
Всем большое спасибо за помощь, в след. раз пригодится, мне или еще кому. Пока актуальность пропала. Такое бывает.
Цитата(kulpanov @ Mar 17 2011, 09:36)

Всем большое спасибо за помощь, в след. раз пригодится, мне или еще кому. Пока актуальность пропала. Такое бывает.
так что? заработало? или CAN потерял актуальность? или весь проект потерял актуальность?
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.