本帖最后由 kevin0129 于 2015-1-11 14:14 编辑
, |1 x! c, a# z2 s: e; r J) q( L& q) D2 E) b% K
最近看到沐紫老师手上有多余的nucleo stm32f072的板,果断以之前的活动价购买了一块,之前研究过stm32f103,当使用072的时候发现它的这个HAL库和标准库差别十分大,于是便研究了一下这个HAL库,之前使用了一点这个cube MX,发现这个配置软件非常好用,相对于103来说,我们不用再来自己动手配置外设了,直接设置几个参数就够了,今天来介绍下cube mx生成一个带I2C和SPI的工程的步骤(之前用103没怎么调通过I2C,一直软件模拟,这次尝试下,发现没有出现I2C bug,应该不是侥幸,毕竟测试了四天四夜.......)
) ^- U0 Y3 y, c, p7 k- h1.打开cubemx后选择nucleo f072的板子,这个很好找. t. x8 E) x% C) C: \6 K% U0 m9 v
2.配置外设的引脚
# y- D! H7 X# y5 l
8 g- C! J2 s2 [& r/ M$ ^# O! eI2C就直接选择I2C模式5 j" \) Q2 y7 d3 R0 T$ j
T' L- e% e& N* m; x# K, B( ~' F, N
SPI设备我用的一块显示屏,没必要去读它,我就直接选择了主机只发送的模式,如果要读写的话就不要选择这个了2 ^. H( g2 o4 S; j# O
' b7 i( h1 i3 p ?! LI2C的引脚更改,我看到板子上的SCL和SDA在PB8和PB9上果断把默认的引脚改成PB8和PB9(这个其实可以不用改的,我只是为了接线方便)
) F$ \1 ~9 K$ D! P9 `7 w) [" Y4 \
- O6 o- q+ p: F接下来配置几个I/O做显示屏的控制I/O,直接都设置为输出就够了!7 N" Y8 e. a" F& \/ [* i. S
% E! q. [. \9 X* l& n$ @6 T接下来配置时钟,我自己焊了一个HSE晶振,所以选择了外部晶振,配置系统时钟为48M,还有设置I2C的时钟为系统时钟
; C- B8 X3 ~# ~& D
1 v8 r0 K% P* }5 j7 ]接下来是I2C的配置,设置为标准模式100k速度, 上升沿400ns下降沿100ns,这个地方的设置和f103的I2C配置有点不一样,我没有选择中断和DMA最后修改下I2C的GPIO配置就够了(和配置其他gpio一样)
. ]! {& r4 j, X1 V8 Y1 {5 h
9 _2 Z2 F% l5 I( N$ N) u3 a( hSPI的设置更简单只需设置数据长度和速度就够了,同样没有用DMA和中断,只需配置I/O就够了: l1 F5 N+ t, l2 v+ ?
最后去配置一下那几个控制I/O就够了,这样就可以生成工程了9 c, H; y" Q% Q
! Q+ h- p' B g' | {0 y
生成工程的时候我选择了这个,我不喜欢把所有的代码都放到main.c文件里面,看起来很麻烦,这一项是单独生成对应的外设.c和.h文件,看起来比较舒服
- P) d$ a7 c O: Z生成工程完毕后,外设都基本设置好了,主要配置下I2C的读写程序和SPI的写程序就够了; Q, c" b5 y* h. |3 h' @2 F
- void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)4 g' |6 W. o5 M4 T2 b
- {
. Z8 E1 w o# {. R - uint8_t TxData[2] = {REG_Address,REG_data};
: q+ ?/ Y1 }/ D" Q# Y" H - while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK); q/ _! d8 Z) ?" @5 J% [
- {
0 F3 p/ v# I7 y) q& P5 f# S/ H - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)# u9 L% ]0 t8 v# c
- {
( g+ V& N1 V! Z - Error_Handler();
5 X! D# A$ _ U; X# Z4 I4 q - }
4 z, \- F y+ X - }$ B7 l. ]2 W H C% t0 `+ R
- }
复制代码 ! n% J; O5 W3 M3 @! T
1 q+ l' g8 j2 E" ]# p0 |- H这是I2C的写单个字节的程序
3 ]. [" A5 F* c/ s4 P0 v( F- uint8_t* Double_ReadI2C(uint8_t REG_Address)$ N. N9 _8 T$ S& y2 s
- {
" o0 ^! ^3 Y" x% E - 2 I# h r* X! C" T' o
- while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,®_Address,1,500) != HAL_OK) k5 Z$ A! @% }& x
- {
5 k8 w: |+ f8 Q: I- e - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
$ E, G( D. r: B3 U, j - {
+ K) l3 J$ R# }* r - Error_Handler();
& w2 k4 j& x" F1 W* t" E; P$ | - }
0 |4 ]0 Q7 z, U$ B; y* U: e) P - }
: z& J l* i; G. A: G - / N" W+ j7 v/ U- L) D) A) z
- if(HAL_I2C_Master_Receive(&hi2c1,I2C1_READ_ADDRESS,(uint8_t*)RxBuffer,2,1000) != HAL_OK)
5 y# t4 v3 ^3 N. |5 b - {. ? {+ J: N6 |) m+ {
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF), v0 u k! A& }# v
- {1 x8 e0 M" y4 f: U6 j
- Error_Handler();, P$ g! n- X; k. N$ R6 q E
- }
- Q$ m7 W9 k* ^2 d2 h - }
6 g! L1 ~/ C/ _& N& d - return RxBuffer;0 i* G0 ~3 _% i V
- }
复制代码
: _$ ~) @5 k$ F+ l! D这是I2C读两个字节的 程序,主要写单个字节的时候需要取地址(®_Address),由于这个HAL_I2C_Master_Transmit()这个函数的输入参数,数据那一项是一个指针,所以如果传单个字节必须取地址,有一个PDF文件介绍了HAL库函数的使用,但是全英文的,可以看看提高自己的英文水平,主要的两个I2C函数都在这里,可以直接调用HAL 的API,用起来非常方便!
- s- J" `7 s/ Q& J j- void LCD_Send_Data(unsigned char Data)/ q r* i1 V8 I
- {8 x# R6 ]+ Y. I0 n0 x V; x1 y
- LCD_CS_L();
4 s6 a! B/ Y- E+ ^% ?+ s - LCD_DC_H();
: w3 k, O* o, e4 _, O" X - HAL_SPI_Transmit(&hspi1,&Data,1,100);: C( u& N5 o h$ n
-
# g- N" O. ~* ?" o! [$ ] - LCD_CS_H();
) T3 S% H1 d$ F( v J; j6 U - LCD_DC_H();
% }+ Q# |+ |$ @- [ i - }& }, J5 w3 X: Z/ w$ J
- void LCD_Send_CMD(unsigned char CommandByte)
2 U4 S/ h: |( z - {
! I; C- z1 r2 f& s - LCD_CS_L();
8 `! n* c# `# B; ~3 X X' w - LCD_DC_L(); , Z2 x1 T8 |& [( {9 j. K
- HAL_SPI_Transmit(&hspi1,&CommandByte,1,100);( Z( Q2 A( ?1 N, I$ W0 o$ V9 x3 w
- LCD_CS_H();
7 p1 J+ U3 I2 I, {8 C - LCD_DC_H(); ) Z9 s6 I" r2 v8 h+ H* u# \1 V
- }
复制代码 7 d# k* i' h3 v9 j, B; o
这是SPI的写函数,一个发命令,一个发数据,也是调用了HAL的API HAL_SPI_Transmit()这个函数,同样注意发一个字节的时候也要去地址8 R+ E+ n# r% \+ n- o1 f
主要的东西都完成了,只要把对应的LCD驱动和I2C设备的驱动复制过来,然后把读写接口对上,工程就完成了。
1 i5 s7 h6 ~% |* N9 w8 z本来自己的程序没有问题,但是调试的时候发现I2C一直卡死,还以为时出现了I2C,郁闷了一段时间,其实是自己没看电路图,造成视觉上的蒙蔽0 w1 z- F" k u9 f7 Y: d
3 t" x- f- o+ {% F9 r. F有没有人以为这里就是对应的SCL和SDA,我之前一直把SCL和SDA插在这里,结果I2C就一直卡死,表示自己给自己眼睛坑了,结果去查电路图才发现) n$ i$ @# s y1 ^* r/ L
( \! J2 }5 s, fSCL和SDA分别是第二排和第三排靠内的那两个,换下接口后I2C就立马工作了,表示自己在这个上面把自己坑了半天........, H8 \4 I$ _* J" \$ Q# v
STM32F0çHALåºç¨æ·æå_é¨å1.pdf
(6.34 MB, 下载次数: 1865)
|
我的IIC也显示为“FF”,原因是每次断电或复位产生的信号干扰被误读。
木有放弃啊,已经出来了,F7现在都支持了4 `0 |. Y7 V' O+ f5 Z
http://www.st.com/web/en/catalog ... _searchtype=keyword
已解决,cube设置错误,把SPI定义成了单发。