本帖最后由 kevin0129 于 2015-1-11 14:14 编辑 ; r: j, f$ x1 @* w) y4 G5 |5 Z
9 l' f" j1 K1 a6 ~% g
最近看到沐紫老师手上有多余的nucleo stm32f072的板,果断以之前的活动价购买了一块,之前研究过stm32f103,当使用072的时候发现它的这个HAL库和标准库差别十分大,于是便研究了一下这个HAL库,之前使用了一点这个cube MX,发现这个配置软件非常好用,相对于103来说,我们不用再来自己动手配置外设了,直接设置几个参数就够了,今天来介绍下cube mx生成一个带I2C和SPI的工程的步骤(之前用103没怎么调通过I2C,一直软件模拟,这次尝试下,发现没有出现I2C bug,应该不是侥幸,毕竟测试了四天四夜.......)
' x9 O" Q% v8 V+ i c1.打开cubemx后选择nucleo f072的板子,这个很好找" I" ~. W- ~: B9 z1 {" s4 d) q/ J# n
2.配置外设的引脚
0 o3 b/ b6 J# w1 z
/ h- u ]& |& i8 n7 L" s4 `I2C就直接选择I2C模式
3 S! @; R5 G5 E8 ~: F
8 E! f [- K, B' m% P4 T" m* ^7 j
SPI设备我用的一块显示屏,没必要去读它,我就直接选择了主机只发送的模式,如果要读写的话就不要选择这个了
" p8 @) _ U( a. f
$ H9 B. n8 D" xI2C的引脚更改,我看到板子上的SCL和SDA在PB8和PB9上果断把默认的引脚改成PB8和PB9(这个其实可以不用改的,我只是为了接线方便)
4 E( r- d& K1 a5 k- W$ o4 Y) k5 f
2 f% c! {% u8 R' M
接下来配置几个I/O做显示屏的控制I/O,直接都设置为输出就够了!5 G3 ?$ P& g# O; u. E. | Z
/ W3 U5 W+ D B3 @( k4 m) S
接下来配置时钟,我自己焊了一个HSE晶振,所以选择了外部晶振,配置系统时钟为48M,还有设置I2C的时钟为系统时钟
, A+ {! [5 I, @' [
/ [6 Y6 ` n9 Q( P/ _7 h
接下来是I2C的配置,设置为标准模式100k速度, 上升沿400ns下降沿100ns,这个地方的设置和f103的I2C配置有点不一样,我没有选择中断和DMA最后修改下I2C的GPIO配置就够了(和配置其他gpio一样)/ c$ F! z. L) }3 O" O
( r) z+ Q6 t; Z, J) QSPI的设置更简单只需设置数据长度和速度就够了,同样没有用DMA和中断,只需配置I/O就够了& Q8 w' I" o0 K' G" h, Z
最后去配置一下那几个控制I/O就够了,这样就可以生成工程了
5 z' O/ a3 m- X/ Z4 ?( C
% u1 B( }4 O+ z
生成工程的时候我选择了这个,我不喜欢把所有的代码都放到main.c文件里面,看起来很麻烦,这一项是单独生成对应的外设.c和.h文件,看起来比较舒服( ]7 F$ V- o7 V5 ~
生成工程完毕后,外设都基本设置好了,主要配置下I2C的读写程序和SPI的写程序就够了/ a9 E9 K) P; T" }5 J
- void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
0 E5 Q- H% q) b0 v4 N - {4 r% F# g/ q+ ^/ f( u5 N3 J
- uint8_t TxData[2] = {REG_Address,REG_data};
3 r- Q/ V( R; m" ] - while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK)
9 U3 I" T, o) u% }# J/ A* \ - {. E6 E% m4 v7 m; n) N* J, f
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
: K7 a, [: t: y: d. c1 H - {
0 b5 }; u$ I! h9 _, L9 h - Error_Handler();
# I& U7 J1 r; g# ]7 x3 k" M4 M; d - }; k0 l3 M7 r7 q! Y3 f) o- s+ ^
- }/ b4 c1 U% r; t4 Y2 R; ]4 r. M$ I
- }
复制代码
Y \3 g' s" K8 `
- L9 c) |! U* Q) f2 f这是I2C的写单个字节的程序, J- D# b! s& f7 r
- uint8_t* Double_ReadI2C(uint8_t REG_Address)" y/ R0 h# R& C0 M% ?7 q7 b9 H
- {
8 }) X2 j2 m% Z4 _. }, _ j9 T; b - d7 t! N0 u, n6 c- K5 p% V$ M# t
- while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,®_Address,1,500) != HAL_OK)1 _1 _8 a# j' J% T2 @
- {
% S. y. S( x- T% z' \& \- W - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
- F( D6 }5 E u/ S - {
" Z" y" }8 }4 m& o - Error_Handler();, f$ b- X! B" R8 K* k
- }! x u7 ?5 y6 i/ b0 T# A
- }
& S, _$ n9 J4 J) Z. g - 7 r2 x: |6 V* [; d- S" a$ H
- if(HAL_I2C_Master_Receive(&hi2c1,I2C1_READ_ADDRESS,(uint8_t*)RxBuffer,2,1000) != HAL_OK)
: ^1 H) s/ ?5 u. V - {. l# }" F& J( N1 q' E8 \
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF); u, W7 b' h& e4 z7 [# P6 j
- {2 r" j6 x" S* {# b4 P
- Error_Handler();
; _% J+ i# s3 x - }
! A2 m; s/ q3 }" H- q7 o - }3 S7 v) n- q! R) u5 A9 D
- return RxBuffer;
0 K9 V7 |! e/ T4 l - }
复制代码
8 Q" }$ {8 |$ b9 G- O$ c这是I2C读两个字节的 程序,主要写单个字节的时候需要取地址(®_Address),由于这个HAL_I2C_Master_Transmit()这个函数的输入参数,数据那一项是一个指针,所以如果传单个字节必须取地址,有一个PDF文件介绍了HAL库函数的使用,但是全英文的,可以看看提高自己的英文水平,主要的两个I2C函数都在这里,可以直接调用HAL 的API,用起来非常方便!
# v' v, J+ h1 {% Y" @- void LCD_Send_Data(unsigned char Data)4 z4 R- u8 z- z1 c: F* y+ y
- {/ [& ^6 h% V" {5 t
- LCD_CS_L();, O7 M4 r% N: V1 T& D$ t
- LCD_DC_H();
9 F& z4 k# u" M- |1 q - HAL_SPI_Transmit(&hspi1,&Data,1,100);: a9 ^5 P/ I- D1 ?4 r0 Q: X2 }
- % r# C. k1 G- d( I( S7 J5 \( i3 ?1 y
- LCD_CS_H();0 h/ R, e" \# _
- LCD_DC_H(); / s- r+ N( _2 e( ]* v) o7 A( H
- }
& F( ^; G! E2 v7 t3 U - void LCD_Send_CMD(unsigned char CommandByte): s) Q& P) W0 g% S, E
- {. h- |1 M' l' n* F* M
- LCD_CS_L();! Z4 A7 l$ z5 ?0 X
- LCD_DC_L(); ' J+ J+ ~2 ]. V2 h" N5 M
- HAL_SPI_Transmit(&hspi1,&CommandByte,1,100);) a: M9 ~% e: t7 L
- LCD_CS_H();' C# F" z n% O) K
- LCD_DC_H(); - T5 F. G, n q1 k; {, D
- }
复制代码 ) @$ J( F" K4 n) Z0 o+ r1 o! _1 R
这是SPI的写函数,一个发命令,一个发数据,也是调用了HAL的API HAL_SPI_Transmit()这个函数,同样注意发一个字节的时候也要去地址
% \/ P8 k6 \& X1 e4 A: R主要的东西都完成了,只要把对应的LCD驱动和I2C设备的驱动复制过来,然后把读写接口对上,工程就完成了。
% S; j G3 O, j本来自己的程序没有问题,但是调试的时候发现I2C一直卡死,还以为时出现了I2C,郁闷了一段时间,其实是自己没看电路图,造成视觉上的蒙蔽# L0 {4 H+ D" N7 L+ Q: [( R
3 i+ t. O8 ]1 W/ d' d7 F4 g0 d有没有人以为这里就是对应的SCL和SDA,我之前一直把SCL和SDA插在这里,结果I2C就一直卡死,表示自己给自己眼睛坑了,结果去查电路图才发现! W7 r4 x. K, Y0 x4 I
+ h6 j% |6 P0 e8 S
SCL和SDA分别是第二排和第三排靠内的那两个,换下接口后I2C就立马工作了,表示自己在这个上面把自己坑了半天........
% y% x j5 W: [/ a- N0 j
STM32F0çHALåºç¨æ·æå_é¨å1.pdf
(6.34 MB, 下载次数: 1865)
|
我的IIC也显示为“FF”,原因是每次断电或复位产生的信号干扰被误读。
木有放弃啊,已经出来了,F7现在都支持了7 ^# `7 @0 k, l" k4 z; D
http://www.st.com/web/en/catalog ... _searchtype=keyword
已解决,cube设置错误,把SPI定义成了单发。