这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,- v& ]/ D! z" X& w: L2 ~
5 \ c w; \9 B' r
- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码 + K& t2 Q% W8 p5 f$ c, |* W
结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。
) D" h, V4 B7 H$ n& J& d2 ]* i$ w, c( p
由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。
1 }# g, a' p: b$ m( R6 R: Y/ H1 x/ Y$ W/ L
- DEBUG [D] main:94 hello armwind
; X7 `/ O6 O! n - DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码 # f" A! ~$ q8 L# _, A, e0 D% O* E B
查看源码发现,断言表明,这个方法只能映射系统mem.* g. {+ w1 g- J1 ^
( a+ x( A. T7 t: N8 \5 }- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)
' p& b: T4 ?& K - {
9 n( \0 A& h8 u* Y# R1 k - uint32_t tmpctrl = 0;5 p* q9 T4 Q3 o
- 4 |/ {: b: y5 ?+ b3 [8 w
- /* Check the parameter */- \2 J) K; g% p) r
- assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));6 Z; B6 U, f2 Q" @' [/ o
1 [; S) J! t* E5 \2 V' P- /* Get CFGR1 register value */" a& z9 \3 X4 ]) G* b8 u
- tmpctrl = SYSCFG->CFGR1;) v% L+ z+ h" {0 I* q& A5 \) G
- 9 H) q! i: E; k* E! r8 K" ]* I
- /* Clear MEM_MODE bits */3 n" u* q' E: }, A6 j* `
- tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);/ x/ H% n& N# L: ]9 A s
- ; d% u! e( {! Z
- /* Set the new MEM_MODE bits value */+ f# P: }' r) Q$ N- `2 ]
- tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;- P1 o& p2 `' |5 H0 R2 M
: i/ ?! j' x1 y. c. f; X# V- /* Set CFGR1 register with the new memory remap configuration */7 F, ~! Y S* f U1 B- o9 ]$ L
- SYSCFG->CFGR1 = tmpctrl;
I) H( x; d0 D+ A: L - }! p$ M4 C/ J* O" m3 H" i
- : H( [% ? E o
- //宏定义很明显
) u* v5 O$ T% C H/ h( `1 @ - #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \( u; d& B9 t% X- O
- ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \. A/ Y4 |# D0 ?& N. Y
- ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码
* c) }% D6 T9 @3 p; U \所以使用下面代码即可map成功
) z9 O+ h; {, o2 D, b* i: d( `# S. {/ X p: D
- //不要覆盖掉系统原始的配置
& m3 u7 x: j0 g& R; p+ w9 |$ y2 \, R - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码
0 R3 u9 [" ^2 P完整的Can初始化代码/ j+ {! s W i% F
. c8 M1 d- X. {5 C M2 P4 e- void can_init(void)5 S" x/ y* k$ B
- {1 o7 q8 B$ W$ B" }% D; q
- GPIO_InitTypeDef GPIO_InitStructure;# ^6 B* l# e8 `" w
- NVIC_InitTypeDef NVIC_InitStructure;9 r2 W+ b* N6 S' z& H+ i
- CAN_InitTypeDef CAN_InitStructure;7 Q9 k) x# n4 H7 N; k9 J4 L
- CAN_FilterInitTypeDef CAN_FilterInitStructure;
' T" y. Z, `6 M! l* d - 0 `& a B) _# b7 f
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
" a9 [/ W4 b: \5 A) w' z - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
6 E. s5 I* `4 S" Q$ P
$ g& ~. a4 P/ `; Z4 f2 {+ \( ~6 E- //这里一定要先映射GPIO
6 }- A+ O2 K8 N4 g5 f - /* Enable GPIO clock */
% d- F+ r; K( y# p - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);; L+ q- }) ?) n3 P0 s
- /* Connect CAN pins to AF7 */
5 S2 o! g5 U. o$ Q/ W3 i2 h - /* CAN GPIOs configuration **************************************************/9 F4 a9 N/ p }2 M5 C
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
. N. ]1 w' R! b# O$ ^ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);
$ H2 a: e k m) e T! `6 u. d% S - 0 v1 D7 R |% d" r+ e( b+ j; ~
- /* Configure CAN RX and TX pins */) W$ f7 u2 b' C8 K0 z- g: O0 y
- GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;; M' e3 O: A6 [/ t$ ?4 K1 x: d( M
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
0 M; ]6 V9 l" J( \( q - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
6 ~8 Z' H! P$ y6 |1 p - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
& r, ^0 S2 [( g4 e - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;) x& W q k7 p, g
- GPIO_Init(GPIOA, &GPIO_InitStructure);
/ L: g* E' r3 K' V+ ?8 m$ ?; K - ! M! q# Y* X- A. ]
- /* NVIC configuration *******************************************************/+ M3 i8 { i! y4 Z1 L
- NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;. Y% S# K4 O z8 o9 O% J1 f( _
- NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;2 B; z3 v4 ~7 j* w( @
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;, K9 l- c: _: b9 A
- NVIC_Init(&NVIC_InitStructure);
+ k4 k" c( e! E* p - : k3 z2 W( c! ^ N, A" K3 J
- /* CAN configuration ********************************************************/) ]9 ?4 q% u1 J% \7 N/ v( W
- /* Enable CAN clock */, q+ X3 _6 d8 M- j) I) d
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);$ Z' q/ y8 a7 ^: s, K1 l
% G2 e7 F( i- D- /* CAN register init */
! \8 A7 ?2 I1 a - CAN_DeInit(CAN);
& r0 v6 d' J6 B8 l - CAN_StructInit(&CAN_InitStructure);1 b+ Y) H) s7 f4 i
% x, o0 N+ c; q6 t y: q9 R+ a- /* CAN cell init */
& d( R7 v$ m( V - CAN_InitStructure.CAN_TTCM = DISABLE;3 B* d L: M5 y2 ?/ \
- CAN_InitStructure.CAN_ABOM = DISABLE;
9 F; h' c9 \, [# ~! Q' t - CAN_InitStructure.CAN_AWUM = DISABLE;
& m5 A' C* e; L5 T; O3 k - CAN_InitStructure.CAN_NART = DISABLE;
/ m+ G2 K2 o0 ^0 z3 d - CAN_InitStructure.CAN_RFLM = DISABLE;% X8 {% t8 p; U" Z- B6 f8 W
- CAN_InitStructure.CAN_TXFP = DISABLE;* z" }$ |" E8 m4 T) K' P( K0 F
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
$ k) I: L- \# }8 a) a - //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;- e0 q9 \/ e" C
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;- b3 X/ c+ V9 |6 }5 U4 y
- ! H; j- ~5 ?* F1 \5 b5 Q9 u
- //200k的配置, |( \5 n) e- L) f8 I# |6 c
- //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k
! `% a0 j8 B4 K8 G - /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */. U- s/ N# s5 }! x$ @( Y
- CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
4 t p* C5 V0 _) D* i - CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
$ [! L0 s3 m* Q6 B" b) s6 S - CAN_InitStructure.CAN_Prescaler = 12;
5 f0 Z8 u4 } b. Z6 ]$ g - CAN_Init(CAN, &CAN_InitStructure);
/ p# {, f. ?8 o+ z7 \/ |+ R
& I' z8 T$ H9 Y! e$ i, z* z* N+ Y' y- /* CAN filter init */
" S+ X# i& j2 g a: s: w0 \ - CAN_FilterInitStructure.CAN_FilterNumber = 1;
: O' j# G9 X1 i: J4 ~ - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;! ^, b, d5 ~) L
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
4 }# Z, U$ v: G5 B - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
1 l) u& z2 U7 t# p8 O- [' v* ] - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;+ d/ Q( `! J/ _* G. w6 k
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
1 S. m: B; _8 z/ g, K4 ] - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; \: L4 A( b/ ]% k% C$ C
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
. m6 B3 P8 a4 b, R% S - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
7 `. Z& Z2 P' A! K, |/ u - CAN_FilterInit(&CAN_FilterInitStructure);
, t: R: V0 s% L8 A, _ - /* Transmit Structure preparation */6 P, n# J# ^% k& Y+ c0 ^ ?
0 P8 Z6 c1 U& W @$ y2 i8 L- /* Enable FIFO 0 message pending Interrupt */! C S- J- n- y2 N E# l# u( g' o
- CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
* @: G& c2 a; t1 p4 d- T, o4 w6 N: J - }/ i0 z! i4 O+ @: b! q) Z/ [
( y- ], h8 j% \- 3 g) R& j: N4 D: r8 K% a
复制代码
) H% b) w0 T; z/ d! J& @1 e2 d, ]: S
|