本帖最后由 kevin0129 于 2015-1-11 14:14 编辑 * E6 o. k; |1 } _
- c. k/ ~- _$ q S 最近看到沐紫老师手上有多余的nucleo stm32f072的板,果断以之前的活动价购买了一块,之前研究过stm32f103,当使用072的时候发现它的这个HAL库和标准库差别十分大,于是便研究了一下这个HAL库,之前使用了一点这个cube MX,发现这个配置软件非常好用,相对于103来说,我们不用再来自己动手配置外设了,直接设置几个参数就够了,今天来介绍下cube mx生成一个带I2C和SPI的工程的步骤(之前用103没怎么调通过I2C,一直软件模拟,这次尝试下,发现没有出现I2C bug,应该不是侥幸,毕竟测试了四天四夜.......)
- S# O. s8 E; R1.打开cubemx后选择nucleo f072的板子,这个很好找
2 x$ j$ K5 ^' v# S2.配置外设的引脚
s5 l% Y3 j0 @4 k
6 h, p: \0 f, YI2C就直接选择I2C模式
( T" Q- F! @! Y/ M$ w! d
/ w( p" |. U$ OSPI设备我用的一块显示屏,没必要去读它,我就直接选择了主机只发送的模式,如果要读写的话就不要选择这个了
( h. I; R, v5 L6 j) ^1 t" f3 K
' u5 J; R' O& g4 X+ S Y0 O& U
I2C的引脚更改,我看到板子上的SCL和SDA在PB8和PB9上果断把默认的引脚改成PB8和PB9(这个其实可以不用改的,我只是为了接线方便)
y9 b' H ~$ y+ D7 u
" M7 e' v5 t$ I. O$ j; M7 \+ q+ x6 R
接下来配置几个I/O做显示屏的控制I/O,直接都设置为输出就够了!* y" e) |1 M8 [% @8 K0 S
/ ~% J4 Q. q$ L% B) O' k3 x接下来配置时钟,我自己焊了一个HSE晶振,所以选择了外部晶振,配置系统时钟为48M,还有设置I2C的时钟为系统时钟* M0 Q# a4 g7 c% {% g
2 Q' G1 ?# y4 t
接下来是I2C的配置,设置为标准模式100k速度, 上升沿400ns下降沿100ns,这个地方的设置和f103的I2C配置有点不一样,我没有选择中断和DMA最后修改下I2C的GPIO配置就够了(和配置其他gpio一样)
) Q( S$ K- M; O% w5 M$ P0 M2 L
2 p0 N! C! D7 U+ x6 e: u
SPI的设置更简单只需设置数据长度和速度就够了,同样没有用DMA和中断,只需配置I/O就够了3 P8 b5 t6 J) n0 L+ {+ P
最后去配置一下那几个控制I/O就够了,这样就可以生成工程了% n) y/ w+ l, }4 P2 S
- \$ u' H7 U6 ~: K3 |
生成工程的时候我选择了这个,我不喜欢把所有的代码都放到main.c文件里面,看起来很麻烦,这一项是单独生成对应的外设.c和.h文件,看起来比较舒服& z1 Z7 V7 j; e# v& C5 e
生成工程完毕后,外设都基本设置好了,主要配置下I2C的读写程序和SPI的写程序就够了5 k) g! s# t1 |7 z
- void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
/ _0 T5 E2 E$ {$ F6 [+ ~" T+ X - {
& {( K, u% j9 O6 w- _3 n - uint8_t TxData[2] = {REG_Address,REG_data};; V" e; i# q9 {- V* b, Y
- while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK)
, I: i T! ?. d, |$ R/ n - {
8 G# ~# Y& t& z1 H* ?) H - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
: [' K, i l" y" q& t - {: T9 B3 x* R4 D% J
- Error_Handler();
8 `- f% [5 H4 \- k2 ~7 |( w; L0 o } - }/ Y2 @# p X% R Y
- }
% j* I: ], ^ } - }
复制代码
# a# N5 R4 v/ ~4 o7 U* `* w7 p$ s' c2 p( k# ~% T9 j5 B
这是I2C的写单个字节的程序
8 S7 Z$ O' h/ `6 k) s- uint8_t* Double_ReadI2C(uint8_t REG_Address)
( R! b4 F3 @% \4 S# T - {8 W& ^+ z7 R/ y
-
8 `2 ?5 x, ^$ M* c( u% a* z - while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,®_Address,1,500) != HAL_OK)
, ^; H& t: ?: d7 \2 S, I* | - {9 q5 j7 @$ G0 e; v
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
" | n% X' k/ O8 J2 z2 H - {) I. x1 M3 I/ f' v( H6 G6 F! t ^
- Error_Handler();
( t" F8 w+ N# k% Y- f - }/ d0 b! L w7 i7 W* |* O* ]
- }
/ L2 S9 ]( I1 t+ a - + z& Z% G/ L: h) c5 Z) U1 X
- if(HAL_I2C_Master_Receive(&hi2c1,I2C1_READ_ADDRESS,(uint8_t*)RxBuffer,2,1000) != HAL_OK)
1 R% B$ o& R; W3 {# @; Z9 r - {$ K) a% p5 r' j( X/ J) c, V: c
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
5 j% l& Z- r/ }% e3 L - {- P( X* J! w; J, e0 T5 b
- Error_Handler();0 Y7 d' h, g n1 U4 ^+ p
- }6 Q0 E' O( P4 Y( l, }0 {
- }
0 W8 H3 I) G, j. `6 M: \ - return RxBuffer;
7 c8 T; P+ U2 ~$ m - }
复制代码
6 X) G4 Z w. ^/ Z3 T这是I2C读两个字节的 程序,主要写单个字节的时候需要取地址(®_Address),由于这个HAL_I2C_Master_Transmit()这个函数的输入参数,数据那一项是一个指针,所以如果传单个字节必须取地址,有一个PDF文件介绍了HAL库函数的使用,但是全英文的,可以看看提高自己的英文水平,主要的两个I2C函数都在这里,可以直接调用HAL 的API,用起来非常方便!1 p P8 V! w: X6 N* w
- void LCD_Send_Data(unsigned char Data)$ O) N- X+ W! B
- {5 h# _& x. C+ S- a6 d! N0 o- N' R
- LCD_CS_L();
$ {0 m7 n4 I5 ?, ?/ N - LCD_DC_H();
+ s# t4 B$ ?7 | - HAL_SPI_Transmit(&hspi1,&Data,1,100);
! N& R% G) W1 @; w" W - " C* z( ~( }; l, W5 F
- LCD_CS_H();
% \: I% F0 _1 D% @ - LCD_DC_H(); 1 B1 s7 o7 x7 i3 w. ~1 t2 z
- }
9 A" w& D' \- n3 A" ^) V/ e - void LCD_Send_CMD(unsigned char CommandByte)9 c5 b- T: W' q& r
- {
6 e9 T: b, L7 I% X7 n+ X - LCD_CS_L();1 a6 F, ?7 ^; n9 P) y9 y2 w
- LCD_DC_L();
8 a, J) Y" e3 J. Y4 l4 a; P - HAL_SPI_Transmit(&hspi1,&CommandByte,1,100);
8 u ]/ h* {1 ?$ j7 K/ @# e' g - LCD_CS_H();- i& A2 `; I% |6 b0 w, c
- LCD_DC_H();
% q& s% f5 P: R. z - }
复制代码 * h5 ^0 U& F# o$ T1 I
这是SPI的写函数,一个发命令,一个发数据,也是调用了HAL的API HAL_SPI_Transmit()这个函数,同样注意发一个字节的时候也要去地址, y2 U! I9 ]4 s0 p1 P0 I) X
主要的东西都完成了,只要把对应的LCD驱动和I2C设备的驱动复制过来,然后把读写接口对上,工程就完成了。
" Q- J, S$ o% q e% @$ Q本来自己的程序没有问题,但是调试的时候发现I2C一直卡死,还以为时出现了I2C,郁闷了一段时间,其实是自己没看电路图,造成视觉上的蒙蔽
% }7 J' d; z8 w2 l
8 t. `2 Z' y0 B
有没有人以为这里就是对应的SCL和SDA,我之前一直把SCL和SDA插在这里,结果I2C就一直卡死,表示自己给自己眼睛坑了,结果去查电路图才发现
( Z* n% j! `+ m
0 f6 U4 ^$ w# i) F8 n
SCL和SDA分别是第二排和第三排靠内的那两个,换下接口后I2C就立马工作了,表示自己在这个上面把自己坑了半天........
+ F$ P1 b2 W& I+ _' T' U% z7 c
STM32F0çHALåºç¨æ·æå_é¨å1.pdf
(6.34 MB, 下载次数: 1865)
|
我的IIC也显示为“FF”,原因是每次断电或复位产生的信号干扰被误读。
木有放弃啊,已经出来了,F7现在都支持了1 @- K. M2 d: u% w; x' A
http://www.st.com/web/en/catalog ... _searchtype=keyword
已解决,cube设置错误,把SPI定义成了单发。