STM32F107的串口IAP跳转功能实现过程笔记

给你一囗甜甜゛ 提交于 2019-11-28 22:43:58

工程从CAN接口方式转换为USART接口,IO口,时钟,中断,数据缓存等都做好了,但是USART接受数据老是不对,检查了波特率等设置,都没问题。

启动定时器测试,发现原因是芯片工作时钟频率不对。主频率根本就不是72M.而是比72M慢好几倍。

USART3_Configuration()应该不会出现问题,估计是时钟出现了问题,可是RCC_Configuration()我都是按照固件库函数来的怎么会出错呢?我从stm32f10x_rcc.h源头开始找起,发现默认初始化时钟函数SystemInit()里面有有问题,分频设置当然不会出现问题,问题出在时钟选择上,105/107属于互联网产品,Preprocessor Symbols用的是STM32F10X_CL,固件很多地方会针对这个STM32F10X_CL做出条件编译,其中SystemInit()默认选择外部时钟HSE,HSE的设置值HSE_VALUE在stm32f10x.h中宏定义默认是25MHz,我的板子用的是8MHz晶振,当然那里要改,所以我注释了原来,把8MHz加上。

 

#if !defined  HSE_VALUE

 #ifdef STM32F10X_CL   

//  #define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */

  #define HSE_VALUE    ((uint32_t)8000000) /*!< 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 */

然后继续调试,发现还是不行,始终不对,然后继续跟踪SystemInit()函数,最后找到最终决定设置时钟频率的地方,stm32f10x_rcc.h的SetSysClockTo72(),默认选择最高72MHz,根据自己项目的需要的时钟是需要72MH,在里面的条件编译那里修改成这样:

 

#ifdef STM32F10X_CL

 

#if(0) 

    /* Configure PLLs ------------------------------------------------------*/

    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */

    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */

        

    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |

                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);

    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |

                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);

 

#else

   /* PLL2 configuration: PLL2CLK = (HSE / 2) * 10 = 40 MHz */     //HSE = 8MHz 

    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */  

    RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | 

                              RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); 

    RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV2 | RCC_CFGR2_PLL2MUL10 | 

                             RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); 

#endif

 

就可以了!!参考http://news.eeworld.com.cn/mcu/2018/ic-news081240692.html

 

问题2:IAP跳转到APP,老是不成功,一跳就死。中断、时钟什么的都关闭了,没有用。后来偶然发现另外一个工程可以,发现问题原因。

原来,跳转过来的APP工程中,代码是这样

 

main{

__enable_irq();

RCC_Configuration_107();
GPIO_Configuration();
I2C_Configuration();
CAN_Configuration((char *)ModID,0);//Connect to PC
// CAN2_Configuration((char *)ModID,0);//Connect to Module
NVIC_Configuration();

...

}

改成这样就可以了:

main

{

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8003000);
RCC_Configuration_107();
GPIO_Configuration();
I2C_Configuration();
CAN_Configuration((char *)ModID,0);//Connect to PC
// CAN2_Configuration((char *)ModID,0);//Connect to Module
NVIC_Configuration();
__enable_irq();

 

}

增加一句话,并且在设置的NVIC后,再开启中断。就好了!!!!

原来失败的原因是,中断向量表没有及时设置地址!而是先开中断允许,又开了外设,然后才设置中断向量,中断一允许,外设的中断就要进入中断函数,这时相当于找错了中断入口地址!

原来如此!对于外设、中断、时钟、中断向量表原来还有这样一层先后顺序!!!!!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!