Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: CAN stm32f207
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Log_in
Доброго времени суток. Разбираюсь с CAN на плате терраэлектроникс с кристаллом stm32F207. Наблюдается такая ситуация. На выходе CAN посылки идут не с интервалам, а как будто кучей. Даже если единожды запустить команду CAN_Transmit(CAN1, &TxMessage), то на выходе сигнал есть постоянно. Если использовать режим Loopback, то посылка выходит одна. Но даже в этом случае он никак не распознается устройством, ловящим все посылки CAN на заданной скорости. Само устройство точно работает http://can.marathon.ru/. Я уже грешу на настройку скорости, тактовой системы. Может кто знает, в чем причина?
CODE
#include "stm32f2xx.h"

void GPIO_Init_TE(void);
void USART_Init_TE(void);
void CAN1_Config(void);
void RCC_Configuration(void);


CanTxMsg TxMessage;
CanRxMsg RxMessage;

int main()
{
long int foi=0;
RCC_Configuration();

CAN1_Config();

GPIO_Init_TE();

/* Transmit Structure preparation */
TxMessage.StdId = 0x321;
TxMessage.ExtId = 0x01;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 1;

TxMessage.Data[0] = 0;
TxMessage.Data[1] = 1;
TxMessage.Data[2] = 2;
TxMessage.Data[3] = 3;
TxMessage.Data[4] = 4;
TxMessage.Data[5] = 5;
TxMessage.Data[6] = 6;
TxMessage.Data[7] = 7;

while(1)
{
for(foi=0; foi<100000000;foi++);
CAN_Transmit(CAN1, &TxMessage);

}
}

void GPIO_Init_TE(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd((RCC_AHB1Periph_GPIOB) , ENABLE);

//лампочка
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);

}


void CAN1_Config(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

/* Connect PD1 to CAN1_Tx pin */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
/* Connect PD0 to CAN1_Rx pin */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);

/* Configure CAN RX and TX pins */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

/* CAN configuration */
/* Enable CAN clock */
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 |RCC_APB1Periph_CAN2, ENABLE);

/* CAN register init */
CAN_DeInit(CAN1);

/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE; //Включение или отключение времени срабатывает режим связи
CAN_InitStructure.CAN_ABOM = DISABLE; //Включить или отключить автоматическое управление bus-off
CAN_InitStructure.CAN_AWUM = DISABLE; //Включить или выключить режим автоматического пробуждению
CAN_InitStructure.CAN_NART = DISABLE; //Включить или выключить режим без автоматического повтора передачи.
CAN_InitStructure.CAN_RFLM = DISABLE; //Включение или отключение Locked режим приема FIFO.
CAN_InitStructure.CAN_TXFP = DISABLE; //Включить или выключить приоритет передачи FIFO
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //Определяет режим работы CAN

CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
// CAN Baudrate = 1MBps (CAN clocked at 30 MHz)
//BaudRate=1/[ t_pclk(BRP +1)(1+bs1+1+bs2+1) ]
CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; //3----это TS1
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq; //4----это TS2
CAN_InitStructure.CAN_Prescaler = 23; //2----это BRP
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);

}

void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
RCC_ClocksTypeDef RCC_ClockFreq;
// Сбрасываем клокинг в "0"
RCC_DeInit();
// Включаем внешний кварц
RCC_HSEConfig(RCC_HSE_ON);
// Ждём пока устанавливается внешний ВЧ тактовый сигнал
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus != ERROR)
{
// Внешний тактовый сигнал появился, стабильный
// разрешаем использование буфера команд
FLASH_PrefetchBufferCmd(ENABLE);
//-------------------------------------------------------------------
// итак
//Внешний кварц 25МГц
//Тактовая частота ядра: 120МГц
//-------------------------------------------------------------------
/* Flash 2 wait state двойная задержка*/
FLASH_SetLatency(FLASH_Latency_2);

RCC_HCLKConfig(RCC_SYSCLK_Div1); /* HCLK = SYSCLK AHB clock = SYSCLK=120*/

RCC_PCLK1Config(RCC_HCLK_Div4); //APB1 clock = HCLK/4 120/4=30 для CAN

//RCC_PLLSource_HSE=25 - источник для PLL, PLLM=25, PLLN=240, PLLP=2, PLLQ=5
// HSE/PLLM=VCO, VCO*PLLN/PLLP=PLLCLK, VCO*PLLN/PLLQ=PLL48CK см. 48 стр мануала
RCC_PLLConfig(RCC_PLLSource_HSE,25, 240, 2, 5);
//Разрешаем PLL
RCC_PLLCmd(ENABLE);

// Ждём пока устаканится PLL
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY ) == RESET)
{}
// PLL - устаканился
// Выбираем PLL как источник тактирования системы
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

// Ждём пока PLL не станет клокингом системы
while (RCC_GetSYSCLKSource() != 0x08)
{}
}
RCC_GetClocksFreq(&RCC_ClockFreq);

}
Neborak
Цитата(Log_in @ Jan 14 2014, 17:18) *
Доброго времени суток. Разбираюсь с CAN на плате терраэлектроникс с кристаллом stm32F207. Наблюдается такая ситуация. На выходе CAN посылки идут не с интервалам, а как будто кучей. Даже если единожды запустить команду CAN_Transmit(CAN1, &TxMessage), то на выходе сигнал есть постоянно. Если использовать режим Loopback, то посылка выходит одна. Но даже в этом случае он никак не распознается устройством, ловящим все посылки CAN на заданной скорости. Само устройство точно работает http://can.marathon.ru/. Я уже грешу на настройку скорости, тактовой системы. Может кто знает, в чем причина?

Подобная ситуация может возникнуть в случае, если второй узел не подтверждает принятое сообщение, тогда, отправитель "долбит" пачками с паузами. И в случае если скорость отправителя (или какого-то из получателей) не правильно настроена, но тогда должна появиться ошибка приема на втором узле.
ZASADA
никто АСК в ответ на сообщение не присылает, поэтому идет переповтор передачи.
Log_in
Но ведь параметр CAN_InitStructure.CAN_NART установлен в DISABLE. Или это что-то другое?
Neborak
Цитата(Log_in @ Jan 14 2014, 18:45) *
Но ведь параметр CAN_InitStructure.CAN_NART установлен в DISABLE. Или это что-то другое?

Остальные узлы должны подтвердить получение сообщения.
mantech
Цитата(Log_in @ Jan 14 2014, 17:18) *
Само устройство точно работает http://can.marathon.ru/.


Может несколько не в тему, но с теми прогами, которые на этом сайте, может работать только их устройство или можно просто подключить драйвер к ком-порту?
Log_in
Проблема решена. Как вы и говорили, дело было в отсутствии ответа. Когда искал причину наткнулся на хорошую литературу по этому поводу( полная статья на английском и сокращенная на русском http://www.micromax.ru/articles/article.sh...te/Can_kvazer_1, http://www.kvaser.com/en/about-can/the-can...ol/15.html(есть картинки сигналов осциллографа). А не было ответа по банальнейшей причине! На плате терраэлектроники нет распиновки для СAN выхода. В начале перепробовал обе комбинации, но плата не работала тогда еще по другой причине, поэтому оставил как было. А сейчас это и стало камнем преткновения.)) Зато досконально разобрался и тактированием и настройкой скорости CAN.) Прилагаю работающий код.
Да, и так программа (http://can.marathon.ru/.) работает только с родным устройством.
CODE
#include "stm32f2xx.h"


void GPIO_Init_TE(void);
void CAN1_Config(void);
void RCC_Configuration(void);

int flag_RCC;

CanTxMsg TxMessage;
CanRxMsg RxMessage;


int main()
{
long int foi=0;
short int n_CAN_Tx=20;
flag_RCC=0;
RCC_Configuration();



CAN1_Config();
GPIO_Init_TE();
if(flag_RCC==1)
{
GPIO_SetBits(GPIOB, GPIO_Pin_9);
}
//GPIOB->BSRRL = GPIO_Pin_9;
/* Transmit Structure preparation */
TxMessage.StdId = 0x00;
TxMessage.ExtId = 0x01;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;

TxMessage.Data[0] = 0xFF;
TxMessage.Data[1] = 0;
TxMessage.Data[2] = 2;
TxMessage.Data[3] = 3;
TxMessage.Data[4] = 4;
TxMessage.Data[5] = 5;
TxMessage.Data[6] = 6;
TxMessage.Data[7] = 12;

//CAN_Transmit(CAN1, &TxMessage);
while(1)
{
for(foi=0; foi<10000000;foi++);
if(n_CAN_Tx !=0)
{
CAN_Transmit(CAN1, &TxMessage);
n_CAN_Tx--;
}
}
}

void GPIO_Init_TE(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd((RCC_AHB1Periph_GPIOB) , ENABLE);

//лампочка
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB, &GPIO_InitStructure);

}


void CAN1_Config(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

/* Connect PD1 to CAN1_Tx pin */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_CAN1);
/* Connect PD0 to CAN1_Rx pin */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_CAN1);

/* Configure CAN RX and TX pins */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOD, &GPIO_InitStructure);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);

/* CAN configuration */
/* Enable CAN clock */
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 |RCC_APB1Periph_CAN2, ENABLE);

/* CAN register init */
CAN_DeInit(CAN1);

/* CAN cell init */
CAN_InitStructure.CAN_TTCM = DISABLE; //Включение или отключение времени срабатывает режим связи
CAN_InitStructure.CAN_ABOM = DISABLE; //Включить или отключить автоматическое управление bus-off
CAN_InitStructure.CAN_AWUM = DISABLE; //Включить или выключить режим автоматического пробуждению
CAN_InitStructure.CAN_NART = DISABLE; //Включить или выключить режим без автоматического повтора передачи.
CAN_InitStructure.CAN_RFLM = DISABLE; //Включение или отключение Locked режим приема FIFO.
CAN_InitStructure.CAN_TXFP = DISABLE; //Включить или выключить приоритет передачи FIFO
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; //Определяет режим работы CAN

CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
// CAN Baudrate = 125 (CAN clocked at 30 MHz)
//BaudRate=1/[ t_pclk(BRP +1)(1+TS1+1+TS2+1) ]
CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq; //----это (4=TS1+1)
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq; //----это (5=TS2+1)
CAN_InitStructure.CAN_Prescaler = 24; //----это (24=BRP+1)
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);

}

void RCC_Configuration(void)
{
ErrorStatus HSEStartUpStatus;
RCC_ClocksTypeDef RCC_ClockFreq;
// Сбрасываем клокинг в "0"
RCC_DeInit();
// Включаем внешний кварц
RCC_HSEConfig(RCC_HSE_ON);
// Ждём пока устанавливается внешний ВЧ тактовый сигнал
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus != ERROR)
{

// Внешний тактовый сигнал появился, стабильный
// разрешаем использование буфера команд
FLASH_PrefetchBufferCmd(ENABLE);
//-------------------------------------------------------------------
// итак
//Внешний кварц 25МГц
//Тактовая частота ядра: 120МГц
//-------------------------------------------------------------------
/* Flash 2 wait state двойная задержка*/
FLASH_SetLatency(FLASH_Latency_2);

RCC_HCLKConfig(RCC_SYSCLK_Div1); /* HCLK = SYSCLK AHB clock = SYSCLK=120*/

RCC_PCLK1Config(RCC_HCLK_Div4); //APB1 clock = HCLK/4 120/4=30 для CAN

//RCC_PLLSource_HSE=25 - источник для PLL, PLLM=25, PLLN=240, PLLP=2, PLLQ=5
// HSE/PLLM=VCO, VCO*PLLN/PLLP=PLLCLK, VCO*PLLN/PLLQ=PLL48CK см. 48 стр мануала
RCC_PLLConfig(RCC_PLLSource_HSE,25, 240, 2, 5);
//Разрешаем PLL
RCC_PLLCmd(ENABLE);

// Ждём пока устаканится PLL
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY ) == RESET)
{}
// PLL - устаканился
// Выбираем PLL как источник тактирования системы
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

// Ждём пока PLL не станет клокингом системы
while (RCC_GetSYSCLKSource() != 0x08)
{}

}
RCC_GetClocksFreq(&RCC_ClockFreq);

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