这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,! E" I# s3 I0 F6 s/ \0 X
( q% Z2 a, |9 x6 |- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码 K" h' h4 a% c
结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。0 W4 ]+ F% ]# h" x" G
! [2 l7 c, n2 z. D) X( N由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。' J; N& F+ c+ |) j$ `" A5 F8 `3 z
: i% o2 I( U* J/ z# `- DEBUG [D] main:94 hello armwind% k. N I! A6 T3 Y1 Q; Y$ q
- DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码
' E3 Y- w9 T5 o5 i5 x1 b查看源码发现,断言表明,这个方法只能映射系统mem.$ c1 N, s! ~5 h% m$ K# w6 ]
" o5 c- ]4 h5 @$ t- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap): }& T, @& V8 \) I. }; Z
- {+ `+ L7 W2 c3 _
- uint32_t tmpctrl = 0;: {5 s$ u) x# W3 ~
- * Y/ a9 y0 N, V O
- /* Check the parameter */
+ R# n. d4 a. B8 V - assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));! S/ m3 u4 o4 c; a A& ]0 {4 t7 A5 ~4 D
, m) P( x1 S* e7 A L- /* Get CFGR1 register value */* j* w! d; }8 V- M$ A+ H
- tmpctrl = SYSCFG->CFGR1;
1 i& L! g, Q0 q6 v, x
; I9 T; _5 x0 f. f7 W! B$ \$ J- /* Clear MEM_MODE bits */0 h: a* J/ ?& Z
- tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);+ a3 B$ C c; V* m: T, u
- 9 s# t+ ^2 d* m
- /* Set the new MEM_MODE bits value */4 C+ g+ l* _" R. v8 n
- tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
7 _5 y% j) z* x2 V! L E6 I6 ?
, F" X" X/ A5 R. ^- l W- /* Set CFGR1 register with the new memory remap configuration */
8 r& d; ?% l4 Q4 \; y - SYSCFG->CFGR1 = tmpctrl;2 |' a2 w/ i: W
- }$ S5 T# ~- I2 ?& ~
4 U$ M5 R2 c; N- //宏定义很明显. r: I( F. I$ \5 F
- #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \8 L; c7 B0 D+ r9 K$ ?
- ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \
$ s0 N" {2 v' s, e& L# R4 C - ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码
Z8 ~/ Z) C6 M* R/ J: V所以使用下面代码即可map成功
' M3 v- x: F* {, T1 z
, n$ L+ G3 L- f# a- W- //不要覆盖掉系统原始的配置
. v; ^( L% ~2 e8 N8 R$ y+ W - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码
) T6 X/ e6 ]6 A# ?完整的Can初始化代码; O; W6 |7 f5 O; b6 [
4 U, C- ]4 U& O4 U
- void can_init(void)5 Y0 N6 B8 U k9 L
- {; [: b! a- E F: B1 V
- GPIO_InitTypeDef GPIO_InitStructure;
& A- c- Y7 l& \# g* F: l - NVIC_InitTypeDef NVIC_InitStructure;
" r3 ^' F, ~/ g& Y) Z- _ - CAN_InitTypeDef CAN_InitStructure;
: M9 L8 W. }3 Y: I% i# l4 O" z - CAN_FilterInitTypeDef CAN_FilterInitStructure;* c* s, i+ h- q
) [3 t% \$ I6 `2 j7 X- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
2 y% s) l. m% l/ ` - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;1 t3 M; ]& C4 F
" Y$ m, [4 a2 @2 y1 r+ k# _- //这里一定要先映射GPIO, ~( v5 }8 r- l Q) k* v
- /* Enable GPIO clock */
1 u+ U5 ^. M/ o* I( i2 M* D - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);. ~+ B: N' |) Q! w9 Y7 F+ o' o5 G
- /* Connect CAN pins to AF7 */+ T: g( O: e1 Y# @
- /* CAN GPIOs configuration **************************************************/0 l* q- A# q5 N2 k& F
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
: W! M3 X f2 s8 b# W; N1 j/ y4 R - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);
" C- V3 S; I# k# a1 z* p2 u
4 @& P W+ d- E/ \- /* Configure CAN RX and TX pins */
4 ]$ ^: v" A' u2 ]2 _+ w - GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;) p0 D0 K. O, M5 Z
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
1 _3 V- ]% p8 ]$ @ - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
( M, O5 F. p" z+ ~* G2 D - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
* m9 W) k( C; J$ R, U, U( j - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
7 X8 S$ @3 |9 P/ y" m' x% K5 y - GPIO_Init(GPIOA, &GPIO_InitStructure);. h+ o# D. \0 i" F. Z) Y
- ' f2 x' ]3 J D0 M N. u, T8 A
- /* NVIC configuration *******************************************************/1 o8 d" e0 N3 J7 e
- NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;4 a# f, J& k) w- H. ^% M
- NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;- ^ Z5 s4 e( i5 a* [
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;/ S% x9 Z" ]# n/ X( `
- NVIC_Init(&NVIC_InitStructure);" m7 q8 X6 I; y7 \9 f0 e" _( M8 J
5 G. l( D: }. V8 {% G- /* CAN configuration ********************************************************/8 V$ C: I S- g/ v/ R$ k
- /* Enable CAN clock */* _; { q# r/ b2 y
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);6 y- S$ w9 U/ R3 O1 g; M
- 6 @3 W! ?; l9 h5 M' V
- /* CAN register init */, {4 L' ]! x* ]4 S8 v
- CAN_DeInit(CAN);. g! l7 b6 F' F% d9 V
- CAN_StructInit(&CAN_InitStructure);1 h% O/ R, D' m. A4 _
- " R5 F9 H5 i+ Q# X8 \6 i% A" M' T
- /* CAN cell init */3 G' U; A( C0 e) l1 V* y
- CAN_InitStructure.CAN_TTCM = DISABLE;
4 w C3 U L% P* U) W; J - CAN_InitStructure.CAN_ABOM = DISABLE;- G$ H6 `$ b& T: T$ i/ i" O& \
- CAN_InitStructure.CAN_AWUM = DISABLE;
8 n, \) {* a( Q, A8 o) u - CAN_InitStructure.CAN_NART = DISABLE;
( {: ~( [" X9 P! b - CAN_InitStructure.CAN_RFLM = DISABLE;& L. W" R P2 @" {5 f+ F
- CAN_InitStructure.CAN_TXFP = DISABLE;7 A3 g+ b1 | r6 `! j# p. h8 ~
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
+ N) I4 I$ T9 P5 Y' q; c7 d - //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;6 D, U: K' v6 _+ Q" r! h6 y) V$ x6 {
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;& m8 l( J1 [3 b
- ' j2 o+ n0 C# P6 H2 f. `. _4 b
- //200k的配置/ l5 Q2 w3 g8 v: |% [; {7 C0 @
- //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k
" E+ _/ i' k6 b2 z2 p - /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */; A3 m. [; w& d3 J7 m* [" W- W
- CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;" b4 u6 O& b; H5 W4 Z; e
- CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;/ B. j4 ~/ F* e. O5 H h9 X9 w
- CAN_InitStructure.CAN_Prescaler = 12;
5 I: C& J. P- O' {+ q' @ - CAN_Init(CAN, &CAN_InitStructure);
* j$ F. e5 T) c# @2 ?" ^
0 Y4 G( \8 I7 ^) v1 K- /* CAN filter init */
% V2 R6 j( I [8 d - CAN_FilterInitStructure.CAN_FilterNumber = 1;. x# f) `0 r: D2 q/ A/ D+ h
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;+ M4 I$ j( z, ^; r& O- U0 `( r* I
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
V( [) P& ~8 i1 w4 l - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
9 p! m- H4 x1 ]# M: m - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
6 `7 ]8 R; u3 A+ g3 @6 M$ F4 L - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;3 ^8 g! z* t( ^3 m
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;2 _: O7 h) c9 @& Y
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
3 W$ c8 ~' a; ~4 t8 l% H - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
, y% {+ Z, r s- _6 D/ H - CAN_FilterInit(&CAN_FilterInitStructure);7 [1 h, r6 o& j# Q* F
- /* Transmit Structure preparation */3 n8 R' W/ n5 i) Z
, a5 }! ?* A/ c+ T# t/ M- /* Enable FIFO 0 message pending Interrupt */
& t- V" P i+ S2 _- D3 k - CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);+ Z$ p2 p* c+ P
- }+ E) \# ?- e: @% Q
f. Q- X1 ]$ u0 G0 S% [
; Q5 B i6 T0 F s9 K
复制代码 6 m# U+ l& C' \3 M! Z0 I
1 y5 P9 t r% B5 F9 \
|