本帖最后由 kevin0129 于 2015-1-11 14:14 编辑
. J5 z0 r: m5 |( `) S. T) T& T0 I* H/ f9 ^
最近看到沐紫老师手上有多余的nucleo stm32f072的板,果断以之前的活动价购买了一块,之前研究过stm32f103,当使用072的时候发现它的这个HAL库和标准库差别十分大,于是便研究了一下这个HAL库,之前使用了一点这个cube MX,发现这个配置软件非常好用,相对于103来说,我们不用再来自己动手配置外设了,直接设置几个参数就够了,今天来介绍下cube mx生成一个带I2C和SPI的工程的步骤(之前用103没怎么调通过I2C,一直软件模拟,这次尝试下,发现没有出现I2C bug,应该不是侥幸,毕竟测试了四天四夜.......), O! {0 u- r ?- D4 q# c9 R9 f
1.打开cubemx后选择nucleo f072的板子,这个很好找
( b: _: I, q% L6 A% `4 a2.配置外设的引脚
6 j" ?4 Y0 k- [( [; f
: w, X! F; ^% R) Y/ H' t+ k/ ]
I2C就直接选择I2C模式7 A/ @1 k4 l) s- e+ y
7 u' a1 N( e) J [4 O6 d8 c# e
SPI设备我用的一块显示屏,没必要去读它,我就直接选择了主机只发送的模式,如果要读写的话就不要选择这个了 ~7 N, l8 h* b1 @/ P7 v1 I8 {
, f! X$ ?; Y& iI2C的引脚更改,我看到板子上的SCL和SDA在PB8和PB9上果断把默认的引脚改成PB8和PB9(这个其实可以不用改的,我只是为了接线方便)
, M2 t* O. j! g6 a
8 s1 i* E [9 G8 Z8 t; H5 W接下来配置几个I/O做显示屏的控制I/O,直接都设置为输出就够了!% [6 Q3 {) z# S
" Z4 B9 j% t% O- g* S
接下来配置时钟,我自己焊了一个HSE晶振,所以选择了外部晶振,配置系统时钟为48M,还有设置I2C的时钟为系统时钟
" ^2 w% J) ?/ l0 v
+ J/ i2 T% e! z
接下来是I2C的配置,设置为标准模式100k速度, 上升沿400ns下降沿100ns,这个地方的设置和f103的I2C配置有点不一样,我没有选择中断和DMA最后修改下I2C的GPIO配置就够了(和配置其他gpio一样): Z) r" n' y4 z& I
! q6 f' t+ z' y% L) c) |4 F8 t! TSPI的设置更简单只需设置数据长度和速度就够了,同样没有用DMA和中断,只需配置I/O就够了& L: c$ F% c+ `
最后去配置一下那几个控制I/O就够了,这样就可以生成工程了" d" n% y- a3 _, [/ L
A( I4 q: a$ ^4 F
生成工程的时候我选择了这个,我不喜欢把所有的代码都放到main.c文件里面,看起来很麻烦,这一项是单独生成对应的外设.c和.h文件,看起来比较舒服
& T3 }" L( n3 _! ~) I生成工程完毕后,外设都基本设置好了,主要配置下I2C的读写程序和SPI的写程序就够了1 ~1 K' d% I" u- G
- void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)" m2 g% Z: i* h; v$ `( ?. B6 j1 N
- {
5 X7 } l2 G- Q. J* y - uint8_t TxData[2] = {REG_Address,REG_data};0 L0 z1 | E& ^2 m+ e, L- ~
- while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK)' w" |0 c: b& u$ Z/ T: t
- {
+ I1 t/ x3 }' L - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)# W2 L' A( K; y0 ~8 b4 }7 _
- {; s8 t8 J) [3 K7 b* ]
- Error_Handler();5 }, o7 i7 v0 k3 C. ?; n- D- I
- }' M8 Z$ k/ D9 C5 W0 M
- }
3 Y# ?' q$ o8 |& K4 s! z5 p. Y - }
复制代码
! L& Q6 r. f7 ^: p. F0 u7 I/ g5 ]
5 D" F" Y: W7 `+ ~这是I2C的写单个字节的程序
; z2 h( ]1 r# f( i. g: l- uint8_t* Double_ReadI2C(uint8_t REG_Address)
. e9 u" F, V9 m) j$ |$ J+ ` - {
: _; z* T& s5 ^' L9 J7 X -
5 d) O# u: {' _* z) w% i8 m - while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,®_Address,1,500) != HAL_OK)& r1 ~7 e. d! k" l k8 n
- {
) V2 `1 X& |' d' R' x5 Y& N& z - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
' \+ x! _7 {. c3 ^( Y5 f) ~ - {
4 y9 _7 S0 F! F! c - Error_Handler();$ R( _, ]/ u% q% m5 g
- }
& w" z; Z1 @/ J - }9 u& R+ d) H, n- s# V3 {) O
-
8 R& D& c8 j; y5 h$ @( d/ j - if(HAL_I2C_Master_Receive(&hi2c1,I2C1_READ_ADDRESS,(uint8_t*)RxBuffer,2,1000) != HAL_OK)/ F4 w- }+ i( s% l
- {" g: U5 I/ c, r6 U& R0 e! Y$ z
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
6 f a! g- i- X! `6 X - {/ [1 f( x% E1 K9 D% N
- Error_Handler();& ?' V& ~) Z, w+ Z8 h! J Z Y' n
- }
* M% B( }- T0 b ]4 S1 T - }' x7 Q$ M- n' `
- return RxBuffer;
6 |% k* G8 d y7 F) ]; q( _ - }
复制代码 # v X' ?; `% U/ S+ ~+ z0 W
这是I2C读两个字节的 程序,主要写单个字节的时候需要取地址(®_Address),由于这个HAL_I2C_Master_Transmit()这个函数的输入参数,数据那一项是一个指针,所以如果传单个字节必须取地址,有一个PDF文件介绍了HAL库函数的使用,但是全英文的,可以看看提高自己的英文水平,主要的两个I2C函数都在这里,可以直接调用HAL 的API,用起来非常方便!
& S! H8 i) {, m6 C, e/ p- void LCD_Send_Data(unsigned char Data)
- y5 z3 r9 c, i7 c6 X; z - {
! H, J4 L3 m7 X5 P: { - LCD_CS_L();. M7 x; P O8 n0 }/ S8 l3 F
- LCD_DC_H(); & c. x- v; ]+ ]( z8 O/ P/ d
- HAL_SPI_Transmit(&hspi1,&Data,1,100);
; |; v9 R0 T- x, |" f6 X - 1 i% x* ^9 K2 Y0 F' a* `
- LCD_CS_H();
/ F. Q! K( \+ o5 V/ u' ?: ~7 P2 ? - LCD_DC_H();
~9 \! d1 w9 Z4 c) U - }% {. x$ F4 ~( @! |$ ^) f: S
- void LCD_Send_CMD(unsigned char CommandByte)
% A" x7 V( k9 r) t - {
& E. R3 I* L7 A+ l! u - LCD_CS_L();
7 \# J% |# ]9 @; M( Z0 ^( a - LCD_DC_L(); 5 k: z7 ^- A; K
- HAL_SPI_Transmit(&hspi1,&CommandByte,1,100);
/ E. K# f7 [* [ h& B& P( ? - LCD_CS_H();
4 ~5 ^; i: r1 Q/ P - LCD_DC_H();
& v: v* d3 w- P3 b/ t0 `6 G - }
复制代码
3 P; o- E* A( X) U% \) I这是SPI的写函数,一个发命令,一个发数据,也是调用了HAL的API HAL_SPI_Transmit()这个函数,同样注意发一个字节的时候也要去地址
* ~& a& n! l8 k( y) ]( P' l" `主要的东西都完成了,只要把对应的LCD驱动和I2C设备的驱动复制过来,然后把读写接口对上,工程就完成了。) h5 Y6 N" q+ E; z: [2 l
本来自己的程序没有问题,但是调试的时候发现I2C一直卡死,还以为时出现了I2C,郁闷了一段时间,其实是自己没看电路图,造成视觉上的蒙蔽
$ ?' f# e& t' b7 S0 K: i% l
% ]; }. L0 J! {0 K* E# |有没有人以为这里就是对应的SCL和SDA,我之前一直把SCL和SDA插在这里,结果I2C就一直卡死,表示自己给自己眼睛坑了,结果去查电路图才发现3 s3 _; D# h/ ?1 F& k, q: c
1 `/ K; f. y) s$ k
SCL和SDA分别是第二排和第三排靠内的那两个,换下接口后I2C就立马工作了,表示自己在这个上面把自己坑了半天........8 J6 X7 }% a' ?# s1 U% h6 r& i
STM32F0çHALåºç¨æ·æå_é¨å1.pdf
(6.34 MB, 下载次数: 1865)
|
我的IIC也显示为“FF”,原因是每次断电或复位产生的信号干扰被误读。
木有放弃啊,已经出来了,F7现在都支持了
http://www.st.com/web/en/catalog ... _searchtype=keyword
已解决,cube设置错误,把SPI定义成了单发。