STM32 系列不同芯片之间程序移植问题。
(F1toF1,F4toF4, F1toF4, F4toF1)
注意:程序移植最大的问题就是时钟和芯片本身资源的问题
每个系列的时钟的最高频率不一样,查看芯片对应的数据手册可得知此芯片的频
率上限,在设置系统时钟的时候只要不超过这个上限一般不会出问题。
察看芯片对应的数据手册可得知芯片的频率上限,如下图。
F1 系列之间的程序移植(参考正点原子论坛)
http://www.openedv.com/forum.php?mod=viewthread&tid=289461&highli
ght=%B3%CC%D0%F2%D2%C6%D6%B2
F4 系列之间移植(本总结的重点,也是本人理解时钟的突破
口)F407 的程序移植到 F401 上
先大致说一下要改的地方
1.Device 里选择要移植的芯片,我原来的是程序是 407 的,现在改成了 401RCTx
2.只有 401 系列需要改头文件,如下图,F4 系列其他不用改头文件,具体参照
system_stm32f4xx.c 看 看 这 个 里 面 你 的 芯 片 分 为 哪 类 , 比 如 407 归 类于
STM32F40xxx/41xxx 而 401 有单独的分类 所以归类于 STM32F401xx 另外
还有 STM32F42xxx/43xxx STM32F411xx 类别,根据类别设置头文件,后面
的 USE_STDPERIPH_DRIVER 是不需要动的
注意:如果编译还有很多错误,那需要更新一下 MDK 的版本了,我之前也遇到
这样的问题,之前是 MDK514,现在是 MDK516a
时钟分频配置(截图来源正点原子 F407)
如何得到主 PLL(PLLCLK)
主 PLL 频率计算方法:PLL=8MHz * N/ (M*P)=8MHz* 336 /(8*2) = 168MHz
其中 分频系数 M 倍频系数 N 分频系数 PQ 设置路径:
外部晶振设置方法:stm32f4xx.h ->
分频系数 M 倍频系数 N 分频系数 PQ 设置路径: system_stm32f4xx.c
->
上图是 STM32F401RTC6 芯片 主频最高 84 MHz 此处设置为 80MHz
如何得到 AHB APB1 APB2
system_stm32f4xx.c
-> static void SetSysClock(void)
F4 系列与 F1 系列之间移植(这种移植主要是移植程序思想)
如果要直接拿例程来改,会很麻烦,也没有必要,因为除了
要改时钟以外还要改启动文件,也会遇到很多问题,这种移
植建议主要是移植思想。
假设现在你网上找到一片 103 的程序,是你工程需要的,很
重要,而你用的是 401 或者 407 系列的芯片,你把里面最重
要的驱动文件复制过去,然后就是改一系列的头文件,然后
就是所用到的外设的配置了。
Sys tick 时钟配置
可由系统时钟分频或者不分频得到
默认不分频,如果要 8 分频,用 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
此条语句
配置函数:
void systicket_init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
SysTick_Config(4800000/100);
}
Sys tick 中断函数
void SysTick_Handler(void)
入口:stm32f4xx_it.c
-> void SysTick_Handler(void) 可以复制也可以在此处写中断函
数
SysTick_Config 的使用及其计算方法
根据学过的物理中的时间与频率的公式:fosc=1/T
T=1/fosc ,fosc 为系统的频率。
如果 STM32 时钟频率为:72MHz,每次的时间为:T=1/72MHz。1 秒钟为:1/(每次的时
间)=1/(1/72MHz)=72 000 000 次。1MHz 是:1000 000。
反过来讲。SysTick_Config(72000)代表:72000*(1/72MHz)=1/1000=1(ms)。即定
时为 1ms。
滴答定时器上电默认开启
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; 打开滴答定时器
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; 关闭滴答定时器
利用 Sys tick 来设计延时函数 (先配置就好,后面延时函
数里面开启定时)
延时函数初始化
void delay_init(u8 SYSCLK)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}
延时 nS:
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us;
SysTick->VAL=0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
延时 xmS 最大 798mS
void delay_xms(u16 nms)
{
u32 temp;
SysTick->LOAD=(u32)nms*fac_ms;
SysTick->VAL =0x00;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16)));
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL =0X00;
}
延时 mS 最大 65535mS
void delay_ms(u16 nms)
{
u8 repeat=nms/540;
u16 remain=nms%540;
while(repeat)