这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,4 h- t. P) Y+ r* g4 I- K- x/ g
, Y5 T+ r, y) f6 r* X) A5 K
- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码
& w7 o6 X+ ^! t9 Z- v结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。/ \9 c* f2 @ Q) R% \$ M
* w& i4 Z1 O& `. B4 k( Z+ F由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。
/ Y6 b% V' ^$ u; N/ p* I
, ? V9 E! C0 {. s- DEBUG [D] main:94 hello armwind3 _5 v7 X1 K; i: F3 P
- DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码
4 y, w8 t6 `% q5 A0 w, d查看源码发现,断言表明,这个方法只能映射系统mem.
w7 k! L& G8 h( b3 F. J2 }3 Q
! N& C+ q; C) ]- p6 T+ V. F4 F- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)6 N/ g7 A3 q$ c5 m; X4 J1 B) y& c" S
- {
4 {# R! S8 ~ T3 b. G - uint32_t tmpctrl = 0;5 T; k! g. Y4 X5 W0 _+ S
2 B1 K& O0 a. ]! ]$ Y4 l. ]& L- /* Check the parameter */4 ^- ^6 n. H. A
- assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
. E* X2 v8 [$ G - $ ^: U7 `/ l! ?& N/ X- t
- /* Get CFGR1 register value */
; z5 ~+ q. K- [2 E4 x& j, A$ B - tmpctrl = SYSCFG->CFGR1;) O, z; I) d6 e
- 6 O2 P5 ^- w: W# A. X3 O: b
- /* Clear MEM_MODE bits */
, b" K l& t: b- N4 a - tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);+ H9 w0 o+ D2 G; `* ?9 x" q& n
- l- y. ~! b: f" Y: ]- /* Set the new MEM_MODE bits value */) n$ X3 R$ S1 k1 P
- tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;( K! N8 s- g; X5 `
, k, `$ A( u- \: S' n- /* Set CFGR1 register with the new memory remap configuration */1 ]0 N% w; W7 ]* u' M, x7 K
- SYSCFG->CFGR1 = tmpctrl;- k: U9 Y' [, ~2 j' v3 p
- }
0 X8 Q7 s8 B" _5 X- M - , A) j6 z2 g9 m1 E+ p9 _
- //宏定义很明显" o: f1 G% }4 D& K& B4 K
- #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \+ q, d& {! d; m5 g7 Q
- ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \
6 y( M" W- I E+ T - ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码
@& U2 j* K) h+ l# e9 J所以使用下面代码即可map成功
9 h M) u' a2 @( O$ X: K+ G+ F4 D* e
- //不要覆盖掉系统原始的配置
! O+ [4 V+ S2 I - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码
2 q/ m; \( p2 O' A0 j* ~8 n完整的Can初始化代码
; @' N2 |6 E+ N" Q4 ]! R1 K( F2 y' r. i# R7 n. b
- void can_init(void)2 W: b( f4 U( g- Y' G
- {# Y& Q3 f7 @9 d3 J
- GPIO_InitTypeDef GPIO_InitStructure;, M) I6 n. b) k+ y9 l: v
- NVIC_InitTypeDef NVIC_InitStructure;+ Z. l/ j- j, `7 r& Z! l
- CAN_InitTypeDef CAN_InitStructure;7 j4 Z$ p; R0 s% i, w" T( v: w
- CAN_FilterInitTypeDef CAN_FilterInitStructure;
K& i" G" k8 ?& u8 R n$ ?# S - 4 n1 C d; D3 J+ i n' e* F
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);! j' e2 p9 X3 E( d- e
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
|$ X0 r6 o" g1 L. z0 m: U# W8 W$ ~! c
+ ]8 A2 \% J1 |7 _- //这里一定要先映射GPIO
7 Q& I- p: @; ]0 s) Z, h - /* Enable GPIO clock */
' [. b6 c7 w; j2 _; O: T# g - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);+ g. c& w$ k; @# y% `
- /* Connect CAN pins to AF7 */
' s! {* `5 [7 d9 B4 a0 Q - /* CAN GPIOs configuration **************************************************/. d9 X( D) W4 o) `- R& f+ S
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
6 B) [: p7 n0 _% r0 H! f' W: l- p: x - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);" f/ l v" P) g/ z$ G" m) u- \
: d/ q+ g6 z' A1 h- /* Configure CAN RX and TX pins */7 s5 {+ Y% F/ M Q
- GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;
9 f* z7 u; W- ^' ?2 o - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
8 _# T& v; e# c. W1 K - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;3 s& s/ p9 X8 D& B7 w& s! a
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; s; K; @, U* v! `8 m9 R. t4 K& ^4 q
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
. \3 A9 h2 P4 Z7 v8 M) `5 N. l- H - GPIO_Init(GPIOA, &GPIO_InitStructure);
$ q. ?4 h) q" U2 W - 1 L* u6 l% F9 D* g2 {# I# s
- /* NVIC configuration *******************************************************/2 r2 u0 e' u1 }' z- c: W
- NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;
( m: ^9 m6 {8 a - NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;7 B: n1 x3 S' h, f2 { j' i
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;: O9 {! C8 T" M! Z5 ?2 p
- NVIC_Init(&NVIC_InitStructure);% U6 d/ G+ t) X: x% }, {# v
- 5 D* Q1 F# K, o- N
- /* CAN configuration ********************************************************/# u/ S1 }# L- E! {4 e" o. l' t& W
- /* Enable CAN clock */5 R$ ~* V% K& o% H G8 K
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);1 i3 u1 I* Q- N- u1 A3 _' `+ ]. u
- 7 p9 h8 |& ^2 U% @# J
- /* CAN register init */9 t1 N7 g) @, V) \
- CAN_DeInit(CAN);+ G5 f/ ]9 U( q3 r% {, m9 g. x) o3 x
- CAN_StructInit(&CAN_InitStructure);3 i( c% O& r; N8 R g
- 7 K& T y- N4 v
- /* CAN cell init */
8 t! Z& f! o @ - CAN_InitStructure.CAN_TTCM = DISABLE;
H$ M* ~! L( L' p/ k, {8 x - CAN_InitStructure.CAN_ABOM = DISABLE;+ V9 y7 r8 L& J( c# g: W
- CAN_InitStructure.CAN_AWUM = DISABLE;
) ~3 }4 N. Y5 {$ U - CAN_InitStructure.CAN_NART = DISABLE;
1 g6 b2 B1 e' R# N; o6 g; { - CAN_InitStructure.CAN_RFLM = DISABLE;" c3 Z7 @8 I( H; `+ J2 v0 e" b
- CAN_InitStructure.CAN_TXFP = DISABLE;( ~1 C+ x# _3 y( X" n. e
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
+ o0 Y3 K+ B6 \1 C; w* ~ s - //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;8 q6 u1 F- M% }8 s) y
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;, p% s: T- c1 ~
- ; {' a, A4 e$ C) ^
- //200k的配置
' h* `8 b) t. x4 @ S, T4 M2 p - //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k+ r4 h$ h: c+ G. P! Z
- /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */ k1 f* v$ t6 b S# D
- CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;/ M! {0 W! R6 Z6 T
- CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
9 A( r# q1 S, s( j - CAN_InitStructure.CAN_Prescaler = 12;
) `* N( A* a, f/ a; a - CAN_Init(CAN, &CAN_InitStructure);$ ^! b$ V3 Z$ |0 S
0 Z6 ~6 B; g4 w, {7 N$ _' r$ J- /* CAN filter init */
: o# a* W- B3 |, h - CAN_FilterInitStructure.CAN_FilterNumber = 1;
# c3 ]7 ^+ J* N/ Z# e+ N5 o - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;! q* n, ^7 e5 c* M; g
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;4 X0 Y/ v4 M' A9 W1 A
- CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;& A# t8 s8 E, S% l4 O) Y" v! n
- CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
- M7 E% y( F* U) q9 z/ p - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;9 W; f# s# m9 F& n
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
& a3 b9 U1 q, K6 w0 r7 n - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;8 g0 @8 a& H, d9 H, O7 D
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;8 B5 l Q- @% ~
- CAN_FilterInit(&CAN_FilterInitStructure);
- w: r3 t0 c6 U& J - /* Transmit Structure preparation */1 s2 U% S; D2 D" I
* ^4 p( Q2 K" k! d- /* Enable FIFO 0 message pending Interrupt */
( _1 f. l: w4 R: H9 J - CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
* }5 R: l) n' X0 U7 ? - }( }- z, Y R( F; L7 T
- 4 I; U& t1 Y; k& j
- _ b2 i0 d' o0 w* v3 z2 f* Z! d
复制代码
' a4 x; R3 N2 B3 G9 _! ~2 U, r; [9 v: }
|