本帖最后由 kevin0129 于 2015-1-11 14:14 编辑
, S" m: P9 e' _. [: _! k
; W* W5 w3 w. W5 f0 i6 n, n" Z 最近看到沐紫老师手上有多余的nucleo stm32f072的板,果断以之前的活动价购买了一块,之前研究过stm32f103,当使用072的时候发现它的这个HAL库和标准库差别十分大,于是便研究了一下这个HAL库,之前使用了一点这个cube MX,发现这个配置软件非常好用,相对于103来说,我们不用再来自己动手配置外设了,直接设置几个参数就够了,今天来介绍下cube mx生成一个带I2C和SPI的工程的步骤(之前用103没怎么调通过I2C,一直软件模拟,这次尝试下,发现没有出现I2C bug,应该不是侥幸,毕竟测试了四天四夜.......)
# I0 N! X$ N" q( z; T `% Z7 p% t1.打开cubemx后选择nucleo f072的板子,这个很好找$ C- v7 o* J3 K5 `# ]& G
2.配置外设的引脚2 {) K" c& ]1 q: Q. |' Z
/ n6 n2 B& Q' P: \& |2 x
I2C就直接选择I2C模式3 U1 a- s9 v. U3 W4 _, o$ V0 S
& y$ q8 `! ^6 Q% k7 u+ d' ?! `SPI设备我用的一块显示屏,没必要去读它,我就直接选择了主机只发送的模式,如果要读写的话就不要选择这个了: i- ^: t; @' z& ^* |
. g9 {; _4 Z1 fI2C的引脚更改,我看到板子上的SCL和SDA在PB8和PB9上果断把默认的引脚改成PB8和PB9(这个其实可以不用改的,我只是为了接线方便)
* Z% h. [) ?4 U# X( t
; I3 ?+ y( k a& C3 L, t% |
接下来配置几个I/O做显示屏的控制I/O,直接都设置为输出就够了!
. D! Y \1 Q* F" c& ?1 Q
8 v9 j! g- { [: A4 h接下来配置时钟,我自己焊了一个HSE晶振,所以选择了外部晶振,配置系统时钟为48M,还有设置I2C的时钟为系统时钟 s, A% i: b: B; M, q
& h/ R4 j4 I4 e K接下来是I2C的配置,设置为标准模式100k速度, 上升沿400ns下降沿100ns,这个地方的设置和f103的I2C配置有点不一样,我没有选择中断和DMA最后修改下I2C的GPIO配置就够了(和配置其他gpio一样)
6 b- c* Q/ c* ]. t& m
$ Q# c' }) r0 p
SPI的设置更简单只需设置数据长度和速度就够了,同样没有用DMA和中断,只需配置I/O就够了
7 |: T. w( G5 v" T' k+ u最后去配置一下那几个控制I/O就够了,这样就可以生成工程了
1 H! m- _; w- r: D, j1 j9 r
3 S3 A4 q1 o2 W* a0 \( Y. b5 J- k# \生成工程的时候我选择了这个,我不喜欢把所有的代码都放到main.c文件里面,看起来很麻烦,这一项是单独生成对应的外设.c和.h文件,看起来比较舒服 h0 F* F# m; e, S; g
生成工程完毕后,外设都基本设置好了,主要配置下I2C的读写程序和SPI的写程序就够了
$ p% s% a( N+ B' Y+ [5 h- void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
6 s' d7 q$ S! f+ m; n2 }% U2 Z" P - {5 z+ @& U9 Y4 a0 b9 Y$ f
- uint8_t TxData[2] = {REG_Address,REG_data};! h. Y9 f( c5 W& N \2 ~, R
- while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK)0 s2 B% r6 k* u2 H: s" I6 @; G
- {
6 d1 U( }0 h2 E/ ~/ A: f - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)/ k+ M* F5 a1 k+ b, C! }
- {7 o1 k3 e9 S. s2 B/ K
- Error_Handler(); B# f# {2 L0 u" S/ R. K( J) x5 u
- }
3 i& q1 p1 U/ U' i) ~/ e2 {) P9 J( x8 S - }
% U6 G5 x* G! q - }
复制代码 9 k0 Q: r$ U( ~& m9 c, |0 E
3 h R" k( m9 a这是I2C的写单个字节的程序# q& h( n. K- a% O8 F
- uint8_t* Double_ReadI2C(uint8_t REG_Address)
2 t0 A% K" a5 a2 d, ?* o6 l) _" s - {8 x) a' c) _! l( ^7 `
-
. S8 G/ S- W+ s0 b" w5 b3 q o5 V - while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,®_Address,1,500) != HAL_OK)5 X6 m& i" P; d4 u
- {
& x5 V8 T" B* o) t" T2 B# v - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
# t2 ?8 B4 U& @ - {
; U! _" u0 h* N# r# ^9 s - Error_Handler();1 Y8 U( D- G8 o8 T! d% O
- }
1 @/ D* o3 G$ |. G( K& J - }
/ l5 f. U' m1 l# \: K' `4 K. ~ -
- j* G7 Z, }2 \2 X: R u6 ] - if(HAL_I2C_Master_Receive(&hi2c1,I2C1_READ_ADDRESS,(uint8_t*)RxBuffer,2,1000) != HAL_OK)# U: z+ O0 R) `( ]3 m
- {
. t& ]1 R' @, }' C, U6 f - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
9 h* R6 h; y/ Y( p: { - {
0 a. E# t) H/ x0 \ ~. {4 ]# B, B L - Error_Handler();
% s! N$ T! c+ T - }6 X8 q! D+ {; s+ `. N+ z3 q
- } Y5 r1 {9 p! b, p4 _4 ]
- return RxBuffer;4 x; d$ U! m ^$ X
- }
复制代码 ; X8 } ~+ F( |" `
这是I2C读两个字节的 程序,主要写单个字节的时候需要取地址(®_Address),由于这个HAL_I2C_Master_Transmit()这个函数的输入参数,数据那一项是一个指针,所以如果传单个字节必须取地址,有一个PDF文件介绍了HAL库函数的使用,但是全英文的,可以看看提高自己的英文水平,主要的两个I2C函数都在这里,可以直接调用HAL 的API,用起来非常方便!
# @" e1 G, u( N' Y- void LCD_Send_Data(unsigned char Data)
) F& `7 f m9 v* X - {
) Q' N+ U W5 X' Y2 w$ Y - LCD_CS_L();4 N% p% H- h* Z* y# p! j
- LCD_DC_H();
) X" H" O' T" ?+ l% E8 v* Z - HAL_SPI_Transmit(&hspi1,&Data,1,100);
) M: `7 M" h2 c3 L! s$ e -
2 w( v' s) t; G+ b( n) U8 P' Y0 i - LCD_CS_H();
8 Y8 M: ~* C Y- j - LCD_DC_H();
+ q- Y! ]% y4 P) A% `9 c) e - }) K/ o- t9 d! x2 z2 V
- void LCD_Send_CMD(unsigned char CommandByte)
0 F: m, ~' K: j) Q( S1 x - {- y- m3 [5 J& q6 \7 h
- LCD_CS_L();
+ j+ A7 M: h" f+ l# c - LCD_DC_L();
- L" p: ~0 y9 g9 Y0 A - HAL_SPI_Transmit(&hspi1,&CommandByte,1,100);" k3 o+ o* R7 M
- LCD_CS_H();3 y, }$ ^6 b, `+ q r8 O: Q7 o/ Y
- LCD_DC_H(); ) R* e+ R5 T& |+ K5 p
- }
复制代码
1 M* V. V8 z- C, r, n这是SPI的写函数,一个发命令,一个发数据,也是调用了HAL的API HAL_SPI_Transmit()这个函数,同样注意发一个字节的时候也要去地址3 g3 j3 Z. S% m7 A
主要的东西都完成了,只要把对应的LCD驱动和I2C设备的驱动复制过来,然后把读写接口对上,工程就完成了。
- q& w o- ~$ S# I本来自己的程序没有问题,但是调试的时候发现I2C一直卡死,还以为时出现了I2C,郁闷了一段时间,其实是自己没看电路图,造成视觉上的蒙蔽
9 d! y! e$ V; v6 ~; c
7 ~4 a t# x/ L$ f/ Y# k
有没有人以为这里就是对应的SCL和SDA,我之前一直把SCL和SDA插在这里,结果I2C就一直卡死,表示自己给自己眼睛坑了,结果去查电路图才发现7 \, Y5 Y) X8 R- `3 K2 a
P9 A4 R' P$ A1 rSCL和SDA分别是第二排和第三排靠内的那两个,换下接口后I2C就立马工作了,表示自己在这个上面把自己坑了半天........
8 O4 G1 ~) H. h3 r3 k
STM32F0çHALåºç¨æ·æå_é¨å1.pdf
(6.34 MB, 下载次数: 1865)
|
我的IIC也显示为“FF”,原因是每次断电或复位产生的信号干扰被误读。
木有放弃啊,已经出来了,F7现在都支持了; X* L" E# c9 _% I( |
http://www.st.com/web/en/catalog ... _searchtype=keyword
已解决,cube设置错误,把SPI定义成了单发。