本帖最后由 kevin0129 于 2015-1-11 14:14 编辑 . e5 n3 ~9 m: [9 H* }& j' b
# j5 Q9 G" E9 ^; r7 \2 v: ~9 h 最近看到沐紫老师手上有多余的nucleo stm32f072的板,果断以之前的活动价购买了一块,之前研究过stm32f103,当使用072的时候发现它的这个HAL库和标准库差别十分大,于是便研究了一下这个HAL库,之前使用了一点这个cube MX,发现这个配置软件非常好用,相对于103来说,我们不用再来自己动手配置外设了,直接设置几个参数就够了,今天来介绍下cube mx生成一个带I2C和SPI的工程的步骤(之前用103没怎么调通过I2C,一直软件模拟,这次尝试下,发现没有出现I2C bug,应该不是侥幸,毕竟测试了四天四夜.......)
' c( x3 N$ C& `4 w: H1.打开cubemx后选择nucleo f072的板子,这个很好找6 X$ P; R" R6 E7 ^. x9 t
2.配置外设的引脚
& g, S7 C" c! `. O- B+ V8 d
6 X* b! J, y5 {3 t9 i- m* d- HI2C就直接选择I2C模式6 f% i. z/ [- E$ `( o" B
4 [; K3 | a1 d1 C! ]% O: Y$ q- \ qSPI设备我用的一块显示屏,没必要去读它,我就直接选择了主机只发送的模式,如果要读写的话就不要选择这个了6 ]9 l9 s" U: t: a( C) n, ^
* Q* Z% K. s- O& lI2C的引脚更改,我看到板子上的SCL和SDA在PB8和PB9上果断把默认的引脚改成PB8和PB9(这个其实可以不用改的,我只是为了接线方便)5 U# P( S1 o- A: U; B$ k
" Y$ }. w4 l& A) D5 \- m
接下来配置几个I/O做显示屏的控制I/O,直接都设置为输出就够了!
0 f1 M1 W5 c9 O/ Q" t' ^* d2 r1 h
" Y7 d1 W: F9 |
接下来配置时钟,我自己焊了一个HSE晶振,所以选择了外部晶振,配置系统时钟为48M,还有设置I2C的时钟为系统时钟) w3 J$ Z4 i! R; ~, q
" p, Y- f$ {2 h1 B2 r) `
接下来是I2C的配置,设置为标准模式100k速度, 上升沿400ns下降沿100ns,这个地方的设置和f103的I2C配置有点不一样,我没有选择中断和DMA最后修改下I2C的GPIO配置就够了(和配置其他gpio一样)' j- \7 W- t" E
! {8 q5 @ U0 n; C
SPI的设置更简单只需设置数据长度和速度就够了,同样没有用DMA和中断,只需配置I/O就够了0 V5 f. {0 }/ L7 y0 m" [5 p+ Q! Q
最后去配置一下那几个控制I/O就够了,这样就可以生成工程了
4 Z0 C, V! M; I) `* e# _
# C6 j z/ ?# i2 w8 k
生成工程的时候我选择了这个,我不喜欢把所有的代码都放到main.c文件里面,看起来很麻烦,这一项是单独生成对应的外设.c和.h文件,看起来比较舒服+ Y* Q3 B* S9 y; x& o. f
生成工程完毕后,外设都基本设置好了,主要配置下I2C的读写程序和SPI的写程序就够了
3 s$ L8 M! d' k6 r! v% `2 `. n% b5 i- void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)8 d7 s `$ M( u; K
- {' v' u2 R8 I0 t a4 w+ B8 a
- uint8_t TxData[2] = {REG_Address,REG_data};
w4 u4 w$ c- h8 [, h% ]% _) `7 U1 t6 E - while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK)- q" H7 U2 J, y2 l
- {
0 C+ d$ j6 w8 _/ S; d - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
5 M7 \" c$ q1 W9 w" k" z) L - {/ h: ]0 i& `9 u: r9 N# d7 P4 l
- Error_Handler();$ K8 W6 m% {7 H& K+ ?! v' q7 K7 j: \
- }
7 ^7 r2 Q* h1 k% h! Q" @& P - }
9 g% |& q, s' R; V" I - }
复制代码 6 x9 D7 }1 o: y& u- d
$ ~& L6 u4 B4 I& T5 X6 i这是I2C的写单个字节的程序
+ r2 M- W; y' z7 _% P- uint8_t* Double_ReadI2C(uint8_t REG_Address)' K2 _' Q3 m J, S1 d) Y( M
- {
" k( F/ U' n$ e- f! _- \: N& o- l - % U4 d9 f0 C5 r& x
- while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,®_Address,1,500) != HAL_OK)
! F* r- @- s( I& g, [5 L1 L/ L - {
7 x) a3 A3 K0 `5 j( i - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)7 ^+ q, ^# e' f0 G0 Y
- {
" _; m( z3 R/ p - Error_Handler();
& r) D) \. p! e' C, q& G' [ - }/ y) H" b) N9 K
- }
4 \% Q. U$ ` p. j; I -
1 Y2 E- f7 A! {) E - if(HAL_I2C_Master_Receive(&hi2c1,I2C1_READ_ADDRESS,(uint8_t*)RxBuffer,2,1000) != HAL_OK)( }+ s" Y# E3 ]* `' i: k
- {
/ ]# D, B9 D* y4 v - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)# I7 V0 Z' d- v4 d8 A8 @
- {
# A- b* D8 N+ @+ ? - Error_Handler();
$ R1 h9 o, A- P# ?$ O* M - }3 `4 x0 A w2 X0 `! F
- }
) u7 i3 F! h+ E& |, A- X z5 M - return RxBuffer;, l8 f' z& O7 m4 M4 d
- }
复制代码 0 \" q& n5 Q3 q! P& c5 ~
这是I2C读两个字节的 程序,主要写单个字节的时候需要取地址(®_Address),由于这个HAL_I2C_Master_Transmit()这个函数的输入参数,数据那一项是一个指针,所以如果传单个字节必须取地址,有一个PDF文件介绍了HAL库函数的使用,但是全英文的,可以看看提高自己的英文水平,主要的两个I2C函数都在这里,可以直接调用HAL 的API,用起来非常方便!3 g- q5 H6 G7 i* V" h+ k1 o
- void LCD_Send_Data(unsigned char Data)
% g8 i1 Q L6 [7 M9 Y - {
5 c) O+ ~; R, M( d9 L% m - LCD_CS_L();0 {1 a, K1 ?! \2 V% E
- LCD_DC_H(); , E$ J9 x' w* D; Q. H/ B
- HAL_SPI_Transmit(&hspi1,&Data,1,100);6 u4 }1 [$ N/ O* v$ O/ J# J1 [
-
7 i8 M# g) L8 t# n' G ` - LCD_CS_H(); }$ H) c4 B& A3 l/ C1 f
- LCD_DC_H(); 5 p1 t4 [% b. m8 a' W4 j5 @
- }
+ X! [ F# o& H2 [1 R- p) K - void LCD_Send_CMD(unsigned char CommandByte)
' B& J e. C9 X7 c - {
' O' h. d" O( z0 D - LCD_CS_L();
# W& _8 n7 ]$ G - LCD_DC_L();
/ g# e; d- k1 k' Y2 w: b5 L - HAL_SPI_Transmit(&hspi1,&CommandByte,1,100);3 f4 d" @% g8 ~9 J9 s
- LCD_CS_H();" r1 T' i2 F/ l9 A3 d- g
- LCD_DC_H();
4 f1 \$ z) E! B" F - }
复制代码
, L( h# n8 r. [, O7 T5 q' z4 T这是SPI的写函数,一个发命令,一个发数据,也是调用了HAL的API HAL_SPI_Transmit()这个函数,同样注意发一个字节的时候也要去地址
% A2 W# U) H" t) C主要的东西都完成了,只要把对应的LCD驱动和I2C设备的驱动复制过来,然后把读写接口对上,工程就完成了。0 B6 y% C! m6 X: ]
本来自己的程序没有问题,但是调试的时候发现I2C一直卡死,还以为时出现了I2C,郁闷了一段时间,其实是自己没看电路图,造成视觉上的蒙蔽5 S0 R2 v7 g/ f6 o
/ \7 ?# c# F& W" F有没有人以为这里就是对应的SCL和SDA,我之前一直把SCL和SDA插在这里,结果I2C就一直卡死,表示自己给自己眼睛坑了,结果去查电路图才发现
% z+ q+ `1 d. K4 S2 E5 P/ M
- s/ @ X1 S+ L1 r( kSCL和SDA分别是第二排和第三排靠内的那两个,换下接口后I2C就立马工作了,表示自己在这个上面把自己坑了半天......... e5 k7 x# ?! q4 E9 j
STM32F0çHALåºç¨æ·æå_é¨å1.pdf
(6.34 MB, 下载次数: 1865)
|
我的IIC也显示为“FF”,原因是每次断电或复位产生的信号干扰被误读。
木有放弃啊,已经出来了,F7现在都支持了
http://www.st.com/web/en/catalog ... _searchtype=keyword
已解决,cube设置错误,把SPI定义成了单发。