реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> CAN на STM32, скрость передачи по CAN
DmitryDI
сообщение Mar 23 2011, 15:20
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 789



Все сконфигурировал как в исходниках, но не работает. Чип STM32F107, кварц 25 Мгц, Нужен 1 МГбит/c

Настройки
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_16tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 1;

Скорость = 25 МГц/(1+16+8) = 1 МГбит/c

Обмена данных с проверенным мастером нет. ???
Заранее спасибо за помощь.

конфигурация полностью
CODE

void CAN_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

/* Configure CAN1 and CAN2 IOs **********************************************/
/* GPIOB, GPIOD and AFIO clocks enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB, ENABLE);

/* Configure CAN1 RX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOD, &GPIO_InitStructure);

/* Configure CAN2 RX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/* Configure CAN1 TX pin */
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);

/* Configure CAN2 TX pin */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/* Remap CAN1 and CAN2 GPIOs */
GPIO_PinRemapConfig(GPIO_Remap2_CAN1 , ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_CAN2, ENABLE);

/* Configure CAN1 and CAN2 **************************************************/
/* CAN1 and CAN2 Periph clocks enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1 | RCC_APB1Periph_CAN2, ENABLE);

/* CAN1 and CAN2 register init */
CAN_DeInit(CAN1);
CAN_DeInit(CAN2);

/* Struct init*/
CAN_StructInit(&CAN_InitStructure);

/* CAN1 and CAN2 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 = ENABLE;
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_16tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler = 1;//2

/*Initializes the CAN1 and CAN2 */
CAN_Init(CAN1, &CAN_InitStructure);
CAN_Init(CAN2, &CAN_InitStructure);


/* CAN1 filter init */
CAN_FilterInitStructure.CAN_FilterNumber = 1;
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_FIFO0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);

/* CAN2 filter init */
CAN_FilterInitStructure.CAN_FilterIdHigh =0x2460;
CAN_FilterInitStructure.CAN_FilterNumber = 15;
CAN_FilterInit(&CAN_FilterInitStructure);

/* Transmit */
TxMessage.StdId = 0x01;
TxMessage.ExtId = 0x01;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 8;
}



/**
* @brief Configures the NVIC for CAN.
* @param None
* @retval None
*/
void NVIC_Config(void)
{
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

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

NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x1;
NVIC_Init(&NVIC_InitStructure);
}

int main()
{

NVIC_Config();
/* CANs configuration */
CAN_Config();

/* IT Configuration for CAN1 */
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);

/* IT Configuration for CAN2 */
CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);

while(1)
{
TxMessage.Data[0] = 0x55;
CAN_Transmit(CAN1, &TxMessage);
Delay(1000);

}
}


Сообщение отредактировал IgorKossak - Mar 23 2011, 19:26
Причина редактирования: Оформление кода в [codebox]
Go to the top of the page
 
+Quote Post
zksystem
сообщение Mar 23 2011, 16:20
Сообщение #2


embedder
***

Группа: Свой
Сообщений: 264
Регистрация: 11-05-05
Из: Казань
Пользователь №: 4 911



Вот Вам кусок моей инициализации, проверял с адаптером IXXAT:

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

/* 125kb
CAN_InitStructure.CAN_SJW = CAN_SJW_4tq; //1
CAN_InitStructure.CAN_BS1 = CAN_BS1_12tq; //3 (1..16)
CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq; //5 (1..8)
CAN_InitStructure.CAN_Prescaler = 16;//4
*/

//1Mbit
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 = 4;

CAN_Init(CAN1, &CAN_InitStructure);

/* set BTR register so that sample point is at about 72% bit time from bit start */
/* TSEG1 = 12, TSEG2 = 5, SJW = 4 => 1 CAN bit = 18 TQ, sample at 72% */

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

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

}


P.S. Исходник древний, так что не пинайте если что...

Сообщение отредактировал IgorKossak - Mar 23 2011, 19:27
Причина редактирования: Оформление кода в [codebox]


--------------------
Мечты стареют куда быстрее мечтателей… Стивен Кинг. "Ловец снов"
Go to the top of the page
 
+Quote Post
Forger
сообщение Mar 23 2011, 20:30
Сообщение #3


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Вот мой код (рабочий):

CODE


CAN_TypeDef * baseCAN1 = (CAN_TypeDef*)((UNSIGNED32)0x40006400);

enum TSystemFrequency
{
SYSTEM_FREQUENCY_12MHz = (12 * 1000000L),
SYSTEM_FREQUENCY_24MHz = (24 * 1000000L),
SYSTEM_FREQUENCY_36MHz = (36 * 1000000L),
SYSTEM_FREQUENCY_48MHz = (48 * 1000000L),
SYSTEM_FREQUENCY_56MHz = (56 * 1000000L),
SYSTEM_FREQUENCY_64MHz = (64 * 1000000L),
SYSTEM_FREQUENCY_72MHz = (72 * 1000000L)
};

enum TCANBaudRate
{
BR_10Kbps = (UNSIGNED32)10000L,
BR_20Kbps = (UNSIGNED32)20000L,
BR_50Kbps = (UNSIGNED32)50000L,
BR_100Kbps = (UNSIGNED32)100000L,
BR_125Kbps = (UNSIGNED32)125000L,
BR_250Kbps = (UNSIGNED32)250000L,
BR_500Kbps = (UNSIGNED32)500000L,
BR_800Kbps = (UNSIGNED32)800000L,
BR_1000Kbps = (UNSIGNED32)1000000L,
};

struct TCANFrame
{
union
{
UNSIGNED16 communicationObjectId; // Поддерживается только 11-битный ID
struct
{
UNSIGNED nodeId : 7;
UNSIGNED functionCode : 4;
};
};
bool isRemoteTransmitionRequest;

UNSIGNED8 dataLength;
union
{
UNSIGNED8 dataPayload08[8];
UNSIGNED16 dataPayload16[4];
UNSIGNED32 dataPayload32[2];
UNSIGNED64 dataPayload64[1];
};
};



////////////////////////////////////////////////////////////////////////////////////////////////////////////////


void THardwareSTM32::initializeCAN(TCANBaudRate baudRate)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

// CAN1 Periph clock enable
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);

// CAN register init
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);

// CAN cell init
CAN_InitStructure.CAN_TTCM = DISABLE; // Time triggered communication mode
CAN_InitStructure.CAN_ABOM = DISABLE; // Automatic bus-off managemen
CAN_InitStructure.CAN_AWUM = DISABLE; // Automatic wake-up mode
CAN_InitStructure.CAN_NART = DISABLE; // No automatic retransmission
CAN_InitStructure.CAN_RFLM = DISABLE; // Receive FIFO locked mode
CAN_InitStructure.CAN_TXFP = DISABLE; // Transmit FIFO priority
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
CAN_InitStructure.CAN_Prescaler = (_systemFrequency / 2 / baudRate / 9); // CAN_SJW_1tq + CAN_BS1_4tq + CAN_BS2_4tq
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 interrupts init
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE); // FIFO 0 message pending interrupt


// Разрешить прерывания от приемника CAN1
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

#ifdef DEBUG
CAN_DBGFreeze(CAN1, ENABLE);
#endif
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool THardwareSTM32::sendCANFrame(TCANFrame & frame)
{
// Ждать освобождения буфера передатчика CAN_PORT1
while ((baseCAN1->TSR & TSR_TME0) != TSR_TME0);

// Transmit mailbox 0 busy?
// if ((baseCAN1->TSR & TSR_TME0) != TSR_TME0)
// return (CANBufferTx.put(frame));

// Разрешить прерывание USB_HP_CAN_TX_IRQ
// CAN1->IER |= CAN_IT_TME;

// Установить Id (только 11-битный идентификатор)
baseCAN1->sTxMailBox[0].TIR = (frame.communicationObjectId & (UNSIGNED32)0x000007FF) << 21;

// Установить RTR
if (frame.isRemoteTransmitionRequest)
baseCAN1->sTxMailBox[0].TIR |= (UNSIGNED32)0x00000002;

// Установить объем передаваемых данных
baseCAN1->sTxMailBox[0].TDTR = (frame.dataLength & 0x0F);

// Скопировать данные
baseCAN1->sTxMailBox[0].TDLR = frame.dataPayload32[0];
baseCAN1->sTxMailBox[0].TDHR = frame.dataPayload32[1];

// Начать передачу
baseCAN1->sTxMailBox[0].TIR |= (UNSIGNED32)0x00000001;

// Разрешить прерывания от передатчика CAN1
// enableInterrupt(USB_HP_CAN1_TX_IRQn, 0, 0);

return (true);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////
bool THardwareSTM32::getCANFrame(TCANFrame & frame)
{
CanRxMsg RxMessage;

// Забрать полученный CAN-кадр из буфера принятых сообщений
// CAN_Receive(portNumber, CAN_FIFO0, &RxMessage);
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage);

// Вычислить Id принятого CAN-кадра (расширенный 29-битный идентификатор урезается до 11-битного)
if (RxMessage.IDE == CAN_ID_STD)
frame.communicationObjectId = RxMessage.StdId;
else
frame.communicationObjectId = RxMessage.ExtId;

// Get RTR
if (RxMessage.RTR == CAN_RTR_REMOTE)
frame.isRemoteTransmitionRequest = true;
else
frame.isRemoteTransmitionRequest = false;

// Get the DLC
frame.dataLength = RxMessage.DLC;

// Get the data field
frame.dataPayload08[0] = RxMessage.Data[0];
frame.dataPayload08[1] = RxMessage.Data[1];
frame.dataPayload08[2] = RxMessage.Data[2];
frame.dataPayload08[3] = RxMessage.Data[3];
frame.dataPayload08[4] = RxMessage.Data[4];
frame.dataPayload08[5] = RxMessage.Data[5];
frame.dataPayload08[6] = RxMessage.Data[6];
frame.dataPayload08[7] = RxMessage.Data[7];
}


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
adnega
сообщение Mar 24 2011, 06:38
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702



Терминаторы на концах линии установлены?
Go to the top of the page
 
+Quote Post
DmitryDI
сообщение Mar 24 2011, 06:41
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 789



Честно сказать – я все-таки не понял – связь скорости с системной частотой – почему в формуле появилась 2 :
CAN_InitStructure.CAN_Prescaler = (_systemFrequency / 2 / baudRate / 9); // CAN_SJW_1tq + CAN_BS1_4tq + CAN_BS2_4tq


Сообщение отредактировал IgorKossak - Mar 24 2011, 07:56
Причина редактирования: Бездумное цитирование
Go to the top of the page
 
+Quote Post
DmitryDI
сообщение Mar 24 2011, 12:38
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 70
Регистрация: 5-04-07
Из: Санкт-Петербург
Пользователь №: 26 789



Всем спасибо за отклики - все заработало:
правильные настройки


..........................................
// 2. Enable ext. high frequency OSC
RCC_HSEConfig(RCC_HSE_ON);
// wait until the HSE is ready
while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
// 3. Init PLL
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_4); // 100 MHz
RCC_PLLCmd(ENABLE);
// wait until the PLL is ready
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
// 4. Set system clock divders

RCC_ADCCLKConfig(RCC_PCLK2_Div8);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
// Flash 1 wait state
*(vu32 *)0x40022000 = 0x12;
// 5. Clock system from PLL
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
.............................................................................

CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1 = CAN_BS1_5tq;
CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq;
CAN_InitStructure.CAN_Prescaler = 5;

Скорость = 100МГц/2/5/10 = 1 МГбит/с
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 23:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01448 секунд с 7
ELECTRONIX ©2004-2016