这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射, }+ ^) U( p% |) r+ r
0 T0 L2 u" m8 A
- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码
1 i' G/ K7 i* j) p* n+ d5 y, x结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。( d; g& l1 _4 G/ e- r6 B P
u& m$ m/ k, I" N1 X
由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。. J" D. M1 C% H) T0 c5 @
- g1 ?4 E' |7 I: p( E2 A9 i- DEBUG [D] main:94 hello armwind
8 u1 u6 P1 L2 t; b3 q - DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码 }' M" A2 h0 U2 h5 s3 q
查看源码发现,断言表明,这个方法只能映射系统mem.+ v0 b6 |; Z J0 k5 _
, B) D8 X* H# e8 ~! X1 s5 t- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)
( `: b8 D# V2 j3 t - {
2 @; e" a* s* V9 F3 ` - uint32_t tmpctrl = 0;; E+ O' I. z! M# m6 a: [
- 9 S f- D0 q7 m0 `2 M
- /* Check the parameter */5 c( i$ R& O. [) z" x, E6 i
- assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));; O# U# `5 f$ b& G' {1 P1 m/ G$ r0 s
- 0 |/ V: \+ g3 B1 _( A7 ?8 {. _
- /* Get CFGR1 register value */
5 e7 J4 s7 ^ M, U9 Z6 i1 E - tmpctrl = SYSCFG->CFGR1;2 [& U E: u2 t
- , O) n) V* U% G# y3 B1 h& o: J
- /* Clear MEM_MODE bits */
+ {6 N; a" A; l) H& A - tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
! S/ |* M! I. Q" s/ _2 F8 m& ` - 0 l, e# R/ Y8 Q& ~" ^$ H
- /* Set the new MEM_MODE bits value */6 H1 j, I8 H! [2 y/ Z
- tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
7 R2 q, w& |6 z1 A i
8 o4 k" G, t" U- H, y( s' F( [ m- /* Set CFGR1 register with the new memory remap configuration */, K: V: e8 o5 W$ _' k
- SYSCFG->CFGR1 = tmpctrl;0 G% ^5 o: D- k" o& O8 a
- }+ T" q( l( {5 e+ E1 l" v
- ) `, p- n3 E& H) f1 k: N5 q' M
- //宏定义很明显
8 T+ l z% i2 x1 U9 f* k - #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \
+ u2 U& r9 B9 O - ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \) R' Q1 C4 a" ]* m' n0 i5 a8 j$ Q
- ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码 6 C* S I }, G6 o6 Q1 M
所以使用下面代码即可map成功, P7 w m6 b ?+ L% s
' K% X) s6 s; i/ F4 D
- //不要覆盖掉系统原始的配置2 M3 v" U8 n D
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码 0 `7 h" U5 w8 Q8 }
完整的Can初始化代码, E+ E; g, w' p
" ]% _1 H: i5 K0 L& o% s
- void can_init(void)' y- V- {2 V: B: y4 q5 a
- {3 F6 Z6 [+ i4 E; u9 h7 m2 g! i
- GPIO_InitTypeDef GPIO_InitStructure;8 E$ Z; _0 }1 X; e
- NVIC_InitTypeDef NVIC_InitStructure;
8 t( a; ]5 K. D ]+ I$ \* p - CAN_InitTypeDef CAN_InitStructure;
' |0 a7 ]0 {7 a4 r - CAN_FilterInitTypeDef CAN_FilterInitStructure;
9 q' d8 z4 g2 ~0 d2 P. [
* J9 b0 v/ Y, i! M9 H: a2 B- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);4 h$ i7 R1 n; o% K( x
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
0 n4 ]: s0 R* ^. E4 q& c5 P - 6 l- {7 r. v2 j2 H+ c! o; u
- //这里一定要先映射GPIO: L) \. }; R4 |$ v T
- /* Enable GPIO clock */
* `, J! r) p$ }3 ]2 p - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);! A- f G1 Q& ~4 C' k
- /* Connect CAN pins to AF7 */
0 x: n& u) G' u( S - /* CAN GPIOs configuration **************************************************/
. s1 R3 w! ^4 X. {: [8 S - GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
, ?# o* F! N+ \3 D9 X$ U - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);
9 b6 B2 `8 a- q/ y - 4 Z& E+ O1 l' ?( d7 _+ ~
- /* Configure CAN RX and TX pins *// v/ X. e0 j- b3 \% h. B
- GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;
. f4 D! a5 L) e: T" M& @, F - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;- D2 m* R+ f. T
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;* P# |, P: l3 S( Q/ d
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
5 A% f3 v9 D: J- l: G - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
8 A5 i* Z" {# V* i6 Y - GPIO_Init(GPIOA, &GPIO_InitStructure);
9 ^9 ?6 Z$ v- w
( T: ]3 L- A1 A3 W& ?; C) a- /* NVIC configuration *******************************************************/! r3 ~& F8 R+ {- l" X) d- U
- NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;
! Z! S5 F; e3 l6 }$ ~ - NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;
V2 P0 f( w! ] - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;0 _) h5 j+ ^8 R
- NVIC_Init(&NVIC_InitStructure);
( F# ?+ @5 m: R2 h
" \& K. ^8 X1 `6 w! V6 H6 I9 b- /* CAN configuration ********************************************************/* I Z( S- E% N W$ |. [7 B
- /* Enable CAN clock */) x' g3 }3 a# j4 U% ^ m$ B& }
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
4 d$ T( D$ V5 Q/ I0 E: k( [ - 5 \8 }( `# U8 }3 M* Z+ y4 {: z
- /* CAN register init */+ \( m) [4 X" p) d* ]( D% [7 E8 v/ m8 h
- CAN_DeInit(CAN);
) t1 B' [* l7 a9 h C - CAN_StructInit(&CAN_InitStructure); `5 i. {5 W0 D& M$ x6 t
- # u& y& Y% k) A, v. N- T
- /* CAN cell init */
2 t- M L; i5 v3 Y2 |5 k5 W - CAN_InitStructure.CAN_TTCM = DISABLE;7 `1 w4 g# `' I/ _5 p$ `
- CAN_InitStructure.CAN_ABOM = DISABLE;
! ]3 }$ l7 l/ l- \4 c9 Z/ q - CAN_InitStructure.CAN_AWUM = DISABLE;' V* ^* ?, g7 j: K# c/ s9 V3 c5 `
- CAN_InitStructure.CAN_NART = DISABLE;9 I/ F+ ?2 O$ z
- CAN_InitStructure.CAN_RFLM = DISABLE;$ h6 O2 Q$ a8 v. K6 D5 l* M" L3 N
- CAN_InitStructure.CAN_TXFP = DISABLE;
& I ^+ L8 \* k& B% Q# z0 ]5 ?" { - CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;; ^/ P3 R1 W, g* `* I
- //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
" C0 r% L% X" s: ?; H% ^4 m - CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
% ]1 X& P K( K% t0 l# L# c5 M
& |# A- _' ]. M/ H- //200k的配置
! z+ {3 A9 |) D! R3 x/ H - //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k* b' j6 V+ w% y# M4 m6 a V
- /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */
( {; r- l) F5 _/ z2 ~5 E' ] - CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;% p8 @" p0 {/ R. n$ K' A
- CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;8 f* J$ k7 ~' x3 I" G" g7 I
- CAN_InitStructure.CAN_Prescaler = 12;8 I' ]2 f3 X. t B7 o7 J
- CAN_Init(CAN, &CAN_InitStructure);5 i3 y( K& L6 C b2 v4 s
- ' C- b2 Y* l( W# i/ G8 E% x. T
- /* CAN filter init */6 y0 N+ Y' g; G
- CAN_FilterInitStructure.CAN_FilterNumber = 1;4 t3 G$ Q8 z2 y- j* J' o
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
. ]& ?9 t; W% ]4 ?* ? - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;; ^) q) Y7 I! R3 u
- CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;- E4 G' N3 s2 T/ W C
- CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
0 Y) p9 |$ A% R# R6 B - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;" n! J9 G" t! J! s" j. U( ?% G
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
- s5 T2 S7 ], {) |0 h/ b; s, l - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;% n) c/ o0 g& [
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
+ A1 T& ?( W. w p - CAN_FilterInit(&CAN_FilterInitStructure);
+ a4 h" T0 J& M8 G - /* Transmit Structure preparation */1 i/ |2 R3 U1 {& z. r$ Z
+ P9 f$ ]) u4 d9 o$ V& ]- /* Enable FIFO 0 message pending Interrupt */7 Z! i+ ~1 o( I
- CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);3 K9 S/ U/ e+ r. K- K
- }
! q1 I0 e# N& [
$ j+ I: F% V% o- L- ) v( o/ [' g0 r* c a9 A
复制代码 ) A1 M# }% I! T: j4 m
# s& {1 {2 q$ ]$ {2 r6 \) @2 T
|