这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,/ u5 ~7 l: i0 x/ W% X
3 f: J! O S4 ?
- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码 2 b: a/ x! J! X8 [: k/ L
结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。
, F% o/ ?5 e, d l' [
/ M! n: Q2 o9 @' B# `+ s/ V+ {由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。
4 A! j+ [8 g! X5 n: Q' ^& i2 ^2 v
! v8 o9 z( G+ H- DEBUG [D] main:94 hello armwind0 c9 n7 `; W- k5 L) z! |: @
- DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码
9 i" w) D L" \5 C" g查看源码发现,断言表明,这个方法只能映射系统mem.3 O, Q+ P- ]) K" C
9 d ?: c+ H* K7 R- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)2 C+ p% K* _ X8 g5 u
- {
, L: W1 B5 p9 `- C/ X! e+ N ?* w5 t - uint32_t tmpctrl = 0;
3 ?7 `$ K1 R1 w# P$ h - ' ^, k( w5 t3 R
- /* Check the parameter */
3 j8 N* [1 x* F - assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));. y4 z, v5 m- \. L
5 b2 d4 m- }3 d: f- /* Get CFGR1 register value */
, d" W0 L% w8 l3 z; ~ n9 n - tmpctrl = SYSCFG->CFGR1;6 {8 j; K2 E3 k& B {5 b
8 H w) m7 r' q5 Q; B" y- /* Clear MEM_MODE bits */' S# D% v# L4 V& H
- tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);. w' B% g7 P2 A
- 6 f2 z7 V5 n! |% R& k
- /* Set the new MEM_MODE bits value */0 O& J# N' u- ]2 m0 @! |
- tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;
4 ]' G7 a$ D5 N
5 K0 z& y P b% d' O; L: P- /* Set CFGR1 register with the new memory remap configuration */! h, ?8 s D4 N4 L4 ~1 y9 s
- SYSCFG->CFGR1 = tmpctrl;
+ M( F- ^0 u! V' u6 g9 w - }$ T# f1 p5 }/ r. L5 F$ Y
# T+ i0 ~2 R' P3 I1 }- e- //宏定义很明显
0 q1 x$ p8 x/ H" x5 h* k, f" ?- E2 ^ - #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \4 r2 m( \$ W% s0 b
- ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \
; ?4 y5 _5 M! q: k Q5 k - ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码 - W0 u7 |/ u v
所以使用下面代码即可map成功
' B9 X% S7 L! V) G
/ z" k6 y1 R, m: @. T- //不要覆盖掉系统原始的配置
4 V1 j& Y" b8 i& X& o* q6 ~ - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码
* N5 A) l3 X. K) l; h1 n) g* P完整的Can初始化代码
% T! _ _0 z5 Q9 |8 [: S! ]2 w9 K) O8 }/ H& |) o
- void can_init(void)& g" {% G$ [& u2 `
- {
! m( |4 d2 x% H4 p - GPIO_InitTypeDef GPIO_InitStructure;$ d8 f1 Z& k8 |( f o9 z- Q
- NVIC_InitTypeDef NVIC_InitStructure;+ [* H+ B( ^7 R: T$ j( @8 W1 f2 l
- CAN_InitTypeDef CAN_InitStructure;
' V' }, {9 A# Y+ A1 I m - CAN_FilterInitTypeDef CAN_FilterInitStructure;+ ^/ l, b$ j4 u# V0 ^
- 1 K i) t+ b' y) f) d/ u& \
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);5 I$ f' N9 L A- p3 {( g. ^/ u8 W9 B6 P+ i
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;! i% y) J" }: o" q+ c+ X
' M# ?3 d+ `$ ~8 ]' G7 L, |$ S- //这里一定要先映射GPIO# q4 [# H/ @. x9 u: j
- /* Enable GPIO clock */
0 w5 Z9 t4 {: O! H! a( Z+ J! u - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
" x% U. t3 k/ v8 Z( q3 `+ Y3 q2 g4 r6 R - /* Connect CAN pins to AF7 */' O0 J3 o9 U0 F8 y5 F7 @
- /* CAN GPIOs configuration **************************************************/( j0 P% d$ {; N A
- GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
, d% |2 Z ~& u& t/ C5 | - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);
! n+ r! S) N- f; m
8 `1 r) y% w5 r, k- /* Configure CAN RX and TX pins */& @# [3 ?" g" e* y- M' S6 i* ^/ }0 T
- GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;+ }3 K% O- c4 d$ o9 ~+ S7 C; d A, l
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;, S' q5 G- ?. t+ E
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
2 K% V+ g- s" y - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;& s; e; U" w2 v9 h
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
% X* A8 G) s2 b! j - GPIO_Init(GPIOA, &GPIO_InitStructure);
+ S m0 ~( R+ X7 H Z - # [9 t3 m, ~- p( A
- /* NVIC configuration *******************************************************/' i9 Y$ U2 o2 K! ?( Q" S
- NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;3 b' a# q( e' [- G+ {
- NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;
! t2 L# u D h- Y; q2 q/ v - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
; @* y1 V6 B# p7 A, ?2 a/ h0 X - NVIC_Init(&NVIC_InitStructure);1 P) V+ N2 `$ b
- : P3 h$ e' Q5 [; F; D8 a
- /* CAN configuration ********************************************************/
* T! d4 q! F: R# V, p% w# q; K$ Q - /* Enable CAN clock */. K, f2 {6 B6 m4 I: B" |
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);
* Z, }" M/ J4 O; e( ?4 u( u+ P
! K: x9 Y7 ^$ }" T1 M7 X% `+ v- /* CAN register init */6 w* J0 |9 x# x
- CAN_DeInit(CAN);% q" Z- L; }" o
- CAN_StructInit(&CAN_InitStructure);
# }( T" i& {* j( S - 2 K5 n" k& N( H1 [2 |9 N- T* X# \! }
- /* CAN cell init */
$ c" B: z8 A# ]; i) j1 } - CAN_InitStructure.CAN_TTCM = DISABLE;8 U. x' x/ W I& A5 t- `
- CAN_InitStructure.CAN_ABOM = DISABLE;8 V$ i6 w$ Z4 F) L8 y
- CAN_InitStructure.CAN_AWUM = DISABLE;/ }( F5 q& E1 b0 C
- CAN_InitStructure.CAN_NART = DISABLE;: v" m4 u1 d7 |# I
- CAN_InitStructure.CAN_RFLM = DISABLE;
; {5 w. X Z1 f* ]! _2 g+ A W - CAN_InitStructure.CAN_TXFP = DISABLE;
& f. d) A9 g O - CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;! y1 K2 }' G) Y( b
- //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;7 x6 I8 x+ I% T( Z3 ?* b, k. Q! l
- CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;" P& Q1 f) ^1 C0 A
- d2 R: R0 d: D3 [
- //200k的配置9 Z0 u+ m& N. m' u7 k2 O! h1 o
- //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k9 p& u9 n2 e8 o
- /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */: M. E# }' Q" P% J
- CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
- z5 _1 D- i3 t: \6 _ ^ - CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;
+ i j- k5 ~7 [& q5 i: M. s - CAN_InitStructure.CAN_Prescaler = 12;
; H1 t7 m9 J; | I% Y - CAN_Init(CAN, &CAN_InitStructure);
- l8 p, k0 B* X2 d - 8 J! U8 m) M$ f# \# H6 v: P6 d
- /* CAN filter init */' L/ h- M. f0 i( ?$ j
- CAN_FilterInitStructure.CAN_FilterNumber = 1;
( `, X8 i- r+ H1 Z - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
, y6 e: U( [/ x1 w" K; n$ o - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;& {9 P' l8 Z3 @
- CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;& Q7 K' b- V1 V( w
- CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
% `; M3 h+ w! |3 V6 s# L. N [ - CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
6 u! V* ]7 S! i( Z# d - CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;. t+ x. O m7 x" K- e2 G( B3 @
- CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;( P4 L0 c$ M- F' I& X' t
- CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
* Q. d; N/ |/ R. x. J' h - CAN_FilterInit(&CAN_FilterInitStructure);; @) g- a& |( q0 P; p- B
- /* Transmit Structure preparation */
/ b( k8 T `( q* j# A4 G - , G& }0 |+ c6 k% ?6 d! f: n8 B s
- /* Enable FIFO 0 message pending Interrupt */
/ M* ^" S* M) `5 F% H9 u" K2 p - CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
( Y6 f0 T! d6 X; ]7 l p - }
9 Z* B6 F! m, c/ o - 0 e9 U+ Q7 f, J8 b5 e* G ^3 B
- ( G: X C9 x }2 B7 J1 ]
复制代码 % ^1 ?( H, ~9 a- v5 e: L1 n! K( M
* Y8 {/ m! F. c" n5 H
|