这两天玩了一下stm32f042的can,但是折腾了2个晚上,还是没有进展。我知道stm32f042F6P6 ssop20封装的pin17,pin18默认是PA9,PA10的功能,如果想使用PA11和PA12,需要进行端口映射。这样的话,我直接就用了下面的代码,进行端口映射,
3 d0 N( y- z4 b5 f! x. r- N) S' [9 L" c- E. E" K- Q
- SYSCFG_MemoryRemapConfig(SYSCFG_CFGR1_PA11_PA12_RMP);
复制代码 / m; v3 V5 `% H" G/ |# T* g
结果Can总线一直没有波形出来。使用回环模式调试,总线上一直没有波形。
0 E5 y: K$ g9 \7 G0 P0 B! B$ k- @/ W$ j
由于CAN的PA11和PA12和串口1的PA9和PA10是复用的,没有第一时间使用串口进行调试。今天晚上下班将usart2飞线飞出来了。使能断言后,发现下面的断言错误。. l% }6 j0 r- Y- g9 d* F
X g" D1 K( h# h& N3 H& _0 F8 x j
- DEBUG [D] main:94 hello armwind
" ?, m! U& f" A Z+ ?2 q - DEBUG [D] assert_failed:94<div> …/Lib/STM32F0xx_StdPeriph_Driver/src/stm32f0xx_syscfg.c,line:119</div>
复制代码
6 x; I+ |6 z7 C3 F0 @查看源码发现,断言表明,这个方法只能映射系统mem.
. z }5 X/ X& r& d7 y+ m
2 i; f0 I7 m) _3 `( ]- void SYSCFG_MemoryRemapConfig(uint32_t SYSCFG_MemoryRemap)
& y5 P& v; F( `. j8 i- J* C2 k - {: \& S2 x- F% ?# z9 E
- uint32_t tmpctrl = 0;) g$ U# @; }: ]" [( @; K
- + j; \/ M) ^3 [# {) l
- /* Check the parameter */
2 N0 Q K3 J2 F! u7 S L4 ] - assert_param(IS_SYSCFG_MEMORY_REMAP(SYSCFG_MemoryRemap));7 D) S, [) X* l" Y9 F7 G/ `
" K: A# |9 Q+ Z+ D- /* Get CFGR1 register value *// J& ^, u7 x5 c7 D' o- U2 D
- tmpctrl = SYSCFG->CFGR1;
# H5 H! N; t% Q1 T/ `
D g2 Q1 {6 v/ |. W; }- /* Clear MEM_MODE bits */+ m) _( C4 i' H. t8 t) [
- tmpctrl &= (uint32_t) (~SYSCFG_CFGR1_MEM_MODE);
0 C* @! |1 i* c3 ~" P2 `$ ]! x - # B1 i/ A7 N9 y
- /* Set the new MEM_MODE bits value */( x: k/ X$ g: P8 P- ~9 W+ v. }" T
- tmpctrl |= (uint32_t) SYSCFG_MemoryRemap;+ b- j0 e2 L6 E6 P' \1 M7 K
- ) G9 `: }) \6 l1 L
- /* Set CFGR1 register with the new memory remap configuration */
4 ], Q1 M1 b/ e6 m$ n# ? - SYSCFG->CFGR1 = tmpctrl;% T6 U% w) Q8 L e# w
- }
2 ?: w7 a# N4 g - 9 M) ]3 k& g, r) i8 A: l, N9 v
- //宏定义很明显
3 J' z7 T m G5 k$ s( U" l% n - #define IS_SYSCFG_MEMORY_REMAP(REMAP) (((REMAP) == SYSCFG_MemoryRemap_Flash) || \
$ F' N: j) T# E - ((REMAP) == SYSCFG_MemoryRemap_SystemMemory) || \! u6 z% [# V B- G$ ?( L9 b
- ((REMAP) == SYSCFG_MemoryRemap_SRAM))
复制代码 " O/ p% }- ^4 t" l5 J* w$ z
所以使用下面代码即可map成功
+ x: `4 U" F6 a' C/ K- ~# l2 l( p! b& e4 U: S/ |* g4 ^4 N
- //不要覆盖掉系统原始的配置
( W) S/ H4 c3 h - SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;
复制代码
2 Y$ m5 ~3 `6 F9 @1 O8 w6 A' ^完整的Can初始化代码# `. k/ X S# ~5 F# Y& {
- M) M$ c' F. O1 q- ?
- void can_init(void)
2 e) u) _ c I/ }5 p - {& e5 Q k7 q' X4 @ S, u( A
- GPIO_InitTypeDef GPIO_InitStructure;5 F& @( q' X4 H6 D3 m6 `
- NVIC_InitTypeDef NVIC_InitStructure;
% Y# e3 r6 V5 S; S* T - CAN_InitTypeDef CAN_InitStructure;
1 a& O3 D6 {) E+ w% P4 l* ]5 b - CAN_FilterInitTypeDef CAN_FilterInitStructure;, C0 Z: H2 w f
- 7 t, c* ^" V( f
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);: q9 F' N# a# i% e4 |
- SYSCFG->CFGR1 = SYSCFG->CFGR1 | SYSCFG_CFGR1_PA11_PA12_RMP;7 s$ I# d! j4 D5 T9 ?/ T9 O: G5 X- n
- 8 T/ a( ^6 h* w9 ?! `% u
- //这里一定要先映射GPIO8 T) h7 u# f- T0 K
- /* Enable GPIO clock */
% O7 g8 T# n1 \6 V7 ]6 O+ Z - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);. O% U" Y( J2 Z1 ]
- /* Connect CAN pins to AF7 */
. Z. _4 t( a0 i0 k8 h# [6 E - /* CAN GPIOs configuration **************************************************/
0 y# I0 o- ^! D0 O% \ - GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_4);
2 E- U6 O8 e5 v3 I - GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_4);1 j4 ?8 [+ g2 M- A- \. ^
- + [7 ~& ~' d8 C* @: }" v
- /* Configure CAN RX and TX pins */* L# {; z. A `) A
- GPIO_InitStructure.GPIO_Pin = GPIO_PinSource11 | GPIO_PinSource12;
R. V: e. u6 A7 y& K! Q - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
6 E- R6 |0 i* [ - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
% z/ ?+ @: L0 ]/ q; X - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;- ^6 ^ D3 \- ?$ a1 e
- GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;$ ]; g5 H- d; E
- GPIO_Init(GPIOA, &GPIO_InitStructure);
' t7 G9 i( w& d! y6 k - 3 D: M% U. S+ o" Y
- /* NVIC configuration *******************************************************/
s+ N% Q: |8 c5 e% I+ D - NVIC_InitStructure.NVIC_IRQChannel = CEC_CAN_IRQn;
, I, o2 S4 O' Z4 C$ w - NVIC_InitStructure.NVIC_IRQChannelPriority = 0x0;
b/ R, Y: s2 R4 s. i - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;: I; [; V& p# I/ E7 S5 u* Y; O) h' D
- NVIC_Init(&NVIC_InitStructure);" \8 G. E/ N2 C
" \8 c5 O& q# P8 M- P+ {- /* CAN configuration ********************************************************/
* u! W Y3 a0 r# Y - /* Enable CAN clock */
! }% |( C3 x, l( V - RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE); l6 \$ \1 }# v& q
$ {* I1 ^5 M* B# a8 F- /* CAN register init */
* W7 \8 q7 |( y. N6 {% y0 ~ - CAN_DeInit(CAN);
; R% w* F% }8 R2 w6 W - CAN_StructInit(&CAN_InitStructure);$ D' g9 u) L- h) H; i1 P6 m$ T; q
- ' D2 H- _1 H+ I8 o! f/ n8 j
- /* CAN cell init */6 W i& v. ^( d2 A, s
- CAN_InitStructure.CAN_TTCM = DISABLE;
" t% Y6 c! H9 |7 H1 G2 a K; c - CAN_InitStructure.CAN_ABOM = DISABLE;
- y8 ^; k$ w p1 V) q - CAN_InitStructure.CAN_AWUM = DISABLE;- O4 P/ ~6 C5 e& Y d/ a0 `6 V. |
- CAN_InitStructure.CAN_NART = DISABLE;- G; d' k! G9 s" K- |
- CAN_InitStructure.CAN_RFLM = DISABLE;
; s% l5 Y3 e" _3 e* O# f - CAN_InitStructure.CAN_TXFP = DISABLE;1 S6 @/ T3 F$ U, g4 G
- CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;4 ^- v* _/ s# e2 C# H" t
- //CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack;
. r# Y6 d% i% s& ?$ R3 ?1 G - CAN_InitStructure.CAN_SJW = CAN_SJW_1tq;
3 u, \; T8 a& W" W) C5 Y! A
; g1 o5 F. I. A! U a4 p- //200k的配置
; Y1 \# k$ c8 \0 i - //48M/12/(CAN_SJW_1tq + CAN_BS1_4tq+CAN_BS2_5tq) == 200k
: E2 q Q' {; ^; l$ q - /* CAN Baudrate = 1MBps (CAN clocked at 36 MHz) */
0 C% _8 g E/ F: E# k3 r" P - CAN_InitStructure.CAN_BS1 = CAN_BS1_4tq;
6 N5 n! r; L" O" r1 ]8 i Y' q! [ - CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq;/ u# W6 F3 d+ O0 l/ h6 r
- CAN_InitStructure.CAN_Prescaler = 12;
3 p* t( x0 _$ G2 S* @ - CAN_Init(CAN, &CAN_InitStructure);
( H) h W: |* Y" Q* N; R - 6 R/ E2 a9 N" _' `4 W' [# P
- /* CAN filter init */+ ?1 S' V$ q9 j( ?3 W
- CAN_FilterInitStructure.CAN_FilterNumber = 1;
. H0 y1 U8 K1 q" ^4 H5 r2 n& } - CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
0 k1 J7 b9 d$ {% X6 b$ B - CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;
9 x' Y& X; ` P w- \) {" [- |, V - CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
/ w5 ?9 N! H' G* _: c* ~ - CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; K# H" s( G! G4 @+ L$ g1 a+ D) S
- CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;' r4 @1 c2 P6 Q1 D; `3 F
- CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
; O8 o, E* J0 C! T" r) ?) Z- I9 \+ W - CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
. Z: \' A. D) I: M X3 k1 e" L: |2 B - CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;- W0 R7 M3 L7 j& n
- CAN_FilterInit(&CAN_FilterInitStructure);% H6 V( ^) b) Y \
- /* Transmit Structure preparation */ p* c( N' q& P) `4 t# _# R; `! m
- $ b" n9 D- E0 c
- /* Enable FIFO 0 message pending Interrupt */
+ h3 q0 L; l; ^# n1 E$ p% ~- g - CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);
0 w( l: p9 W# _1 _+ b/ y - }. q5 Y" H/ z- }/ y! K# G8 u
+ z. [2 Q' n. B% _! I8 _
9 O4 M2 H v" c" O* {
复制代码 ) I2 ^1 p8 ?" g0 u* k' i
- T& f$ c) g, y- j |