请选择 进入手机版 | 继续访问电脑版

你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32 基于 Nucleo 板 CAN 总线的建立

[复制链接]
STMCU小助手 发布时间:2022-2-12 18:48
前言
STM32 NUCLEO 开发平台是 ST 最新发布的易用性好、可扩展性佳的低成本平台。开发平台具有 mbed 功能支持 Arduino 接口,同时还提供 ST Morpho 扩展排针,可连接微控制器的所有周边外设,可以利用 Arduino 巨大生态系统优势,便于快速实现STM32 学习和评估! 这儿我们评估它的 CAN 外设功能。
一、环境搭建
1、软件:
STM32Cube\Repository\STM32Cube_FW_F1_V1.3.0\Projects\STM3210E_EVAL\Examples\CAN\CAN_Networking\EWARM
2、硬件:
NUCLEO-F103RB(STM32F103RBT6)
3、原理图如下:

ZZ]5XV{X7BN4S[QE9CA1F6G.png

上面原理图是针对 SN65HVD230 的,
因为 PB8 是 CAN_TX,是 MCU 端的发送,需要到 CAN transfer 的输入引脚,即引脚 D(Driverinput);
因为 PB9 是 CAN_RX,是 MCU 端的接收,是 CAN transfer 的输出引脚,即引脚 R(Recv output);

S)3(A{UFVJQQ0LKRP8PCBQ7.png

二、Porting
由于参考的是 STM3210E_EVAL 的示例程序,在用到 STM32F103RBT6 的 Nucleo 板子上的时候,需要做一些 porting 的工
作。
1、系统时钟
在 10E 的 EVAL 板子上,使用的是 HSE,而 Nucelo 上默认的是没有焊接 HSE,所以使用到的是 HIS;利用 CubeMX 生成代码:系统时钟为 36MHz;

1A(AYMMZY%I4I11OE70N877.png

供给 CAN 外设的时钟:是 APB1 的时钟 18MHz;
  1. void SystemClock_Config(void)
  2. {
  3. RCC_OscInitTypeDef RCC_OscInitStruct;
  4. RCC_ClkInitTypeDef RCC_ClkInitStruct;
  5. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  6. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  7. RCC_OscInitStruct.HSICalibrationValue = 16;
  8. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  9. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2;
  10. RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  11. HAL_RCC_OscConfig(&RCC_OscInitStruct);
  12. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
  13. |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  14. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  15. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  16. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  17. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  18. HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);
  19. HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  20. HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  21. /* SysTick_IRQn interrupt configuration */
  22. HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
  23. }
复制代码

2、CAN 的接收/发送引脚
仍然可以都为 PB8 (TX) 和 PB9 (RX) ,不需要改变;
3、CAN 的波特率
(自己想设置的是 500K):

3%]@KA5XRL8X0)BS8]@V.png

@FK:Z$RE2V`4FI06OUD(X.png

  1. CanHandle.Init.Mode = CAN_MODE_NORMAL;
  2. CanHandle.Init.SJW = CAN_SJW_1TQ;
  3. CanHandle.Init.BS1 = CAN_BS1_3TQ; // TS1[3:0] + 1
  4. CanHandle.Init.BS2 = CAN_BS2_5TQ; // TS2[2:0] + 1
  5. CanHandle.Init.Prescaler = 4; // BRP[9:0] + 1
  6. CanHandle.Init.NART = ENABLE;
复制代码

所以,理论上,根据计算公式,
NominalBitTime = 1 × tq + tBS1 + tBS2 = (TS1[3:0] + 1 + TS2[2:0] + 1 + 1)* (BRP[9:0] + 1) x tPCLK;
所以,NominalBitTime = 9* 4* tPCLK; = Freq(APB1)/36 = 18/36 = 0.5MHz = 500K;
4、User 部分
程序中设计到:
  1. while (BSP_PB_GetState(BUTTON_KEY) != KEY_NOT_PRESSED)
复制代码

在 10E-EVAL 板子上,用到的是 PG.08,而在 nucleo 上使用到的是 PC.13
  1. #if 0
  2. #define KEY_BUTTON_PIN GPIO_PIN_8 /* PG.08*/
  3. #define KEY_BUTTON_GPIO_PORT GPIOG
  4. #define KEY_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
  5. #define KEY_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOG_CLK_DISABLE()
  6. #define KEY_BUTTON_EXTI_IRQn EXTI9_5_IRQn
  7. #endif
  8. #if 1
  9. #define KEY_BUTTON_PIN GPIO_PIN_13 /* PC.13*/
  10. #define KEY_BUTTON_GPIO_PORT GPIOC
  11. #define KEY_BUTTON_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
  12. #define KEY_BUTTON_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
  13. #define KEY_BUTTON_EXTI_IRQn EXTI15_10_IRQn
  14. #endif
复制代码

RMDZ8MBAIQQD(NT`5EGYU.png

至此,移植好了;

三、全速运行
1、按下 USER Button,会发出 CAN 报文,CAN 的 PC 端软件能够收到。

SH[I_1~IWL[]C98HQ59CY8S.png

2、CAN 的 PC 端软件发送报文,软件中的中断函数也会进入中断。

(3H6T$R@C`Q@~UH(_UCBE(O.png

说明,CAN 的发送和接收这一基本的操作已经完成了。对于 CAN 的复杂的运用特点,可以在该基础上进一步衍生。
附录:
1、针对现有的 CAN 的总线协议:在数据区域只有固定的 8Byte;也就是说一个 CAN 报文发送的数据只有 8 个,我们的单片机的寄存器也只提供了 8 个寄存器,符合当前的 CAN 的协议;如果客户想发送多个>8 的数据,需要在其上层协议中,用软件去多次发送。也许在下一代的 CAN 总线中,会对这一特点进行改变。

SDWPZ(GFX74NPP]IX$SB~SW.png

2、CanHandle.Init.NART = ENABLE 的说明;
在基于"STM32Cube_FW_F4_V1.10.0
\Projects\STM324x9I_EVAL\Examples\CAN\CAN_Networking" , 如果只用一块 STM32F429-EVAL 调用HAL_CAN_Transmit()的发送函数,会发现 CAN Controller 会不断的发送数据, 这是因为在我们提供的示例中,是需要两块板子互联的,在 CAN 协议中,如果消息没有被正确的接收,它将会 be retransmitted infinitely by the transmitter until it will be acknowledged by the receiver ,而正我们的环境中,只有一块板子,而没有 receiver。

收藏 评论0 发布时间:2022-2-12 18:48

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版