这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,
; O2 ?' g9 O8 T
% U. ~# `+ |- w- J- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码 * s# k8 s$ y! [6 b5 a7 t
结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。
/ L, G* Y+ H. T% X6 ]) K
) _& |1 q/ e- P# E2 U+ i( a- D由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。
5 f5 ? S# c' @) X. ]4 U/ V" }6 Z
( I, L9 v: D$ H7 f1 |3 i' S- DEBUG [D] main:94 hello armwind! s1 R$ z% {% p' Y& }& Z& F( i
- DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码 + |: z7 U! C$ h) c9 h
查看源码发现,断言表明,这个方法只能映射系统mem.
' `' [% }% |6 Z, F: z# @* ~0 M+ K1 o; P _, V$ t2 v; l
- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)/ \ f6 g r, Q1 \
- {
" `+ \( b6 u2 ?* c7 h% q8 L - uint32_t tmpctrl = 0;) ]. v3 g( V! q1 v' K: G- E% o
, Q0 ~5 ~4 X# D1 Y1 O2 X- /* Check the parameter */, U0 A; @6 ^8 \
- assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));
0 c0 ?$ U; G+ G7 \9 { - 9 {8 r* y, j4 ?
- /* Get CFGR1 register value */
, {) a; o1 ?0 z - tmpctrl = SYSCFG->CFGR1;$ I G: O! p$ _( m* G% T
- $ U3 Z& @6 p- P* J0 P; T
- /* Clear MEM_MODE bits */
M% E9 x1 M$ V - tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
* ]$ Q/ K5 m- Y4 K: N/ o
8 W V' s8 Y- X2 @; `' l- /* Set the new MEM_MODE bits value */
1 Z0 M V7 R3 `7 S' E \# Q1 @" l6 ] - tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;' n3 f0 g0 C9 O" C! L- L
$ f. J/ C4 d1 v6 s" |- /* Set CFGR1 register with the new memory remap configuration */
( F; h. }9 b9 P7 v- A$ Y - SYSCFG->CFGR1 = tmpctrl;8 J- `6 O- G- v" P u8 J
- }8 J0 j% b* h1 ?$ J5 b* l' y# y1 d# w7 ^
- ; d5 ^" T* N# h0 a5 H& q. C' {
- //宏定义很明显( a, ~$ H# h) r: K, H S
- #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \
! H! D8 i$ N, E0 q! D% |- U - ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \; w. e5 c% ?2 m) Y1 t
- ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码
: [& y8 X" m0 Y) i' o所以使用下面代码即可map成功2 t8 k& S& G- \* L
" V9 X& D* c' G
- //不要覆盖掉系统原始的配置$ d! B# s+ H5 ], V9 i# \# N# t
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码
T4 A6 U7 g8 q% b0 @/ L7 p完整的Can初始化代码6 N! Y5 U t0 p) m% u- f
1 Z8 T [" \ \+ b# M7 ]! |3 Z
- void can_init(void)% a% j' v: q+ N' U4 \
- {
: Q4 T& e4 X8 {) r - GPIO_InitTypeDef GPIO_InitStructure;5 n$ k& O0 h% [3 r' P1 X
- NVIC_InitTypeDef NVIC_InitStructure;* q" Z' O: V/ I1 r$ F( s
- CAN_InitTypeDef CAN_InitStructure;3 o# t _( {& j, f. S
- CAN_FilterInitTypeDef CAN_FilterInitStructure;
* o' I$ t% M, s0 A# Q
( N' t% p( U' r" y$ M* J( G- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);: `$ w: ^" y( z# u& f# L7 @5 A
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;- i% b6 v# p5 I4 E& S
. @0 f" I3 q! J# A2 f- //这里一定要先映射GPIO$ M. v( [! y+ X
- /* Enable GPIO clock */
) E9 @, d, a/ c0 t( W" P - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
, U) W R D2 h- [# [7 L+ Y; F- e - /* Connect CAN pins to AF7 */
7 ~( _$ j* o. ^& V+ g L3 X - /* CAN GPIOs configuration **************************************************/( i" u' A: G6 d: e) y6 Y3 p! z; |
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
; F! ^$ k6 @1 r( C4 S, R# L- E- N* a - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);
, w; Y; o: t0 z/ T7 ]4 q8 S
( l$ L( O$ z9 [) ~. @# }- /* Configure CAN RX and TX pins */
7 }7 g- T# U7 {: T5 n; Z - GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;& F' z3 C! R8 c3 U, A. q" R5 I) j
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
- `: f/ b+ w0 l$ e- R7 r3 H5 i - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
7 \% A9 c2 l' C* C - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
& L* {2 A Q- c x - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
1 \' {7 z# S2 t' D v" h# E8 ~ - GPIO_Init(GPIOA, &GPIO_InitStructure);1 l' _5 `4 D4 O) O
8 C( a% W3 j3 X8 f% l: g* }1 a- /* NVIC configuration *******************************************************/
9 m8 N7 @" z8 [8 [ - NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;0 u; D+ V7 \( [ D
- NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;1 y4 T; k$ y% _" H
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;. V1 w+ D! W8 s. b$ c7 _
- NVIC_Init(&NVIC_InitStructure);
$ z3 V- w+ a8 @% Z - " Z& O( N; Z" E5 r; U( z
- /* CAN configuration ********************************************************/+ _3 p' r, k1 P) w8 Q
- /* Enable CAN clock */
7 Z$ s' O( ], o0 `$ a, C0 c) {# R - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);/ Y4 S3 \' l7 n b# W/ N( [! z, [4 c; t
- ) P3 Y8 ~ E. D$ W3 O, Z) ~
- /* CAN register init */8 k L; A4 ]5 L9 r+ g, v
- CAN_DeInit(CAN);
# D5 g/ v5 w0 a - CAN_StructInit(&CAN_InitStructure);
. B* r' j0 v- o) U. ~
8 _* H$ C8 }' d: a) o! N, X! Y/ _- /* CAN cell init */
+ Y( ^1 E$ Y4 L' W7 g; ^ - CAN_InitStructure.CAN_TTCM = DISABLE;, t+ {) [ S' _* l* m
- CAN_InitStructure.CAN_ABOM = DISABLE;/ {. F/ _9 g6 R( B8 G y
- CAN_InitStructure.CAN_AWUM = DISABLE;
. |4 |7 R( j2 l: S& x6 _, v - CAN_InitStructure.CAN_NART = DISABLE;- K* x/ Z1 d$ f. r- l" I) f) L, P8 j
- CAN_InitStructure.CAN_RFLM = DISABLE;
6 d( T) O9 ~4 O - CAN_InitStructure.CAN_TXFP = DISABLE;9 ]& a6 B ^# T- D7 Q+ R- J
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;" M, V6 L2 R" I2 c
- //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
4 r4 R5 Y# v C* P - CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
# S1 t% b J1 ]6 P
9 r# R1 m0 O: O- //200k的配置
; o0 L6 c1 W9 L5 B - //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k
. v5 K; ?3 ?1 @4 a4 V% X - /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */8 T6 [ q# X1 E0 n! d8 y5 M% h
- CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;- ~6 W' ]! k: M
- CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
: O# G9 E# B/ ~: j& }4 C8 Z - CAN_InitStructure.CAN_Prescaler = 12;
# u% b- s4 u0 }8 p$ g7 { - CAN_Init(CAN, &CAN_InitStructure);
0 K$ C4 `) E- O$ |* g
! s8 X- v: y# [% ?2 J4 R! `- /* CAN filter init */6 H, |! [4 l; W# h
- CAN_FilterInitStructure.CAN_FilterNumber = 1;2 E2 n! _# w+ Q: Q1 W* q
- CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
3 Q/ H: X/ w7 g2 \8 z9 H2 ?, p% N a - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
9 E9 r" N: o6 w6 b% Y' ` - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
( y2 _% h$ S2 _. C; [ - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
! ?1 @* j! r. x0 s; ] - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
. j" @+ {( V5 ^ - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
2 `7 U) _, s1 Z$ |% w - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
/ N2 M$ h( o; o# C. ]5 d - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
0 c3 _5 Y, [, r5 f - CAN_FilterInit(&CAN_FilterInitStructure);
0 E8 |3 D8 y9 l2 W - /* Transmit Structure preparation */8 L( e; O" ?- o5 @2 q. g
3 {0 R: Z6 _0 y2 t9 }. M# q1 U E- /* Enable FIFO 0 message pending Interrupt */
2 U8 e, v; A8 \& @; O9 a7 w6 v - CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
+ j4 G/ p# h: i' h6 m - }( s" l8 p2 t0 v* |. l# _
- 6 z; r6 u6 G: e0 t2 h. _2 l
) B# Q! ?2 O5 `- v* a% w* g) Q* X. V
复制代码 7 p9 x$ ~1 f! E% n1 ^
& ?5 o- Z& B. U* [* f5 s* o |