这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,
6 ^; C+ B( N; A* d# j/ I9 ^% s& r1 ^4 x; E
- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码
% K: a6 w7 [4 |: L9 R- g结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。$ S, I; \) |& U( ~
. [) {# I; o# j0 Y1 G9 }4 N+ s由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。 A! w0 b3 @* z7 g
3 _- \' a8 Z0 V- k$ {1 R- K- DEBUG [D] main:94 hello armwind
% g( A! o# \ j( b( Z0 J4 }) T - DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码 2 Q3 G( a% D' }9 b9 j; H( D
查看源码发现,断言表明,这个方法只能映射系统mem.
, d9 n0 Y* r9 {& H2 f7 h! J+ o, h' s* o% ?; g
- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)
0 Q" X: X8 e8 G* \6 F - {
& ^3 h* I4 f8 |$ {; C' l - uint32_t tmpctrl = 0;/ @* _, a o( Q7 N6 t
. ?9 s6 Q) {5 h( H$ E5 o0 A- /* Check the parameter */
2 W: G, Z" h5 G% l9 J, q! b - assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
( I' R( v" Y0 Q3 d) V* z$ n
. x X0 u8 l) @+ S- /* Get CFGR1 register value */8 G$ v6 |' L. H8 c- I( J" z
- tmpctrl = SYSCFG->CFGR1;
8 M( O; w4 @/ `" [ - 9 r8 ^+ c. x2 @, V7 g* ?# a
- /* Clear MEM_MODE bits */
8 w( q* }; {3 D, y - tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);1 R8 B8 ^1 A1 n) f' b
- # v |, M' h1 ]2 s
- /* Set the new MEM_MODE bits value */
; f! a# |3 Q3 f( G! n: _ - tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
1 C1 E3 ^9 t; { - ; n! o% }- Y+ D! e$ d
- /* Set CFGR1 register with the new memory remap configuration */4 {0 Q6 \ C$ \. x$ Y
- SYSCFG->CFGR1 = tmpctrl;
- T9 J% v; r- r - }* A9 N1 H* b, a9 K) Q% ~' q
- ) D6 E! `8 D( O/ G
- //宏定义很明显9 i8 a7 K$ g9 S4 O8 W
- #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \
9 z+ T; R! g, u7 s: d& P# A6 V; T - ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \" j% z" f; e$ X) P
- ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码
0 T" s5 L2 n6 D# V0 h所以使用下面代码即可map成功
4 u4 u% H8 R. i, l( T, B$ j$ }+ L5 z" @' s- a; ~
- //不要覆盖掉系统原始的配置
# r$ Z) }6 a/ ?, m& M8 ^ - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码 ! ^4 o$ ^0 d( a3 Z1 H" W$ ?
完整的Can初始化代码. g4 n/ J! n6 q1 `! Q3 M% x; K
- S0 U/ q' z; J; J/ z
- void can_init(void)' D" j$ K3 `" r) ]$ d2 Q
- {
2 A, I$ }7 c/ Z/ u: i5 a2 w - GPIO_InitTypeDef GPIO_InitStructure;
; L' P: M4 S: x5 \& I4 F; O$ m9 C - NVIC_InitTypeDef NVIC_InitStructure;- _( M$ N! t7 i5 Z$ X) Z- `$ h
- CAN_InitTypeDef CAN_InitStructure;' D; ~, o, ], D+ S% [* X, v2 Z0 l- C
- CAN_FilterInitTypeDef CAN_FilterInitStructure;
/ ?1 z! q' B7 s; z7 D - 5 F, k; C) U. b3 Q; Z2 H
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);) l( H7 q" H/ N7 I
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;9 s1 j5 W" k- x: |' L4 z; h
! a- m! D: m6 B( W/ M- //这里一定要先映射GPIO
) x- N9 K( x8 ~7 d( ]0 p - /* Enable GPIO clock */$ B$ ~# b. X7 ^5 e8 H1 u
- RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
& w7 k( ^4 M5 l% `1 m - /* Connect CAN pins to AF7 */
, q' M# P7 D! n8 | - /* CAN GPIOs configuration **************************************************/8 j5 H- @( W/ ~5 r* y7 u
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
7 }. P6 {( H1 ~5 @ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);
6 d0 F4 ]5 l: a# c3 f+ t; |2 p
% {( s0 l: |9 e0 i, ~. R, q8 H- /* Configure CAN RX and TX pins */% I, E$ o! I9 x; s
- GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;
" V& m p9 Q3 f - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- X& \ b! a( I9 F( y F% Z) ? - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;+ |& k6 O) H8 `! s9 b) e
- GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
( {9 F4 {+ t! @6 G2 P1 `, m9 @9 C& @$ f0 p - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;1 Y$ B. F% m3 |9 {; S/ ^
- GPIO_Init(GPIOA, &GPIO_InitStructure);' r$ W! X9 U- p4 u5 y1 [8 ?% \
- / O" `; a. s" X) J
- /* NVIC configuration *******************************************************/
4 E7 N3 x. L: Z9 L - NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;
0 v$ w' u# S( t9 Z! l1 V6 j - NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;
( L& p/ s: _+ X; w( V# t - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
4 F' Z" q# I* x$ l$ t - NVIC_Init(&NVIC_InitStructure);' C1 x% m6 _" u- u% @' n: A: Q% f
! u/ ~8 p( \1 M5 ~8 q- /* CAN configuration ********************************************************/7 ~& s) u P9 m* H. B4 g7 e* C) e" a* L
- /* Enable CAN clock */
3 A7 u! x: x6 \' Y9 J0 ] - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);' k& y! e. r% i& }3 A) R( R- G
& s" G) c- F: a- /* CAN register init */1 x) |& q' ]8 }% Q0 K# V
- CAN_DeInit(CAN);
# R9 x; B4 T: Y) ?# Z7 v2 I - CAN_StructInit(&CAN_InitStructure);
0 [1 |$ K- B5 q
# n3 {8 f+ C9 c- /* CAN cell init */
2 c$ h. k+ I: \/ a! h& K - CAN_InitStructure.CAN_TTCM = DISABLE;
; l6 g# B" }0 Z/ h7 x - CAN_InitStructure.CAN_ABOM = DISABLE;1 S% g& G( [0 a( @$ z0 u- A3 U
- CAN_InitStructure.CAN_AWUM = DISABLE;+ h/ ^1 g- t' L9 r7 c
- CAN_InitStructure.CAN_NART = DISABLE;* _9 O$ Y# @2 V- W
- CAN_InitStructure.CAN_RFLM = DISABLE;
0 r: y, t- x" B1 }8 P5 ~5 j - CAN_InitStructure.CAN_TXFP = DISABLE;, q- Z0 M' L' n' B8 H5 }1 p
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
9 [3 M7 t5 b1 w v; ?& F7 \ - //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;: D" L& ~) ?; _( U
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
' v4 |: R3 J& {; L8 h" x* N* c% b
8 Q: k( b! C- d: d+ z8 k( l- //200k的配置
( P3 E. H! Y* W+ K% e$ `* a( ?6 J6 T - //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k
# c3 P6 F* p" u, T5 a0 j0 X - /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */( T% a. g/ s0 X
- CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;+ v) G) G. A& }! @
- CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;- i6 C, u3 B6 R* M1 q
- CAN_InitStructure.CAN_Prescaler = 12;
4 A, v3 J+ X/ T4 P3 z0 n - CAN_Init(CAN, &CAN_InitStructure);; \5 _% V2 `% b$ m R
) u% h% Y) Z$ g: V- /* CAN filter init */
' ^$ j" e) ~( o - CAN_FilterInitStructure.CAN_FilterNumber = 1;; L% G0 k1 I4 F
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;) ~; ?' I/ O; ] d0 W7 q
- CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
* A& q; b, i- x8 K* N - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;" E8 \; J4 I _. I' M
- CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
3 P. }% U0 E3 g' ?; X, u2 M - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;: i" e" ^2 Q: T* [1 l( B
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
) I& g. C. E" s( E l# f* I0 g - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
( Q* B: }5 R! h0 i4 u# ? - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
a8 u" s) }# x+ e% i! } - CAN_FilterInit(&CAN_FilterInitStructure);& Q* r4 L: m- ^& ?& ~
- /* Transmit Structure preparation */
+ N& b7 c$ C% E5 W$ _
: c6 w6 h! V2 @- /* Enable FIFO 0 message pending Interrupt */5 n' v4 P- m) D% t; _
- CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
. [8 @1 e# Q3 [( r - }
* Q* y, k- {0 D3 T4 b; z
1 s7 k1 z3 r& |) @- ; U2 u) q: u F
复制代码 : {7 z; k) r! E
! O: i1 y- Y- Z8 t
|