Перейти к содержанию
    

Всем привет

Использую stm32f103c8t6 в связке с MCP2551, с другой стороны к нему подключен CAN Shield для Arduino, чтобы ловить пакеты.

При включении со стороны STM32 приходят 2 пустых пакета с заголовком (насколько я понимаю)

После этого STM32 уходит в Hard Fault, тактирование я вроде бы настроил правильно, кванты времени выставил для скорости 500 кбит

Код генерировал в STM32CubeMX, а отладку провожу в Keil uVision5

 

Честно говоря это мои первые попытки работы с CAN протоколом, да и до этого я с STM32 не работал, но похоже я что-то делаю не так

#include "main.h"

CAN_HandleTypeDef hcan;

void SystemClock_Config(void);
static void CAN_Data_Send(void);
static void MX_GPIO_Init(void);
static void MX_CAN_Init(void);

void CAN_Data_Send(void){
	
	CAN_TxHeaderTypeDef Tx_Header;
	
	Tx_Header.StdId = 0x201;
	Tx_Header.IDE = CAN_ID_STD;
	Tx_Header.RTR = CAN_RTR_DATA;
	Tx_Header.DLC = 0x08;

	uint8_t Tx_Data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
	
	HAL_CAN_AddTxMessage(&hcan, &Tx_Header, Tx_Data, (uint32_t *)CAN_TX_MAILBOX0);
}	

int main(void){
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_CAN_Init();

  while (1){
		HAL_Delay(500);
		CAN_Data_Send();
		HAL_GPIO_TogglePin(GPIOC, CAN_Error_LED_Pin);
	}
}

void SystemClock_Config(void){
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
	
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){
    Error_Handler();
  }

  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK){
    Error_Handler();
  }
}

static void MX_CAN_Init(void){
  hcan.Instance = CAN1;
  hcan.Init.Prescaler = 9;
  hcan.Init.Mode = CAN_MODE_NORMAL;
  hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan.Init.TimeSeg1 = CAN_BS1_4TQ;
  hcan.Init.TimeSeg2 = CAN_BS2_3TQ;
  hcan.Init.TimeTriggeredMode = DISABLE;
  hcan.Init.AutoBusOff = DISABLE;
  hcan.Init.AutoWakeUp = ENABLE;
  hcan.Init.AutoRetransmission = ENABLE;
  hcan.Init.ReceiveFifoLocked = DISABLE;
  hcan.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan) != HAL_OK){
    Error_Handler();
  }
}

static void MX_GPIO_Init(void){
  GPIO_InitTypeDef GPIO_InitStruct = {0};

  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  HAL_GPIO_WritePin(CAN_Error_LED_GPIO_Port, CAN_Error_LED_Pin, GPIO_PIN_RESET);

  HAL_GPIO_WritePin(LED_Output_GPIO_Port, LED_Output_Pin, GPIO_PIN_RESET);

  GPIO_InitStruct.Pin = CAN_Error_LED_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(CAN_Error_LED_GPIO_Port, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = Button_1_Pin|Button_2_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

  GPIO_InitStruct.Pin = LED_Output_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LED_Output_GPIO_Port, &GPIO_InitStruct);

}

void Error_Handler(void){
}

{2E0E8566-15F8-4E7A-92C9-FA01EC04A7DB}.png.jpg

{4FFD33FB-9ED1-4218-A241-1E70AEDD28A7}.png.jpg

{F453FD4A-166D-4EA9-BC06-B5C993958982}.png.jpg

Изменено пользователем Koteyk0o

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

29 minutes ago, Koteyk0o said:

После этого STM32 уходит в Hard Fault

Расшифруйте причину hardfault. В книге Дж. Ю прекрасно написано как это сделать для cortex-m0/m3/m4(f). Ибо причины могут быть совершенно разные. А некоторые даже вполне "безобидные" (например, невыровненный доступ, включается принудительно).

Хотя, скорее всего, какая-нибудь ошибка доступа к памяти (выход за границы массива, неаккуратная работа с указателями).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, похоже была ошибка с почтовым ящиком в функции HAL_CAN_AddTxMessage

void CAN_Data_Send(void){
	
	CAN_TxHeaderTypeDef Tx_Header;
	
	Tx_Header.StdId = 0x321;
	Tx_Header.ExtId = 0x01;
	Tx_Header.RTR = CAN_RTR_DATA;
	Tx_Header.IDE = CAN_ID_STD;
	Tx_Header.DLC = 2;
	
	uint32_t mail_Box;

	uint8_t Tx_Data[8] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
	
	HAL_CAN_AddTxMessage(&hcan, &Tx_Header, Tx_Data, &mail_Box);
}

 

С таким кодом контроллер работает, мигает встроенным светодиодом, функция отправки работает, отправка возвращает HAL_OK. Но.

После отправки ОДНОГО сообщения шина сходит с ума, и ардуина с CAN Shield принимает кучу одинаковых пустых сообщений в огромнейшем колличестве до перезагрузки stm32

Я так понимаю это уже какая-то аппаратная проблема? Потому что по дебагу вроде бы все отлично, отправляется сообщение, дальше дергается нога GPIO, задержка, и так по кругу, все как и должно быть.

{E42A5F4E-CCB6-4575-B6AD-36F59C97899F}.png.jpg

Изменено пользователем Koteyk0o

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

CAN контроллер на STM не видит доставки сообщения.

1. Ошибка в физике CAN.

2. Никто не отвечает Acknowledgement.

И еще, почему в программе ID = 0x321, а на приеме 0x448? Передается не то или не оттуда?

А после 

HAL_CAN_AddTxMessage(&hcan, &Tx_Header, Tx_Data, &mail_Box);

не нужно дождаться окончания передачи сбросить мэйлбокс? ( В версии HAL, что я использую, такой функции нет, поэтом не знаю чем она завершается)

Изменено пользователем Andrew_Q

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, Andrew_Q сказал:

CAN контроллер на STM не видит доставки сообщения.

1. Ошибка в физике CAN.

2. Никто не отвечает Acknowledgement.

И еще, почему в программе ID = 0x321, а на приеме 0x448? Передается не то или не оттуда?

А после 


HAL_CAN_AddTxMessage(&hcan, &Tx_Header, Tx_Data, &mail_Box);

не нужно дождаться окончания передачи сбросить мэйлбокс? ( В версии HAL, что я использую, такой функции нет, поэтом не знаю чем она завершается)

 

Спасибо большое, отключил AutoRetransmission и все ок, данные передаются в нужном промежутке времени

Цитата

И еще, почему в программе ID = 0x321, а на приеме 0x448? Передается не то или не оттуда?

Передается не то, ID указан один, приходит вообще другое

 

{7780D1A6-DA45-4186-9640-0795F14BCBE5}.png.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Смотрите что конкретно делает HAL_CAN_AddTxMessage(). Что берет? Куда кладет? Как выбирает мэйлбокс? Как его освобождает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня подозрение, что мы наблюдаем проблемы а) с битовой скоростью и б) с тем, что ардуина принимает всё подряд и не говорит, что принято с ошибкой.

Осцилл у Вас есть? А ещё лучше - логический анализатор (подключать между контроллером и PHY'ем CAN'а).

 

Советики:

- объявите в настройках проекта дефайн USE_FULL_ASSERT. Очень помогает в отладке этого чёртова хала - иначе при ошибках вызова он "ест" любые комбинации параметров и падает в совершенно неожиданных местах.

- как что-то заработает, верните назад авторетрансмит. Это полезная фича CAN'а. Иначе на более-менее загруженных шинах сообщения будут теряться (ну или придётся руками этот ретрансмит делать).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все заработало, извиняюсь, мой косяк

Если у кого-то принимаются неверные данные с помощью MCP2515 CAN модуля для ардуино, то проверьте какой у вас там установлен кварц. Обычно там стоит кварц на 16 МГц, но у меня почему-то стоял кварц на 8 МГц, из-за этого модуль работал неправильно. Его можно или перепаять, или поменять значения квантов времени в библиотеке

1 час назад, esaulenka сказал:

У меня подозрение, что мы наблюдаем проблемы а) с битовой скоростью и б) с тем, что ардуина принимает всё подряд и не говорит, что принято с ошибкой.

Осцилл у Вас есть? А ещё лучше - логический анализатор (подключать между контроллером и PHY'ем CAN'а).

 

Советики:

- объявите в настройках проекта дефайн USE_FULL_ASSERT. Очень помогает в отладке этого чёртова хала - иначе при ошибках вызова он "ест" любые комбинации параметров и падает в совершенно неожиданных местах.

- как что-то заработает, верните назад авторетрансмит. Это полезная фича CAN'а. Иначе на более-менее загруженных шинах сообщения будут теряться (ну или придётся руками этот ретрансмит делать).

Спасибо за советы, ретрансмит включу обратно

{E8AEF4E6-FDC2-412A-BAB4-6D6DA4CE9869}.png.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ребята расскажите по подробней ( прям вообще подробно) .как Koteyk0o собрал это все . меня итересует к каким пинам он цеплялся к stm32f103c8t6 и как и что делать в STM32CubeMX. сам Koteyk0o не отвечает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это так не работает. Думаю, сначала стоить изучить как вообще КАН работает.

 

 

 

Изменено пользователем Behram

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 hours ago, kostet2010 said:

ребята расскажите по подробней ( прям вообще подробно) .как Koteyk0o собрал это все . меня итересует к каким пинам он цеплялся к stm32f103c8t6 и как и что делать в STM32CubeMX. сам Koteyk0o не отвечает.

Поскольку Вы спрашиваете, на какие пины цеплять CAN, то это не тот вариант, когда можно соединить 3-4 проводка и "все работает". CAN - это уже настоящий сетевой контроллер, очень младший брат Ethernet. И погонять его в стиле UART без полного понимания процесса (хотябы "в общем") не получится.

Пины на процессоре и плате, соответстующие CAN Вы можете легко "вычислить" из принципиальной схемы платы, а если ее (схемы) нет - то из даташита на SRM32F103 и прозвонки пинов. Для "выхода" на шину CAN нужен еще трансивер (8-лапковый soic). Вам надо ступить на "пусть самурая", те начать чтение даташитов и изучение интерфейса узла CAN (библиотечных функций и обращения с ними) :declare: 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для STM32F0x2 я вот такую штуку сделал. Обрабатываю разные ошибки, и если на шине нет слушателя, то получаю соответствующий статус (и делаю abort передачи).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 часов назад, k155la3 сказал:

Поскольку Вы спрашиваете, на какие пины цеплять CAN, то это не тот вариант, когда можно соединить 3-4 проводка и "все работает". CAN - это уже настоящий сетевой контроллер, очень младший брат Ethernet. И погонять его в стиле UART без полного понимания процесса (хотябы "в общем") не получится.

Пины на процессоре и плате, соответстующие CAN Вы можете легко "вычислить" из принципиальной схемы платы, а если ее (схемы) нет - то из даташита на SRM32F103 и прозвонки пинов. Для "выхода" на шину CAN нужен еще трансивер (8-лапковый soic). Вам надо ступить на "пусть самурая", те начать чтение даташитов и изучение интерфейса узла CAN (библиотечных функций и обращения с ними) :declare: 

 

я спросил на какие пины цеплять кан-шилд  MCP2551 к  stm32f103c8t6 и как это все в STM32CubeMX красиво прорисовать.

14 часов назад, Behram сказал:

Это так не работает. Думаю, сначала стоить изучить как вообще КАН работает.

 

там другая микросхема. я же спрашиваю(интересуюсь) как к stm32f103c8t6 подключить кан-шилд MCP2515 CAN шина модуль TJA1050 приемник SPI модуль для Arduino и как это все прописать в  STM32CubeMX

  Скрыть контент

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...