你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32 CAN总线调试的一点心得总结

[复制链接]
aimejia 发布时间:2018-6-1 13:47
本帖最后由 aimejia 于 2018-6-1 13:49 编辑 7 e' k# ]) A/ N& d$ o) T" d
  ~- i5 C2 s& @0 Y( u; [8 i
一. 开发平台与工具:* B" e3 B+ G5 E2 ]9 P& E
- o' p" T3 d7 H" H7 }! ]6 {' J
1. 平台: STM32F103C8T6  48PIN工控板和自己设计的STM32开发板! }7 k2 T3 q- h/ {! Z  i
: b9 p2 n! I1 m- p6 K. e7 N$ G
2. 软件: MDK5 UVision V5.14.0.0  e, \8 j7 p7 W! r- K0 s' G7 h

; v" _$ V& V0 _3. PACK: STM32F1xx_DFP——1.0.5(2014-03-14)
, R( ]! d- z) Y  C( L8 }6 g* }( o8 ?' I9 S$ Y; T
4. 其它:USB转串口,ST-Link下载器,
5 Y: n+ A- v+ Y4 l
5 \8 o; _. A& M' _0 o7 fUSB-CAN Adapter用于直接监视CAN口发出的数据,上位机有两个,一个是EmbededConfig for USB2CAN 配置串口、串口波特率、CAN速率等,另一个是EmbededDebug V2.0监视CAN口数据;使用顺序是先配置后查看CAN数据。
7 }- h; \! U6 ~, _2 H) g" e2 J. ~& u6 v- ~5 ]
二. CAN总线的介绍简略:* [3 C3 ~. Y9 q. w( N6 E0 ^9 Y
, D0 z( |" `  d
bxCAN 是基本扩展 CAN (Basic Extended CAN) 的缩写,它支持 CAN 协议 2.0A 和 2.0B 。它的设计目标是,以最小的 CPU 负荷来高效处理大量收到的报文。它也支持报文发送的优先级要求(优先级特性可软件配置)。  l% W" [( ~" ^) G$ G
6 H! ^) e- N9 u3 u$ A2 n4 e0 U$ J
对于安全紧要的应用,bxCAN 提供所有支持时间触发通信模式所需的硬件功能。% K. D/ v# K: x

8 ^# w/ y$ ~, i6 s5 }5 R. k- G% M3 d主要特点# o7 W$ Q$ l+ v/ \; s; S# Y
· 支持 CAN 协议 2.0A 和 2.0B 主动模式6 V' a2 F) @; @1 w2 G" D' d
· 波特率最高可达 1 兆位 / 秒
# {$ l/ O6 |! k' x4 y& k· 支持时间触发通信功能
- f3 O8 I( o8 O' B2 j; [* H/ x5 Z* P) F8 v1 t. W1 ]$ J
发送; M6 @! \' u$ f6 N
· 3 个发送邮箱, c* H+ \8 C% e9 u# D: S' K- Y- G
· 发送报文的优先级特性可软件配置
( d5 S' U  u2 i) X& n· 记录发送 SOF 时刻的时间戳" g: b1 N5 B: S' v3 r( R) j5 z

/ Y6 b" s! ^6 {9 z0 i接收7 ]" {+ Z9 @6 W% [
· 3 级深度的2个接收 FIFO; U) R5 _& T! [. ?
· 14 个位宽可变的过滤器组 - 由整个 CAN 共享
/ K5 J& o( m6 T# Q4 I( r; M. ]· 标识符列表
6 F0 n1 i+ O( h! c1 P$ P· FIFO 溢出处理方式可配置
9 Q. X8 F: u6 ]- b! K3 ]· 记录接收 SOF 时刻的时间戳
7 {6 m) u% W  b7 V3 D  P1 Y% h* K  d" B: V
可支持时间触发通信模式- u  v/ _% g% ~( W# S. N
· 禁止自动重传模式$ g! |. c$ H9 j: l( ]9 t6 G
· 16 位自由运行定时器; h5 h7 q8 D! c
· 定时器分辨率可配置
9 g9 n5 [: J# b1 `+ ?/ @· 可在最后 2 个数据字节发送时间戳/ W7 h: U6 V; G, U; A0 o# m
9 Q! B/ y, U: E  k+ t. r5 y
管理- O' x- _3 K+ ?4 W
· 中断可屏蔽# |! `/ @# D! j- N/ Z8 L0 M4 c
· 邮箱占用单独 1 块地址空间,便于提高软件效率
1 I( \) Z5 _  K* m. ]
8 _+ @5 ~; X/ q9 e% Q4 f+ P; q更多STM32 CAN总线介绍详见:STM32中文参考手册_V10.pdf 或 STM32F10XXX-RM0008 Reference Manual 英文版
0 j2 m1 Q! f7 I; @; _5 q% y  I+ [& R
三. 遇到的问题分析与解决:; Y7 o0 J1 Q) Z& U  J9 k  V/ Q

% a6 A5 t7 E! R& _8 |; S手上有两块STM32的板子,一个是网上买的MINI STM32工控板,另一个是自己公司设计的板子。二者有所不同,大致有两点,第一是串口,工控板用的是USART1 且用的是GPIO PA9(TX)和PA10(RX),自设板用的是USART2 且用的是GPIO PA2(TX)和PA3(RX);第二是CAN口管脚不同,工控板用的是复用功能映射到PB8(RX)和PB9(TX),而自设板用的是PA11(RX)和PA12(TX)。下图所示,两块板子部分原理图:
. D4 ?& \" i; m
# r. ~4 g% W3 Y  [工控板; X  O7 Z* L# B3 U& u5 k
$ H* b7 R$ g& m. M4 P' L3 ^
1.jpg

* `2 A, f6 V/ _% V) S% T, ]自设板
8 ^6 e+ z( }: f1 o* \! q! _' f$ L/ }
2.jpg

( E  \/ m" z8 Z3 c8 R; H$ {现在我是在工控板测试代码基础上,用到自设板上,实现PC端串口与STM32 CAN双向通信,要做的是将USART和CAN口的GPIO配置对应到自设板上。9 p3 _" {8 P" F2 t& y1 s5 p
0 I6 F* L/ S/ s( X- W
首先,串口GPIO配置:4 B% t* s  l: A. `, p6 C8 u

+ e* G2 {' d" R2 L3 E, E工控板
0 P$ E8 t" D  B! y3 i
  1. [objc] view plain copy
    / J6 p6 I: X8 Q
  2. void USART1_Config(void)  
    3 j: M  w. V% w  \
  3. {  
    0 h0 J* U. s  r' P
  4.     GPIO_InitTypeDef GPIO_InitStructure;  
    0 h* W- e/ K6 ]) x
  5.     USART_InitTypeDef USART_InitStructure;  
    1 J# D$ X6 |9 k6 Y
  6.   * T, K. X! K$ Z8 h
  7.     /* config USART1 clock */  2 {  {6 C' d, i9 q  w7 q: R3 D- Y
  8.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);  / p- d, _/ Y8 g
  9.       ' s& Z0 H/ I( B5 l0 ]7 [
  10.     /* USART1 GPIO config */  . O! D5 e0 h* G  v' q. B
  11.    /* Configure USART1 Tx (PA.09) as alternate function push-pull */  ; B% Q: z6 X+ T% F: O0 [7 e" L3 y
  12.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  & T( d; _' d" h# e1 |
  13.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
    $ s  O& j7 U& ?" q  x
  14.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  8 h( `& `+ I! Z1 p3 q# K+ R. a# `
  15.   GPIO_Init(GPIOA, &GPIO_InitStructure);      8 P3 s' x3 r. L5 }5 O3 v2 d1 P
  16.   /* Configure USART1 Rx (PA.10) as input floating */  
    5 y5 i7 e0 J; d9 _! v
  17.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  ; J* B2 `: J  ?1 ]  O' A
  18.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  " A! S8 q" J7 R1 Y$ k
  19.   GPIO_Init(GPIOA, &GPIO_InitStructure);  
    8 J" j( C; Q& K8 Q
  20.         : L% h& [# t2 Q8 f6 ?# ^1 v) k
  21.     /* USART1 mode config */    y6 h6 @  O; r, N& Y% J" S9 R: E5 e
  22.     USART_InitStructure.USART_BaudRate = 115200;  . v/ ^; I( q; p
  23.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
    + e: S$ I# F7 }) X$ p
  24.     USART_InitStructure.USART_StopBits = USART_StopBits_1;  
    % H- [9 `+ a+ o: E4 O; u1 y
  25.     USART_InitStructure.USART_Parity = USART_Parity_No ;  
    ! _# x! V/ c, K' B
  26.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
    / U) X, f( i* \, j4 \
  27.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  8 L) y8 j1 X* ~/ N$ u. @6 u
  28.     USART_Init(USART1, &USART_InitStructure);   
    - Z' f7 p4 a3 n" z! s
  29.   USART_Cmd(USART1, ENABLE);  0 t# O# u- B# {' `% n4 f
  30.       
    ; ?% ~8 d% E  y
  31.     /* Enable the EVAL_COM1 Transmit interrupt: this interrupt is generated when the  $ H" i9 x; B' d+ H. S/ G
  32.      EVAL_COM1 transmit data register is empty */   
    % Y# G+ O. r8 E; S$ l
  33.   //USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  
    . k" x5 Y" |; r
  34.   
    + s0 o& h+ O7 l6 C
  35.   /* Enable the EVAL_COM1 Receive interrupt: this interrupt is generated when the  , {3 S# }  ]. k8 J0 D8 f
  36.      EVAL_COM1 receive data register is not empty */  ' O/ o4 W: A1 o9 p- t+ d# }  j' Q
  37.   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  : H5 [. v) F. X8 o& Z- Q0 S( m  b; Y) G
  38. }  
    , r% j0 |5 O- V, j+ D: @: A. l, b
  39.   ) z+ G6 Y1 C) C+ c; B6 H$ L2 f# F4 q
  40. /***************USART1 ÅäÖÃÖжϷ½Ê½·¢ËͽÓÊÕÊý¾Ý******************************/  
    , _" e; v2 r1 i
  41. void USART1_NVIC_Configuration(void)  
    ( B% v# c) ^  S8 W4 s
  42. {  5 g6 \# l7 ^; z& ~/ n3 l
  43.   NVIC_InitTypeDef NVIC_InitStructure;  
    4 c, j2 h* v# h# J& K/ B
  44.   / R/ C! ~. @- J( u" E6 J- R
  45.   /* Enable the USARTx Interrupt */  ' a& X: H, j# X* n8 g
  46.   NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;  * |. H, z0 a  k% Q- S1 y
  47.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  ' p5 I$ F- ^6 e8 C9 y
  48.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  * `! j- c# @; X# h
  49.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  6 E- t$ j# L0 [* V2 K; h
  50.   NVIC_Init(&NVIC_InitStructure);  - \0 L9 h' U) @0 @2 \9 Q; q
  51. }  ' W" x* A* a9 g: h6 Q) C# ?! v
  52.   
    ' I9 D0 Y1 b* `1 u4 y4 x" A* T' ~
  53. /****************USART1 ÖжϺ¯Êý***************************/  - P, j3 a. h& k$ H- E+ ^, O& d, Q; J- e
  54. void USART1_IRQHandler(void)    T: Z( |8 B* {5 c; [# @* U
  55. {  
    # w& I& B+ D8 k: Z
  56.     if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  - t" s5 L" ?4 S- r
  57.     {  : c  N4 ^1 C% j# Z$ k
  58.         RxBuffer[RxCounter++] = (USART_ReceiveData(USART1));  
    / h+ S  z, {  A) [
  59.     }  9 q8 e- r7 Z; O
  60. }  
复制代码
USART1_Config()用于USART1的GPIO配置,配置到) z; ]* `5 T9 A1 J9 ~6 k
*          | PA9  - USART1(Tx)      |
8 a# [: \$ F4 z1 b9 } *          | PA10 - USART1(Rx)      |
) L1 _2 c* ^; h# ]" Q *           ------------------------
- n0 _2 o2 I- I6 f% k& L3 Y1 |7 B+ pUSART1_NVIC_Configuration() 用于USART1设置中断方式接受发送数据  ]# X7 f5 |; s, N

4 U, g+ ]5 S0 e% wUSART1_IRQHandler()用于USART1中断接受函数) F! j1 i+ q- H0 e2 I) y0 b

: U: B# X' j5 R+ u自设板5 I- [* j9 G- L  j) b$ p
  1. [objc] view plain copy% `( A+ |, |3 r4 ?
  2. void USART2_Config(void)  + l7 v9 u5 U, c& ?9 L* G9 d4 z
  3. {  
    6 ~. |5 s& O. q7 o
  4.     GPIO_InitTypeDef GPIO_InitStructure;  
    3 {3 I) k- c6 g7 }9 B' V. a
  5.     USART_InitTypeDef USART_InitStructure;  . E4 D6 u6 s" C1 H. p
  6.   8 [4 b$ _8 r: V; R
  7.     /* config USART2 clock */  + X& l3 h( Z/ |" E
  8.     //RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);  2 W, f, O  s6 a4 Y
  9.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);  
    ' ~* W8 O/ g% G, m' G. P1 v/ Y' E
  10.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
    " W% f$ W- @% v3 p
  11.       
    ! L/ V; j0 x( z$ p$ M( g2 A4 Z
  12.     /* USART2 GPIO config */  6 n: S0 p1 T  v/ S$ f
  13.    /* Configure USART2 Tx (PA.02) as alternate function push-pull */  
    * I; U$ K1 D- v: W
  14.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;    n- v- L5 ~1 @" o! z) G. x
  15.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
    . w. X; A& l$ B
  16.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  1 S3 I/ G- B- I% t( |( O( Z8 |" |. o
  17.   GPIO_Init(GPIOA, &GPIO_InitStructure);      & z5 p6 ~& m$ q( M0 f$ T+ p
  18.   /* Configure USART2 Rx (PA.03) as input floating */  
    ) [5 X% ?5 E0 L' f
  19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;  
    ' U3 x! K- w& Y/ O
  20.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  . L* Y8 {0 ?/ \8 d
  21.   GPIO_Init(GPIOA, &GPIO_InitStructure);  2 K- j) x/ I9 P
  22.         
    , W& q( J* ~$ Q& t) u% k
  23.     /* USART2 mode config */  
    ! P% D( G. q' P4 E: k
  24.     USART_InitStructure.USART_BaudRate = 115200;  
    / j% B) g# |; w* a  K, U" a
  25.     USART_InitStructure.USART_WordLength = USART_WordLength_8b;  
    3 R& J* d$ G# X2 o: I* F
  26.     USART_InitStructure.USART_StopBits = USART_StopBits_1;  4 G/ X& Y( N& ?/ g/ i
  27.     USART_InitStructure.USART_Parity = USART_Parity_No ;  
    & R# Y8 e7 x7 g/ e1 ?
  28.     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
    2 S2 R* s8 N# l& o/ f; v. U3 N8 d
  29.     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  " i' e/ p5 s4 v/ E8 \. S3 U
  30.     USART_Init(USART2, &USART_InitStructure);  
    : r7 ]: e: E6 |" Z8 a  i& O, z1 i" l' q
  31.     USART_Cmd(USART2, ENABLE);  
    / U5 x( p, \# o3 ~/ B0 F
  32.       
    1 X* x# f$ M3 s0 o  E  H
  33.     /* Enable the EVAL_COM1 Transmit interrupt: this interrupt is generated when the  
    ' e1 S8 x9 M" k
  34.      EVAL_COM1 transmit data register is empty */    + P1 [- ~( ^5 w8 t4 j9 G" Q6 _+ \
  35.   //USART_ITConfig(USART1, USART_IT_TXE, ENABLE);  
    / n( [/ T5 D6 B* q; `0 [
  36.   # J5 f. K, l  F/ H2 Y5 B) h3 _
  37.   /* Enable the EVAL_COM1 Receive interrupt: this interrupt is generated when the  6 ~) n% g, b! D9 y* R) i5 N
  38.      EVAL_COM1 receive data register is not empty */  5 v8 U: E" q+ ]; F( ~
  39.   //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  ! ?, N, r4 L& z/ f. i
  40.     USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  
    4 s, F- K8 W; u4 H) T8 s5 `
  41. }  
    6 Y- e4 w+ b) V( E9 P' v0 v
  42.   
    % B- V! T+ z# h+ v+ f- h
  43.   
    1 l( q# R, q! {4 B. R
  44. /***************USART2 ÅäÖÃÖжϷ½Ê½·¢ËͽÓÊÕÊý¾Ý******************************/  
    . S, s+ @6 Z. S9 p1 g; u# n
  45. void USART2_NVIC_Configuration(void)  * R1 s4 b" D' U% V; m
  46. {  
    : m, E2 ?' p1 v" |. K5 n- |
  47.   NVIC_InitTypeDef NVIC_InitStructure;  
    - K* O3 d" C0 S6 c6 ~
  48.   1 A" f2 G% }7 e9 O' ?; Z
  49.   /* Enable the USARTx Interrupt */  
    9 E. g7 d* L4 G; r
  50.   NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;  2 l2 e$ M  o3 Q
  51.   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  
    % D. D6 ?6 X0 a
  52.   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;  - n: Y6 i/ x2 K
  53.   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
    2 m* P* T6 l6 K( [& ^/ F
  54.   NVIC_Init(&NVIC_InitStructure);  ( M- B/ U7 |4 K; k% M
  55. }  7 z8 l( G" [5 X" ?
  56.   4 W9 t" a; u) g/ w0 A) N/ F6 [7 ]. B
  57. /****************USART2 ÖжϺ¯Êý***************************/  % y" k& Q, c  ~
  58. void USART2_IRQHandler(void)    J8 q; i, \+ a; t
  59. {  
    9 [$ }0 i  W6 H; `
  60.     if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  " J$ i  |+ @+ r
  61.     {  % e. f1 u8 X$ I5 O/ l. ^7 {0 r% X
  62.         RxBuffer[RxCounter++] = (USART_ReceiveData(USART2));  $ y3 i$ l1 @, r9 ?
  63.     }  
    6 H  y) I2 `% o/ U  h& V
  64. }  
复制代码
USART2_Config()用于USART2的GPIO配置,配置到! T: r+ ?- m: |) `( A! z
*          | PA2  - USART2(Tx)      |
. l; m5 D" F1 _: c: n *          | PA3 - USART2(Rx)      |- w9 @# i( L% b) M% A4 [# v
*           ------------------------/ a, s3 e9 w2 p: J0 p: }* H

) }, n. Q$ Y' l$ a2 ?/ nUSART2_NVIC_Configuration() 用于USART2设置中断方式接受发送数据
0 T- }& s- e4 L4 L3 Z- F* R
+ g% q3 H- Q, j7 X& TUSART2_IRQHandler()用于USART2中断接受函数
# U4 w9 \) z$ l8 {& o' H! p; z
6 F4 T- l$ o) d9 A然后,配置CAN口GPIO+ U" w  u  `) ?4 F! u
* B; T1 T; U) n9 i6 \
工控板
) j1 C3 `. B1 U; J% _! k
  1. [objc] view plain copy
    2 Q. |$ Y3 j. H5 x% t: X
  2. /*CAN GPIO ºÍʱÖÓÅäÖà */  ) L( e; F( ]. p
  3. void CAN_GPIO_Config(void)  
    8 n& c( s, C, a/ ^
  4. {  
      f: `% U' Z- Z5 R: x( [( e
  5.   GPIO_InitTypeDef GPIO_InitStructure;   * ]. ^& \7 ?0 M8 x
  6.   /* ¸´Óù¦ÄܺÍGPIOB¶Ë¿ÚʱÖÓʹÄÜ*/     5 S1 Z, x8 t( w. y' x5 r% I3 U. B
  7.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB, ENABLE);                                                                          * n" a) x; C5 A3 Y; D& d& o+ n
  8.   
    / I# ?2 M3 K) ?1 a* q* L8 G
  9.   /* CAN1 Ä£¿éʱÖÓʹÄÜ */  3 o5 n2 ~* l* c# @  C% a
  10.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);   - p9 J% b1 L9 N, u
  11.   / J) U4 d6 R+ r, h# v7 K
  12.   /* Configure CAN pin: RX */    // PB8    o9 a4 v5 Z5 G
  13.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;  * Q. \& \2 j5 ^
  14.   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
    9 y0 [# {( A4 U" Q$ G5 m0 h
  15.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  // ÉÏÀ­ÊäÈë  ( b. O- U9 y: p& G
  16.   GPIO_Init(GPIOB, &GPIO_InitStructure);  
    5 ?+ s# `; M# t6 m( ]8 j/ x
  17.     " R1 ~" k" X1 k$ h/ A0 Z
  18.   /* Configure CAN pin: TX */   // PB9  
    / W# W( K1 z* \. V* h
  19.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;  . o9 @; W: ]1 k8 N$ G+ F3 i
  20.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // ¸´ÓÃÍÆÍìÊä³ö  $ z& c+ R! z* E6 x
  21.   GPIO_Init(GPIOB, &GPIO_InitStructure);  
    & m9 b; c0 u( P2 U+ \, Y6 b
  22.    
    6 G# t+ Y# t, |
  23.     //#define GPIO_Remap_CAN    GPIO_Remap1_CAN1 ±¾ÊµÑéûÓÐÓõ½ÖØÓ³ÉäI/O  
    $ w6 s6 h& k3 Z. w3 w! _. ~
  24.   GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);  0 D  r# X' f8 j& i- s8 @" v! o) j& B
  25.   
      V! j* T' r; Z
  26.    
    7 a$ B, c0 J8 j1 A% b( [3 N; y
  27. }  
复制代码
自设板
8 Z/ n" E, I$ i4 j- a: g
  1. [objc] view plain copy1 B# A0 Y! F) Z( f& Z& L. y6 w
  2. void CAN_GPIOA_Config(void)   
    1 E/ }% t* ^( e# p" S. _
  3. {   
    : X0 ~4 {' w5 _5 H- z7 _
  4. GPIO_InitTypeDef GPIO_InitStructure;       * R7 n9 f8 P2 X* _
  5. /* CAN Periph clock enable */   
    + j0 q! Y( e' F" u5 a8 X
  6.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);   
    + G4 j% I. f& ^
  7. // RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);   
    9 o' z# W4 n5 y. I7 x
  8.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);    % d5 g4 p0 i8 e1 K9 ^9 U; J
  9.     3 U* q) N2 n, U6 K8 ?
  10.   /* Configure CAN pin: TX */   
      N. r% b0 c6 {0 Y
  11.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;    + @( U& _! ?! v/ x" O7 ^; F
  12.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   
    : b- F- t5 g; O$ d
  13.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;   
      b6 \; @# d1 e0 G$ |7 x
  14.   GPIO_Init(GPIOA, &GPIO_InitStructure);       , r* X* ]6 @* D) h: Q3 g
  15. /* Configure CAN pin: RX */   
    1 f6 k2 ^2 _& n$ [. }+ L
  16.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;  
    ; O/ }5 \. `' R4 x- @) V/ l: D+ \
  17.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;     : O& j2 v2 j7 u
  18.   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;     
    ( n9 C5 _8 g- C) Y9 f! a
  19.   GPIO_Init(GPIOA, &GPIO_InitStructure);       " b- j- O, }9 }( l9 |& e
  20.   //GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE);    + a& W$ p& n' C* k; U
  21. }   
复制代码
/******************************************************************************************/! s" z, C! u9 E* B* \- i
就是这里!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
; m0 k0 L! T# y& O- p/ _出现几个小问题,但是却是致命的问题!!!!!!!!!!!!!!!!!!!6 c1 |- e" u9 I% q' C  ^) P

5 O# \4 ^& ^5 r1 ]/******************************************************************************************/+ q' y1 R9 ~+ r4 @  w* H
: e  ~' h/ b$ u% g/ @) a
第一配置GPIO_Speed:
" f5 B0 R5 \5 Q( ?* ?4 L! l- N/ r0 Q" ?6 L
[objc] view plain copy
6 Q3 k, G" N* q) \1 b$ w1 u4 e* |GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  //配置GPIO_Speed为50MHz  " l# z2 @% W) a, l6 @
如果配置GPIO时,省略这一步,会导致CAN口发送不出数据,工控板的配置是放在LED 的GPIO配置中,一开始忽略了这一点,之后用排除法试出来的;
3 a, A8 t+ V/ A+ u; ?. G+ s. }: N
  _% o2 F7 M+ W/ \第二配置复用功能和映射与否:9 f  B, M9 H* ?3 N
  1. [objc] view plain copy
    * A  u  J, v9 R5 d5 H* p& M
  2. // RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //复用功能时钟使能  
复制代码
  1. [objc] view plain copy& k% n8 [8 ?/ [
  2. //GPIO_PinRemapConfig(GPIO_Remap1_CAN1 , ENABLE); //重映射I/O CAN使能
复制代码
  1. [objc] view plain copy
复制代码
  1. [objc] view plain copy
复制代码
  1. [objc] view plain copy
复制代码
上面两个被注释掉了,是由于:  
( z* I0 |0 v" V  U6 e1 V" B- Y用PA11和PA12 用的是CAN的默认端口,而用PB8和PB9是用CAN的复用功能重映射端口。) T+ L; D/ d  n. v  y
9 K, O! T* `% R% x+ n; ~5 c. R+ y$ y( g
  1. [objc] view plain copy
    . S# J$ I( T6 O. A1 u" i
  2.   
复制代码
1 e1 K& T2 j6 m( S/ I
3.jpg

; [8 \- f! F  L3 J具体:4 d. A( s7 G! Q* Q8 b( F$ g
-------------------------------------------------------------------------
0 _/ z# i( N4 S# Q, T7 E) V- y  {; O4 X
默认模式
) b5 @) @) b' W* Y' c$ `9 y
1 k4 r: C* |7 M* |2 z   /* Configure CAN pin: RX */
5 V9 A8 r) a  b
" |+ e) O& z+ u; }/ ]GPIO" {5 b# N! ?7 Q4 \0 x# f) _

+ }1 Z: ^3 O3 K$ l9 I& m_InitStructure.GPIO_Pin = GPIO_Pin_11;6 J; D1 R8 u4 g4 W" A# w4 Y

( ~- M$ M3 V; W   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;5 l5 j3 J* `, f7 U8 h. c9 B
: v( {2 b. ]" S+ H
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;1 R' g7 S# Q& I" l: M
1 @8 `& v( K& m& h) B0 R
   GPIO_Init(GPIOA, &GPIO_InitStructure);6 j6 M& B! O5 R/ W( @+ O

* f/ e2 @4 D4 |2 h   /* Configure CAN pin: TX */( U$ l. o$ S; B/ P
8 v5 x, y' `8 ^  ~5 w4 ~8 o6 P
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;. u4 A) K" d4 x

" c5 v/ R& L. n; X3 O   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/ _$ A4 P1 L! ?0 t
* |9 ?  q; o; ]. T5 ]6 t$ g' \
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
9 E1 J* \# T. ?/ p8 h1 d9 U3 q: o1 K  S, Z: I9 l
   GPIO_Init(GPIOA, &GPIO_InitStructure);
0 A. S; r( p2 I------------------------------------------------------------------------
4 ^+ X, O! X" n/ S' V+ m% i8 u# r5 B9 e. F9 }3 W$ T
重定义地址1模式* h" I0 |9 {0 K) @/ o/ R
! e4 D+ _" ^- k. [0 Q/ y
/* Configure CAN pin: RX */
# D2 z  H* j; w4 |7 T: T6 i7 o" q9 s9 m. X9 d) i
   //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;# A. W2 E/ }, Q" u1 n3 t

) D2 j, q7 O7 g" u* {- F   //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- G8 W- z+ w3 i& S5 n3 O9 E, p& i
# k% q9 ~3 W! w% V6 y   //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;8 l; {6 n* F+ J4 v/ f8 I" c8 e

; Z: ]& f# b) l- [3 Y2 Q5 A7 A   //GPIO_Init(GPIOB, &GPIO_InitStructure);
( M- `  U0 ^2 R7 v* A4 j
" ]$ G/ j1 b6 Z/ m) e8 A   /* Configure CAN pin: TX */  
- u1 Q6 n! _, S; x6 \
; K7 u: K  |1 u# F" w   //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;; D5 D( j0 u( O# z

7 `" u. Y; F' d; Q) [5 T) E# N   //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;7 v9 v, i0 c, u

7 P2 y; |/ c( }9 O9 W   //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
( N; F  m% r8 c. d+ c6 V" F& }+ U) C  b# {  x8 t# X, y' p: `
   //GPIO_Init(GPIOB, &GPIO_InitStructure);
4 s% I8 \& E; S+ [, [2 T
- d  c1 `) \# g& q   /* Configure CAN Remap   重影射 */
" X, j; n7 |+ C4 Q( x
% B- U! _1 A# n4 x" f* z* \   //GPIO_PinRemapConfig(GPIO_Remap1_CAN, ENABLE);1 j! R- ^4 e4 A2 I

2 E: v0 N3 ~( q5 d-------------------------------------------------------------------------  
$ E& F3 E6 `& }( w/ E; i. M. T, v
重定义地址2模式6 V$ c" Y/ s5 Y3 P' l

5 `4 t* g* `6 k' C( l0 U* j+ K7 F9 F   /* Configure CAN pin: RX */3 m' C- O( U7 Y4 ~; K

( u+ X+ ?% j  L" M" s5 q$ u; R   //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
( {" Y4 ], o8 t
7 h. f% m/ m* }* B/ I   //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  ]5 a! H5 n, p( y1 c; F
: k% R; G; E7 Q
   //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;/ u7 f" e5 U, y/ o0 W1 C4 r

! x5 W, H/ m9 s( G- _   //GPIO_Init(GPIOD, &GPIO_InitStructure);/ V: Q# C/ Y* ]4 |
+ f6 p( J2 V# L. l' Z" s4 W
: h) g  z" Y" n" e5 g. o: N8 |# h
   /* Configure CAN pin: TX */, }+ l( g6 Q, u3 q! `- O! t
% l9 d* `6 P7 X, M1 C/ P
   //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
) I8 n! k8 p4 G5 K- Y4 y
8 }, r& I4 N6 n; p6 h. K$ Y, ~   //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
! B3 [- `1 _9 N$ _" x6 u, E( o* [; H3 p0 S8 U' O* J7 U) h! ^% g
   //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
4 p2 ]0 f& l/ q+ ^, j3 j
) c/ P+ G( d2 E9 ~4 G   //GPIO_Init(GPIOD, &GPIO_InitStructure);
6 f0 V  v, @0 @  [! A9 Y' Q5 V- J4 ~' V' T* Z, f) h

. F, |+ z+ L2 K) n   /* Configure CAN Remap   重影射 */
+ w; \% {1 c* M8 d! C# }  }* p% w  X4 P. R9 c
   //GPIO_PinRemapConfig(GPIO_Remap2_CAN, ENABLE);
& _* o/ _7 \8 q! i4 f! g) C, G
5 p8 M5 f7 a$ [-------------------------------------------------------------------------, ~  m  o. Q% |3 H" l
( Y2 }3 |- ^* a! Q' w( Y2 j  Z% g' l
设置完 CAN 的引脚之后还需要打开 CAN 的时钟:; q/ N# D' T- p- c5 k4 ~% i0 C4 c6 c
+ {9 v3 C% z( D3 U7 C  I
/* CAN Periph clock enable */
  T% @$ s" D+ E! |) }& D4 q
3 r+ B9 P2 m9 M  h4 Z, V. ~% B2 G   RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);% T. ?' Z$ w7 _& M3 A9 z
6 w" L* L' H) c7 X2 M; q
第三CAN硬件部分:6 k8 U' Z( U- }# [
& M: a4 a, b4 W
一开始对CAN硬件部分没有过多的了解,后面经过一系列的试验,发现:
$ W% A. u: o4 ~4 |8 N7 g+ \3 ?9 y* l' a( `4 h4 L
1. 如果STM32 CAN TX和RX没有和CAN收发器连接的情况下,STM32的CAN TX和RX是没用数据发出的;. H' ]0 b( }  q
$ Y) C) {8 g3 t) m5 b( `9 o+ s! |) `
2. STM32 CAN TX和RX必须要与CAN收发器的TX和RX对应,即TX接TX,RX接RX,否则CAN没有数据发出,说明:之所以说这个问题,不知道你们有没有注意到,我的自设板CAN收发器TX和RX是反接的;5 z9 n3 K# Y) I* ?) e" V  F1 D
8 |* O, |8 y1 c# ]
3. STM32F103C8T6-LQFP48 的CAN口和USB口复用,即用CAN口是需要将USB口断开,防止有所影响;
0 _+ t/ X) ^3 S* |7 C3 p% ^& r7 @0 s' H4 f  v3 B
4. 是我本身设备问题,我的自设板用的12V电源是我自己焊接的,不太可靠,电源12V时有时无的,所以最好烧写程序的时候点亮一个LED灯,可以显示板子的工作状态;
2 j) V* \0 q6 f
# B: ^" G/ w( f& b5. 工控板上CAN收发器是用TJA1050 是5V供电的,自设板用SN65HVD234 3.3-V CAN Bus Transceivers,之前有所顾虑,怕CAN收发器不一样会导致其它后果,之后发现没有问题。
$ t( r. B1 H6 T3 g+ u4 J. a# c( f6 e7 u2 D3 V0 G

/ U/ z; J6 D! G9 ^9 r6 F7 w
2 t7 E8 J2 A9 A# j; ^% f# v以上为本人的一点心得,走了很多弯路。。。记录点滴,以此自励。/ [+ N5 q+ X7 y& ?( w+ W# F

3 _) T" H+ D1 M8 k
) L) D( M! V' i  W5 {2 @6 ]4 u$ ~; ~' h* i, Q: Q: V
0 w3 J- Z* Z' U8 Y9 S
9 Y) k' p* I: e0 R4 l- D- \
转载自sunnyhyh9 G! V" n3 J* `+ Z1 e

. B' f7 ]$ h3 c3 {$ [
' J% v5 p5 C' J

评分

参与人数 2 ST金币 +3 收起 理由
STMCU + 5
50031185 -2 转载请注明出处

查看全部评分

收藏 评论4 发布时间:2018-6-1 13:47

举报

4个回答
samhong 回答时间:2018-6-2 06:56:45
谢谢分享!
AI++ 回答时间:2018-6-2 10:08:11
转载别人的文章 没有在标题注明 啥意思? 盗文吗?
飞鱼大炮 回答时间:2019-6-17 19:49:25
感谢分享实战例程学习学习
未来,我来 回答时间:2019-6-17 19:57:31
感谢分享实战例程学习学习

所属标签

相似分享

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版