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

【经验分享】STM32F1移植到F0的各种经验总结

[复制链接]
STMCU小助手 发布时间:2021-11-20 22:00
这段时间在公司里做了一个移植的项目,是stm32f103c8t6——>stm32f070cbt6,管脚基本上一样,移植一下库就行了,大概是为了节省成本吧。一开始是懵逼的,以前从来没有移植过stm32,都是想用哪个功能,发现一个是F1一个是F4,就耍小聪明,把其中没有用到库函数的部分复制到另一个上,然后开始编啊编啊……现在遇到项目要做了没办法,网上也找不到资料(我是小白),只能自己硬着头皮改啦!' ?5 T% c$ G+ V* V. t9 E5 B
5 d$ X+ ]# b- |; F, Q" `7 x. K
    想想想,想到后来就是先创建一个工程再说吧!1 e$ Q1 T1 Q# x) e; W& X. K
% C$ H. V8 z$ S
    于是乎,第一步来了:创建一个STM32F0的工程。. r0 }2 J! ?8 l

! |7 j/ [7 W( N    如果你在选择芯片的时候没有你想要的F0芯片,说明你没有那个pack,得下载一个,具体步骤不详细说了。/ v2 k: z) E' u) W
8 k' o9 U% Z' k2 r$ r
    你需要用到的文件有:F0的库、F0的启动文件、F0的各种头文件、CORTEX-M0、系统文件……详细的不说了,对照图中的文件放就行了
- R- N. n3 u. @$ B+ C
' n8 W( A2 L/ L# m  A3 p
20180725134343215.png

2 @' M4 W, }% r# S- M1 u, X  X6 Z6 q6 c$ g' s0 f9 M
    图中没有红线的不用管,其他都必须有,还有一些头文件没在上面,记得在设置——>C/C++里面引用一下,这些文件基本上在官网例程里都能下到。  }; h+ g7 x" u- C) u& m
8 X% `- |6 L7 O1 l( U/ z
    同时要在C/C++一栏里加这么一行字:USE_STDPERIPH_DRIVER,STM32F0XX_MD
; I0 t! ?- y1 G. {. n* K2 F) {; l+ r% P$ W: o8 c1 p: F; Q
20180725134837925.png

3 G+ M+ U' |) l9 q# E7 E5 m5 ]* ?, Z; g$ E$ g/ U* u
    然后再把你自己的程序贴上去,一编译,肯定不会通过的拉,哈哈哈,但是会把你程序中F1用到的库函数和F0库中相冲突的地方显示出来,这时候你就只需要一个个改就成了。
, W8 z! K( Z. h+ n, U/ G" Y: P; o+ q" t0 |8 |. ]
    1.GPIO.c方面
: H2 H% N* w3 t9 p4 u    gpio这方面比较简单,错误大部分都是引脚时钟设置、引脚的模式设置方面会出错误。4 z* E; n6 e. z# a; s1 D, w9 U

3 \, Z3 a7 t4 ]+ G* ^7 H, Y# ], B    1.时钟的话由于F0库中没有使用PCLK作为GPIO时钟源的命令,所以一般都使用HCLK来作为GPIO的时钟源;8 W$ z4 h! {5 T% m: ^1 C
; c; V' m+ A/ a( s( l
    2.引脚的模式设置方面你可以右键“GPIO_InitTypeDef”——>go to Definition看一下这个结构体里面的定义,比较一下F1和F0的设置的不同。, z3 I! }# k, e" u4 @( d
) L# Q: l$ m8 g) E" t2 U  l2 D* j
    这里放两种图,一张是F1的,一张是F0的GPIO设置,大家可以对比一下
$ `4 G& h; g/ \! W; {( l8 ~8 W
20180725135841124.png

: K3 l$ m/ O: y2 @" S% P7 Y; c: M# I7 Q9 O5 T% b3 f" q' U: l" e
0 @; F* ]( g! V  y, G
F1 GPIO设置F0 GPIO设置3 B/ I' H2 p/ N- z4 y

/ }  [6 o. N! x. W* |- i: V
20180725140255219.png

7 k# s- B' {' W5 O) r
0 s8 v$ v0 l7 O9 Y. b  Y7 t% L' E    另外,如果引脚模式为AF_PP,复用输出模式时需要用函数配置一下复用的用途:: K3 E% D2 c! B+ t. ~$ ]
1 ]5 D) ]/ S9 Z& @  }
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_1);GPIO_AF_1对应一些外设,比如说我这里用到了USART1,故要用GPIO_AF_1,你可以右键Definition看一下各个模式的定义。4 g& U- n  @/ U4 K1 p
! T+ t' h& @# _  |3 K
    是不是感觉F0的设置很啰嗦,呵呵。9 Q3 s) ~/ g1 C" q$ s+ U+ a: X0 j  o
' ~' ^2 H+ C! I' x( L
    2.MISC.c(NVIC,即中断)、EXTI.C(外部中断)
" Y6 {8 u, ?9 N+ C) y    1.模式设置
' x9 i, A1 S3 W: q
. m/ S  |) j" K& `, y) u, @4 h/ W    与GPIO模式配置差不多,修改方式大同小异。右键Definition一下“NVIC_InitTypeDef”、“EXTI_InitTypeDef”查看异同,相同不用改,不同就改,多删少补。
; W7 C4 W' F7 M  [8 S2 ?6 R
; J1 t' f! R$ ~6 @% Y. n    还有在配置外部中断源时注意F1和F0是不同的,F1配得外部中断源在哪个通道范围,F0也得相应换:6 W, V2 x  p. l  b# a& a; _

' X2 l  p0 \- R9 L* }2 h6 Q2 O    F1的中断源有:EXTI15_10_IRQn(10-15)、EXTI9_5_IRQn(5-9)、EXTI1_IRQn、EXTI2_IRQn……(1、2、3、4、5)
; Q2 ~: K: n4 B% j1 D/ D0 D- G! ?2 i+ z( L1 ?, ?4 c
    F0的中断源有:EXTI0_1_IRQn(0-1)、EXTI2_3_IRQn(2-3)、EXTI4_15_IRQn(4-15)$ _7 F" z; x: D5 B% _
' b0 s1 u8 U9 }& x4 }! I2 {$ R
    F1的中断源比如说是EXTI15_10_IRQn,那在F0中就得配EXTI4_15_IRQn,如果不在范围中,就得看你外部中断的引脚了,中断源和你引脚号相同5 B1 Q4 Z/ u6 p2 v" n8 D
! t% U$ c% @) r1 W$ h' Y
    3.定时器方面  `+ G6 n4 M; f3 R# h: k' R4 y! O2 M
    这部分由于项目中没有用到,我这里也不敢乱贴以致误导。相信小伙伴们上面的会改了,这个也不是难事,大部分都是修改模式配置的问题。
* f  X4 G$ f* G- x, J. v+ N0 ?( b1 Y! T. j. k
    4.USART.c方面
6 p; O& c7 J& Y    串口配置首先是GPIO的配置和中断方面的配置,上面已经有方法了。这里的模式配置MS是不需要改的:
, X- B+ X9 c$ A0 e7 ^1 K% Q% y$ H! l& p5 s  Q- J& [
    F0:! |6 j8 Q2 E* C6 {

6 }) [! F8 ~& m5 p5 e( D
  1. /* USART1 mode config */
    ; c6 e5 x+ e! \% N
  2.     USART_InitStructure.USART_BaudRate = bps;) J" _9 W! |! l. s# f9 v
  3.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;2 w' w1 t0 K& F3 d' t* ?5 N4 O
  4.     USART_InitStructure.USART_StopBits = USART_StopBits_1;; S2 c* d- ]$ |
  5.     USART_InitStructure.USART_Parity = USART_Parity_No ;( z; N$ \. v& g0 Z+ s$ Z
  6.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;% b2 n. @2 A- b$ N% [
  7.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    9 {5 S+ {8 D( r+ q9 {3 L9 Y
  8.     USART_Init(RS485_UART, &USART_InitStructure);: |; a6 p- D" X' G% w1 s
  9.     USART_ITConfig(RS485_UART, USART_IT_RXNE, ENABLE);
    ) n  _' v$ z% t) \1 s' [. O

  10. * h6 F3 c: o* w2 E9 S$ i
  11.     USART_Cmd(RS485_UART, ENABLE);
复制代码
; @  }7 c$ A2 r9 p  e2 ^
    F1:
3 v0 f% V8 C8 q, k  V; {5 ~" d1 z  L7 _' x: \6 o" H
  1. /* USART1 mode config */
    7 o& S5 W# T. w8 G; M
  2.     USART_InitStructure.USART_BaudRate = bps;
    ! V; r& A" {) g7 }, j6 x4 j3 r$ @
  3.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    , F- {. V3 O2 s
  4.     USART_InitStructure.USART_StopBits = USART_StopBits_1;2 w; a1 b* h3 L; k
  5.     USART_InitStructure.USART_Parity = USART_Parity_No ;% s* C5 f' |( i- V
  6.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;0 t3 G' D/ i- U" y" X# \8 P
  7.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    * d7 X8 ?9 g2 ^! f
  8.     USART_Init(RS485_UART, &USART_InitStructure);$ H1 a# i: Z6 y, @; l
  9.     USART_ITConfig(RS485_UART, USART_IT_RXNE, ENABLE);
    * Y: m5 `) u9 N! V8 S. ?/ g3 _& l. ^

  10. 8 m# B' W+ \" ?% O
  11.     USART_Cmd(RS485_UART, ENABLE);
复制代码
   嗯....一样一样的。注意这里有个寄存器是不一样的:
, @( U4 N( W8 I# `* |
% y* a" q- g' ~& ]+ l就是在接收中断中,有些项目可能需要将这个寄存器重置一下:8 U% x$ S' T2 Y, O& i

& w( ^6 m% B# n" c; l' QF1中为“RS485_UART->SR=0x00;”,SR寄存器,只有16位
3 ?* @1 T( K7 Z3 [" n' {0 m. v) j1 b6 C0 g2 {. U( N, o: K& R" y
而F0中则为“RS485_UART->ISR=0x00C0; ”,ISR寄存器,有32位
/ ?% P4 `9 O5 c1 Y5 E& O: ~! i) L0 @0 T$ a5 _
这些好像不是必要的,具体的功能可以看一下数据手册里怎么介绍的...似乎是中断接收标志位?
4 L5 A/ H' ~- P& ?7 Q" [3 e8 K& C; B/ z/ V; A
    5.中断向量表的重映射
% f4 F5 ^  c# R! N6 i% c* a  E    如果你的项目用到了软件bootloader,中断向量表就得重映射,而F1中有函数可以直接用,然后你会发现F0中没有
9 j% f3 P$ S; I1 d* c/ c! S# m5 j4 N9 _( i7 p
    F1中的函数:- k2 @. z% F. q+ \, I6 L% i* M

+ W, y* }9 R6 U* L0 j    NVIC_SetVectorTable(NVIC_VectTab_FLASH, BSP_ADDR_Boot);
2 i% g" a$ P4 ^1 A9 g. U7 D( L; Y2 {& x: m6 \" U6 T
2 }3 |  V; I+ A! K
    通过查资料得知我们可以用memcpy,将中断向量表拷贝到ram下(F0的中断向量表可以放在RAM中),然后保证存储中断向量表的这部分不会被修改就行了,方法在上面这个网址中。
( C% c8 d7 ~1 k, q. a; b$ ~& ?7 ^$ z$ M, M3 n( n
    F0中的函数:
2 x* b7 K2 d' P' P2 N, ]" A4 v7 D$ d
    memcpy((void*)0x20000000, (void*)0x08000000, VECTOR_SIZE);
# K6 T2 u5 k; N2 T    SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);) `6 Q7 ^$ ^# ^; T% o. ^

' G1 X" ^/ y1 @4 K- z" A. p) B    至于JTAG口的复用问题,STM32F0并不存在,可以将相应的函数删掉即可。
' V9 ?- ]- m1 j7 J) _( H- r4 K" @4 M6 f# c- ]4 c7 ~  g) |
/ L% _1 e/ W& A0 g- H. I8 v  K6 j

7 l6 B2 r% `7 ]/ c3 ~* @: h& J/ h6 z
( t/ J4 R, G. R+ \, [
收藏 评论0 发布时间:2021-11-20 22:00

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版