STM32系统时钟 CAN UART
来源:互联网 发布:mac 复制文件到硬盘 编辑:程序博客网 时间:2024/05/21 09:32
在调试USB-CAN的适配器的过程中,采用库函数开发,在调试串口的过程中串口数据始终乱码。
思考一番,发现由于外部晶振的原因,在 Keil 中Ctrl + Shift + F 查找 HSE_VALUE:
#if !defined HSE_VALUE #ifdef STM32F10X_CL #define HSE_VALUE ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */ #else #define HSE_VALUE ((uint32_t)8000000) /*!< Value of the External oscillator in Hz */ #endif /* STM32F10X_CL */#endif /* HSE_VALUE */由于我采用的是12M的晶振,所以将 8000000 改为 12000000,程序测试通过;
接下来调试CAN总线,程序在自己做的 两个 USB-CAN适配器间 CAN通信测试通过,
但是接上公司买来的 USB-CAN适配器 ,数据始终不成功,双方收发一点反应都没有。
这是为什么,买来的 USB-CAN适配器 是没问题的,我自己做的 USB-CAN适配器 在两个CAN网络间也可以通信,
说明我的 USB-CAN适配器 大体是没什么问题的,由于初次调试 CAN 总线,问题出在哪里, 也没什么思路。
最后把情况反馈给 公司所买 USB-CAN适配器 的卖家,卖家人很好,他推测是CAN总线间波特率的问题。
是这个原因吗? STM32的CAN时钟。在SystemInit()函数中的SetSysClock()
#elif defined SYSCLK_FREQ_72MHz SetSysClockTo72();
SetSysClockTo72() 将系统倍频到 72M ,
/* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK / 2 */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
CAN时钟选采用的是PCLK1时钟,为SYSCLK的一半,即是36M,
但是CAN波特率配置是按照 36M的时钟来配置的,为什么还会不成功呢。
void CAN_StructInit_Init(void) {CAN_InitTypeDef CAN_InitStructure;CAN_StructInit(&CAN_InitStructure);/* CAN cell init */CAN_InitStructure.CAN_TTCM=DISABLE;//禁止时间触发通信模式CAN_InitStructure.CAN_ABOM=DISABLE;//DISABLE;//软件对CAN_MCR寄存器的INRQ位进行置1随后清0后,一旦硬件检测到128次11 位连续的隐性位,就退出离线状态。 CAN_InitStructure.CAN_AWUM=DISABLE;//睡眠模式通过清除CAN_MCR寄存器的SLEEP位,由软件唤醒CAN_InitStructure.CAN_NART=ENABLE;//////DISABLE;CAN报文只被发送1次,不管发送的结果如何(成功、出错或仲裁丢失) CAN_InitStructure.CAN_RFLM=DISABLE;//在接收溢出时FIFO未被锁定,当接收FIFO的报文未被读出,下一个收到的报文会 覆盖原有的报文 CAN_InitStructure.CAN_TXFP=DISABLE;//发送FIFO优先级由报文的标识符来决定CAN_InitStructure.CAN_Mode=CAN_Mode_Normal; //CAN硬件工作在正常模式 CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;//重新同步跳跃宽度1个时间单位CAN_InitStructure.CAN_BS1=CAN_BS1_3tq;//时间段1为8个时间单位CAN_InitStructure.CAN_BS2=CAN_BS2_2tq;//时间段2为3个时间单位CAN_InitStructure.CAN_Prescaler=12;//(pclk1/((1+3+2)*12)) = 36Mhz/6/12 = 0.5Mbits设定了一个时间单位的长度12CAN_Init(CAN1, &CAN_InitStructure);}
反复思考,各种怀疑,最后发现是系统倍频至 72M的时候出了问题,
#else /* PLL configuration: PLLCLK = HSE * 9 = 72 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); ////////////////////////////////#endif /* STM32F10X_CL */
SetSysClockTo72() 里面的赫然是RCC_CFGR_PLLMULL9,我晕。
果断改为RCC_CFGR_PLLMULL6。
为什么库函数 SetSysClockTo72() 这么不不完善,就不能根据外部晶振参数 HSE_VALUE 来倍频吗?
这样局限只能是8M的晶振,在采用8M以外的晶振的时候,一定要注意这个问题。
也怪自己太过于相信库函数了。
一直没怀疑系统倍频 72M的原因也是因为我的串口采用的STM32的串口2,
为什么同是APB1时钟PCLK1,串口能正常工作,而CAN不可以呢...
(PCLK1用于串口2,3,4,5;PCLK2用于串口1)
uint32_t USART_BaudRate; /*!< This member configures the USART communication baud rate. The baud rate is computed using the following formula: - IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate))) - FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */
- STM32系统时钟 CAN UART
- STM32 UART/USART初始化时钟使能
- STM32系统时钟
- stm32的时钟系统
- STM32之系统时钟
- STM32系统时钟
- STM32之系统时钟
- STM32 系统时钟设置
- STM32时钟系统
- STM32系统时钟修改
- stm32时钟系统
- STM32 系统时钟设置
- STM32时钟系统
- STM32 时钟系统
- STM32系统时钟配置
- STM32 时钟系统
- STM32时钟系统
- STM32系统时钟配置
- 保护眼睛颜色的RGB
- Hibernate的配置流程
- unity发布android版,分辨率调节
- XE4 代码自动格式化功能
- 组播的调头路由器和proxy加入消息
- STM32系统时钟 CAN UART
- Cocos2d-x ——CCMenu菜单层的简介
- 初始NUnit
- 推挽输出与开漏输出
- 一个程序员的告白-失败源于没有经验,源于没有指引自己前进的方向,但是成功却是源于99次失败之后偶然的灵光一闪
- mysql Error Code:1175
- fourinone-统一配置管理
- 注册的快捷键不管用
- myEclipse使用技巧:查看某方法/属性被调用的情况