这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,) ]: ~2 a3 m- G+ Z) D; [" p
+ V q5 f5 D& t- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码 ' M) G/ I2 Z w9 m- Q9 n; r
结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。
' ?0 V+ N6 M% @0 ]
/ W; ~1 J$ s4 d i0 N$ l由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。- ~1 c2 G# ~$ w" j
' d: h& }, c# G! s$ P3 w- DEBUG [D] main:94 hello armwind. n$ Z: E. P1 C' @* @( F5 Q9 P
- DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码 ! Z0 g0 w. A5 Z3 D- N8 G
查看源码发现,断言表明,这个方法只能映射系统mem.: l7 l, J) f8 V! t
" j; i* N$ e4 G1 e* b1 J- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)- U0 w0 j6 K; |# K* S; P
- {0 C+ h8 L9 O/ {2 p9 l' k$ j
- uint32_t tmpctrl = 0;# G( O; c6 Y% a( L+ m3 }5 W$ Y
- " C( F/ c3 F& ~, f) B
- /* Check the parameter */
5 f S+ ?2 g4 |: q& h0 L5 Q5 ? T' K& I* E - assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
/ }8 _) G& e& j. N3 z) X0 I) o - # T' v3 w+ o, t I& q P
- /* Get CFGR1 register value */* u# ^. {2 j# y
- tmpctrl = SYSCFG->CFGR1;" s# N" x+ V/ [9 d& u
/ ^" G( }4 w9 _9 J' r- N% n- /* Clear MEM_MODE bits */
G2 `. v+ q# {3 D. ^ X& [: u - tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
f0 m4 q; \' c( R' w* p. r7 y& R - % b+ r6 V7 J# h. y$ ^! C2 d$ q! {& {
- /* Set the new MEM_MODE bits value */
; `! U: n1 m6 W' T# g8 _- b6 Y - tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
/ O0 o. x! }# z- l, |9 Y9 o - 9 o* I/ { H5 w3 j
- /* Set CFGR1 register with the new memory remap configuration */
, t1 q+ p! l# A0 L- F# o - SYSCFG->CFGR1 = tmpctrl;6 P+ v- G4 E8 S9 m8 y
- }
5 U1 y! { s7 f* P6 _+ k
: M' V2 ?2 H4 I/ }1 g% k( o4 X- //宏定义很明显" H8 E/ V3 R2 k4 g" A# U
- #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \
$ E" ]4 e# x' s/ w4 E1 V - ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \/ Z- Z) u0 ~" l+ \9 l0 R& V0 E
- ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码
+ \+ B; c. ~4 o所以使用下面代码即可map成功
* A4 ]# l. y9 I0 O. F1 T7 K; c2 E0 A6 D6 i! }% r/ F
- //不要覆盖掉系统原始的配置
9 K' x' B ~9 {& i3 ^ - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码 7 ?" h. M; q. S& H
完整的Can初始化代码3 q4 ?: B+ T# T+ r6 k
/ n: u1 B+ X1 k8 a0 n" I y+ Y- void can_init(void)
0 v% } p; r5 ]+ h3 Q$ U - {' i: C% Z1 n" x" Z/ L2 E
- GPIO_InitTypeDef GPIO_InitStructure;' A) r$ F; ^; b! U4 o+ Z; S% O
- NVIC_InitTypeDef NVIC_InitStructure;
, j) [' H$ I* z - CAN_InitTypeDef CAN_InitStructure;
" Z4 z! V( m B - CAN_FilterInitTypeDef CAN_FilterInitStructure;
' f; A& H5 R1 |# J
$ t# O7 f. [4 \' } l# r- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);+ |. [, y; F6 I/ i) g6 K
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;' I& X b) F/ N+ T; M0 K
- / _/ \: j O2 s6 U
- //这里一定要先映射GPIO5 Z; s m. l2 Q: b
- /* Enable GPIO clock */" I* n( a4 J0 F( f' ?0 m9 B5 u
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
( f" g7 M0 J& h# V4 w( D" O - /* Connect CAN pins to AF7 */0 A* | J W2 T: t9 |
- /* CAN GPIOs configuration **************************************************/
7 y/ J" [/ @2 o# E5 s; d2 J - GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
& d' z8 n5 Q; E8 S9 M, v - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);
4 y9 g# i' {+ S - $ F$ Z# B; o" L7 Y
- /* Configure CAN RX and TX pins */
# J( }: \5 ?/ A+ ^ - GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;. a7 ?# `! b! i) Y& S! b' V
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;6 [$ V! Y) c! h- K( I+ p
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
4 E, L% S, J' j6 q) } - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;8 x6 Z: w- H( n/ T, x1 i& p
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;3 C3 R$ ~$ B& ?0 A
- GPIO_Init(GPIOA, &GPIO_InitStructure);7 I8 y" z. P [/ j6 _4 q" G
- 4 l, e1 \+ r! y! h0 e
- /* NVIC configuration *******************************************************/$ p2 p3 | `+ F5 ^0 D6 p$ ?- t
- NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;1 B/ h1 ?0 t* U3 O9 x, F: p2 H) ?4 |
- NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;6 A" i, [' q& l4 _
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;3 |( K- Z c) K" f5 a
- NVIC_Init(&NVIC_InitStructure);
. G) @* p, B/ M5 I/ u+ @4 ^
2 P2 l- w' B& y, @: G5 j% |- /* CAN configuration ********************************************************/3 n# v* p* [, Y9 p
- /* Enable CAN clock */$ B. q7 r- \0 S" f% ]5 j
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
/ J/ t$ M+ b1 Y- c, N1 u
% D8 [) K: t- _) ]. E! E& W% `9 a: r- /* CAN register init */6 G4 ]( ]/ J7 F, m [
- CAN_DeInit(CAN);7 M6 j) r: C$ y' d9 J
- CAN_StructInit(&CAN_InitStructure);
9 E' a6 _) k7 b; T5 o
- m$ z' |0 d# v8 s9 v2 _, V- /* CAN cell init */
" m* f% x- I6 \! u* S3 J4 { - CAN_InitStructure.CAN_TTCM = DISABLE;& v2 C0 c7 w/ ^0 c/ e, I
- CAN_InitStructure.CAN_ABOM = DISABLE;
. r+ t+ s9 K( v( ]' h - CAN_InitStructure.CAN_AWUM = DISABLE;
0 Q5 j7 K/ S& o S6 K3 V8 p - CAN_InitStructure.CAN_NART = DISABLE;+ i4 }6 r% }, {, u
- CAN_InitStructure.CAN_RFLM = DISABLE;
0 }! B% C+ p- H; ~& r - CAN_InitStructure.CAN_TXFP = DISABLE;
1 S! M- E# \& g9 R3 p" D - CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
2 V' o2 R! y: v" o2 B- q( J: h% I - //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;$ p @) i- M5 ]+ L8 v X+ x
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;- C5 U/ k/ H9 [, `$ Z4 g: ]
- 5 f9 \. z7 m8 w6 m9 _0 M
- //200k的配置! I! [) n) H r: a/ r
- //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k6 a$ U+ L; T+ l9 h
- /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */) z2 n6 b2 N3 q# @+ n, Q
- CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
: C/ }5 D- r0 n" V - CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
& ~ ~. _/ F' ^! L$ H$ f M - CAN_InitStructure.CAN_Prescaler = 12;# P7 A+ l: f( |5 A8 |+ ]) G
- CAN_Init(CAN, &CAN_InitStructure);
1 h/ I/ c' c4 k; Q9 C5 q5 H+ u9 G7 Y - * P- i3 R) e: c
- /* CAN filter init *// J$ R$ }. _; w5 n7 f
- CAN_FilterInitStructure.CAN_FilterNumber = 1;
9 O$ N- J1 V5 U& s' }; K3 d: ?. y( N - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;$ ^. V9 f' ]6 J8 m$ H- B# }
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
. n) a: j' h# V m - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;( p7 x# u, j) H0 H, G* y/ w
- CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
1 {* a# {( w$ M5 A. ` - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
$ [4 n3 c* }, {+ W+ B. R - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;1 P1 h9 {4 r+ T
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;/ t2 F. x7 A9 q) j+ A
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;/ h& b7 s$ {2 S" y
- CAN_FilterInit(&CAN_FilterInitStructure);
% Q- U: B7 Y0 m9 q( N& R - /* Transmit Structure preparation */( f$ [3 \# Y6 w! V/ Q9 t
2 W( \6 ]- ^+ d0 a3 R- /* Enable FIFO 0 message pending Interrupt */
* a& J' D" w' M# z - CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);* l/ E# Y* i" i5 x+ w0 G& F S F
- }
( `' S8 j; P) ?& y8 d
7 |# p/ p# a w+ A6 X
p2 q3 \! r# A- _) g
复制代码
/ `0 j. _% a' d9 X: D& n% N0 X7 ]) ]4 M+ m# Y
|