这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,4 u% z+ T1 G4 p; J% P8 H
" m# C7 |1 w1 J3 F( F' I
- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码 ' B4 |- y! c4 z6 a
结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。- ~7 W2 ~" k4 A1 F# M
3 C y( h6 }7 T V由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。
4 ?2 m7 t& ^+ |1 o; h( w& A) M, {. V+ a- e
- DEBUG [D] main:94 hello armwind. B9 t# Z W4 N/ l2 v% K
- DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码
2 m( ^" w( H. ~5 M查看源码发现,断言表明,这个方法只能映射系统mem.- [; g$ I( R% m/ W& U1 s2 x
/ ~* r9 k; L. s4 H- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)- A1 h% {8 n+ X% X4 t- p! l
- {
' D' O2 P& i6 @" G" Z/ h- \6 h, R - uint32_t tmpctrl = 0;
6 x# [7 M4 {( T7 j - % b+ o) V8 r6 i, g
- /* Check the parameter */5 f' d- P# X3 l! m, P, o5 J
- assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
1 t( K- {7 z4 U* \ - # s1 q a: I; Z" I0 i+ }
- /* Get CFGR1 register value */
1 S9 c/ _( l/ K - tmpctrl = SYSCFG->CFGR1;; @3 h$ |) }" R4 x
9 W* J: l( b* A, z- /* Clear MEM_MODE bits */6 I4 c% l8 I% G
- tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);. R9 o) L; b9 _4 {+ U/ |
& l8 b" D/ m9 S7 j- /* Set the new MEM_MODE bits value */' T8 a3 L5 L! k/ \- N
- tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;% y9 ?% g$ N% m* e% r" u% ~
/ G1 X5 e, f7 J1 R- /* Set CFGR1 register with the new memory remap configuration */
0 t1 @: F6 `+ E, n' Z - SYSCFG->CFGR1 = tmpctrl;' r7 f; ~; q6 c( {
- }
; r) h2 {; w9 R9 T/ G
% W6 t& y6 Z0 Q4 r- //宏定义很明显, r/ V4 u/ K( Q7 W+ e4 S
- #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \7 U n I3 x+ l. L6 l
- ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \% W* H0 i1 A( a- ~% t' @8 w* q
- ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码
: Z8 C7 X0 K) v8 f4 Z# ^; b所以使用下面代码即可map成功' i7 c' h" f( k4 w8 w, b; O
5 L+ ]# M8 G1 P& a- //不要覆盖掉系统原始的配置- k9 P6 y8 @7 q3 {+ C
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码 ; }9 y- T! p2 J: y
完整的Can初始化代码
3 S& R4 X! j3 O
# d% `* q0 ?% t' C6 T/ R( {- void can_init(void)7 e2 K6 \& u+ @: K
- {% b6 g4 E. z3 Y& K- U/ S
- GPIO_InitTypeDef GPIO_InitStructure;3 I. f C- Z8 r* h9 z2 J2 `
- NVIC_InitTypeDef NVIC_InitStructure;
- a, m# p$ c+ U/ o - CAN_InitTypeDef CAN_InitStructure;4 _* x% Q$ c9 p; u4 a5 j$ z+ M( o! n
- CAN_FilterInitTypeDef CAN_FilterInitStructure;
' v- m3 M9 a8 R5 l0 s* W
) J- `" ?$ X) v; T* f" T- G4 {, n- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
$ V. ^! F% `& t! g& m0 j - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
) A. `/ ^" q- i
; B2 K; `) I9 B: z3 ^- //这里一定要先映射GPIO
% `( t8 v9 E# y4 w - /* Enable GPIO clock */" `. F9 `* Q+ {
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
' e" W! r6 |2 M) t+ \ - /* Connect CAN pins to AF7 */
9 R' g, q1 N" ^ - /* CAN GPIOs configuration **************************************************/: C1 B9 P) P) L/ |
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
' D% s: J! O% n- H. U - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);
5 ?6 Q* n& i4 Z' [/ A
- Z- s5 |* R) R5 a) u1 O; @- /* Configure CAN RX and TX pins */) P/ K& N+ `7 N: X$ Y: `
- GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;7 y# P) h6 I0 c q8 A( f
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;$ k0 w1 S- s4 E; B' x
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
8 I( x0 P; I. ~ - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
4 A: I* i& I+ _9 o) }7 ~ - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;/ {4 }" ?% s* D2 n, ], L) M
- GPIO_Init(GPIOA, &GPIO_InitStructure);) e9 O/ s" f9 C; u7 `! N7 K1 b
7 D, S% m; U7 Z; \" ]& s- /* NVIC configuration *******************************************************/9 e% L8 i( j$ v0 s- m
- NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;$ F# G; r M# W8 G, i3 |! B9 Q
- NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;7 x7 |1 p- \# O8 Y/ |+ h4 b- j
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
3 U0 k8 e h* p, _ - NVIC_Init(&NVIC_InitStructure);
& p Z& t. @% U; }2 g g3 H - 5 c/ u$ Y6 C. T
- /* CAN configuration ********************************************************/& X% m7 M$ x2 P7 S4 |
- /* Enable CAN clock */ F( e/ T4 s j/ s: p
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE); E1 Z; n' W9 `7 c
- " D1 {" l' z5 l
- /* CAN register init */
- I0 q; N* [' Z6 H - CAN_DeInit(CAN);
4 K4 }- t p8 k. Z! g9 V - CAN_StructInit(&CAN_InitStructure);
' h3 x- ?# e" L
% l8 A9 v! u& m- /* CAN cell init */
7 A$ W$ `2 @% T* z8 X - CAN_InitStructure.CAN_TTCM = DISABLE;
6 m* @+ P5 ~) n8 t: @6 G$ X - CAN_InitStructure.CAN_ABOM = DISABLE;
+ t5 j+ H* F3 s( v4 S0 U: z - CAN_InitStructure.CAN_AWUM = DISABLE;9 y4 m. c2 ]6 N: ~4 q
- CAN_InitStructure.CAN_NART = DISABLE;8 l2 W# d- \2 B. ?- O: h
- CAN_InitStructure.CAN_RFLM = DISABLE;
& g4 e5 j% i' a - CAN_InitStructure.CAN_TXFP = DISABLE;% o7 y+ n/ Q, R. q! Y K8 L( S
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;. W P3 {+ v) D( u9 W
- //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
! X: n# H+ s# P- [* ]9 O - CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;! t4 B/ |) Z1 R
- - F, R7 D6 z* Q7 M
- //200k的配置1 d- U9 W# [3 O' {
- //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k0 L1 f, y* P3 I3 v5 f
- /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */& C+ n7 y" b: Z
- CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;3 ?+ _, d: U" I2 n7 Z
- CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;2 @/ ~ k. M% [# u5 k0 e1 w6 A
- CAN_InitStructure.CAN_Prescaler = 12;
9 I& A$ s* E) b3 r3 w. ~ - CAN_Init(CAN, &CAN_InitStructure);+ i5 `6 t6 c8 {
- & h) }# z# r; K( P: I8 v
- /* CAN filter init */
' N0 h: o$ u0 c) m& s! \& \8 V - CAN_FilterInitStructure.CAN_FilterNumber = 1;8 j7 G% r" M# ~
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
7 g0 z8 [" I0 M1 G; o! f7 y - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;- S! Q: r2 x1 ~: b
- CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;, Y" @7 k6 q6 x+ O8 \( T5 P
- CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;5 t# y' x! z7 Q+ a
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
) n p1 d2 G6 |7 ^ - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;7 `0 J2 _6 x) K* N: R4 w( X
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
4 I7 }7 s* s" }" m& ^4 i$ g* ^( Q - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;6 _5 A5 t7 a+ ]4 E5 B8 P* v m' }
- CAN_FilterInit(&CAN_FilterInitStructure);! ^2 P j, N, }7 l: ]
- /* Transmit Structure preparation */; u. K" g2 M3 c, a' L/ z7 ?, a# P
- 4 T! J# X5 k; _" U" K9 A' A' F) i
- /* Enable FIFO 0 message pending Interrupt */9 Z+ `, w2 a1 p& ^
- CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
4 Q, y1 k7 o9 P9 r+ d7 Z4 b - }
# D- }$ c. U5 h- C. I7 l0 j7 R+ ~ - % i0 s ^+ _: X$ {
# I. L! p0 n" ]' B+ P
复制代码
: U- G" F! o* _1 v0 X# T7 f/ A7 Z n7 G$ z4 Z9 `" U x! i
|