本帖最后由 kevin0129 于 2015-1-11 14:14 编辑 6 `/ O5 P" b9 ?
}5 V ~% Q3 m9 I
最近看到沐紫老师手上有多余的nucleo stm32f072的板,果断以之前的活动价购买了一块,之前研究过stm32f103,当使用072的时候发现它的这个HAL库和标准库差别十分大,于是便研究了一下这个HAL库,之前使用了一点这个cube MX,发现这个配置软件非常好用,相对于103来说,我们不用再来自己动手配置外设了,直接设置几个参数就够了,今天来介绍下cube mx生成一个带I2C和SPI的工程的步骤(之前用103没怎么调通过I2C,一直软件模拟,这次尝试下,发现没有出现I2C bug,应该不是侥幸,毕竟测试了四天四夜.......)
q# ?( B8 Z5 p1.打开cubemx后选择nucleo f072的板子,这个很好找
9 ?5 z Z- s8 G" w3 @2.配置外设的引脚) E8 X [ _9 u/ v
/ D& E: O; u, Z5 A0 TI2C就直接选择I2C模式3 x! x& D* ]9 C
7 Y9 G( X- J& S6 s
SPI设备我用的一块显示屏,没必要去读它,我就直接选择了主机只发送的模式,如果要读写的话就不要选择这个了6 n, t' } t" }8 A+ r
3 d2 x+ n" I; h) @! x. gI2C的引脚更改,我看到板子上的SCL和SDA在PB8和PB9上果断把默认的引脚改成PB8和PB9(这个其实可以不用改的,我只是为了接线方便); h$ ?: o+ B' R" u; [
* }4 m ]3 \ c# b
接下来配置几个I/O做显示屏的控制I/O,直接都设置为输出就够了!
2 o9 f6 e; h% G# {- d( z' c1 E
( s7 n2 [) s( F' o接下来配置时钟,我自己焊了一个HSE晶振,所以选择了外部晶振,配置系统时钟为48M,还有设置I2C的时钟为系统时钟
/ b3 ~3 X4 s" V1 T- s
, x s& B8 Y. _5 [! [) {3 W; G N接下来是I2C的配置,设置为标准模式100k速度, 上升沿400ns下降沿100ns,这个地方的设置和f103的I2C配置有点不一样,我没有选择中断和DMA最后修改下I2C的GPIO配置就够了(和配置其他gpio一样)
* e) ~+ `/ f7 h" E. f# s; C
1 u6 W/ I9 ?2 w4 [# r
SPI的设置更简单只需设置数据长度和速度就够了,同样没有用DMA和中断,只需配置I/O就够了
# U4 w- ]" N( ]8 T) ]3 ]7 f: ^2 x最后去配置一下那几个控制I/O就够了,这样就可以生成工程了
) |8 M5 d$ p2 `0 ~' P
5 n" ~/ R0 d8 I4 P! u4 M9 S
生成工程的时候我选择了这个,我不喜欢把所有的代码都放到main.c文件里面,看起来很麻烦,这一项是单独生成对应的外设.c和.h文件,看起来比较舒服
3 B9 b5 \% U7 E* i: i生成工程完毕后,外设都基本设置好了,主要配置下I2C的读写程序和SPI的写程序就够了1 b+ |. u) c4 Z: v+ y! e% e, p. ?- x
- void Single_WriteI2C(uint8_t REG_Address,uint8_t REG_data)
" K$ T! G' g: V$ f9 M$ C - {8 W* U- S4 _; W' n' |: [1 R; M
- uint8_t TxData[2] = {REG_Address,REG_data};/ @' m! t; }* }( z2 M
- while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,(uint8_t*)TxData,2,1000) != HAL_OK)
5 o% S! U7 o7 e) h4 J - {. u6 F% g: ?8 p# H
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)
& Q4 h8 _# t5 g- H - {
$ L* _; O# N; f - Error_Handler();
& K3 z7 r/ r# j( o1 ~+ H3 ~ - }, r1 F. C3 H2 s& f; {$ i
- }
; C6 K. P R- B7 B* r2 _! f - }
复制代码 3 J; \2 g7 b" J; W* t$ Z, T- o
, {( W8 ~; W/ w i: P, j; S& O
这是I2C的写单个字节的程序
1 H+ W5 h g g1 H# v- uint8_t* Double_ReadI2C(uint8_t REG_Address)- v J2 n1 z8 a. y
- {
, ?4 A9 O8 \ ]9 O - 3 J! B5 U* ?% t+ c9 L2 a4 Y) c: n
- while(HAL_I2C_Master_Transmit(&hi2c1,I2C1_WRITE_ADDRESS,®_Address,1,500) != HAL_OK) X% t }! b3 l% a
- {
0 d! X- Q1 }: Y5 B7 p - if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF); k U0 e+ I$ E
- {
) p: N2 |9 M0 L9 {5 V4 C - Error_Handler();4 H. O; b3 B' ?+ O+ v
- }7 U8 v. L* S& a. B: g
- }" c4 H# A' G- n5 h
-
$ `: {6 _! {5 B6 i P - if(HAL_I2C_Master_Receive(&hi2c1,I2C1_READ_ADDRESS,(uint8_t*)RxBuffer,2,1000) != HAL_OK)
, n* W& J9 s# y' Y" D, H - {' B( V% z) T4 W# h1 u
- if (HAL_I2C_GetError(&hi2c1) != HAL_I2C_ERROR_AF)5 k. E! k% X5 k9 Q1 s) V, X
- {; _6 N0 i3 C( Q0 t3 k2 p
- Error_Handler();7 ]% @+ V7 O( Y4 v2 C# Y
- }6 R5 }6 V+ V# F/ W% ~& Z( m
- }
' I0 U+ _* }4 _1 R. I - return RxBuffer;
0 I$ |' a% z& l: D* e/ S. p' J - }
复制代码 : z; g; S. {% O! n/ e/ j3 c% j2 s! i
这是I2C读两个字节的 程序,主要写单个字节的时候需要取地址(®_Address),由于这个HAL_I2C_Master_Transmit()这个函数的输入参数,数据那一项是一个指针,所以如果传单个字节必须取地址,有一个PDF文件介绍了HAL库函数的使用,但是全英文的,可以看看提高自己的英文水平,主要的两个I2C函数都在这里,可以直接调用HAL 的API,用起来非常方便!* F6 Z4 D3 Y6 f" @$ J6 K
- void LCD_Send_Data(unsigned char Data)
! ~% v, v! e& F3 T8 g! j1 s3 s4 p - {1 k" d' j) E; s3 S) O
- LCD_CS_L();
% w& R2 f7 Q6 j. t6 t+ B0 O - LCD_DC_H();
- E4 Y. z& H; l+ m: i1 }0 k8 L - HAL_SPI_Transmit(&hspi1,&Data,1,100);
}7 r$ h0 U" O k/ \4 j: N# W4 z - " h# d* S( U: Y* n! W. q
- LCD_CS_H();
8 d3 K, s' { | g - LCD_DC_H();
( g4 T; U9 U5 j1 H9 z* y2 A8 V - }3 I ~" w( O( _! u" h% b
- void LCD_Send_CMD(unsigned char CommandByte)+ ^! c4 q; P5 R$ K6 u. t1 w) i! w
- {
0 q6 R* m7 X$ P+ Z+ b# v' f - LCD_CS_L();
- K( z/ _ w# R - LCD_DC_L(); * K6 G) K6 H! O8 _
- HAL_SPI_Transmit(&hspi1,&CommandByte,1,100);
3 ?4 |/ u A* }- C, j4 \. ] - LCD_CS_H();
% I% @. b8 j2 U# Z' {7 ~5 r. \+ W - LCD_DC_H();
~ V0 O! x" u - }
复制代码 ' Y& L6 f# u8 \: C! O
这是SPI的写函数,一个发命令,一个发数据,也是调用了HAL的API HAL_SPI_Transmit()这个函数,同样注意发一个字节的时候也要去地址
, \: T0 q% O0 C' A1 t1 {( Y主要的东西都完成了,只要把对应的LCD驱动和I2C设备的驱动复制过来,然后把读写接口对上,工程就完成了。* N3 P) R; {% ?9 V: @; N! ^
本来自己的程序没有问题,但是调试的时候发现I2C一直卡死,还以为时出现了I2C,郁闷了一段时间,其实是自己没看电路图,造成视觉上的蒙蔽
7 i+ m8 ~+ |1 s3 C- y& E2 F
9 W U/ U+ r# j- g有没有人以为这里就是对应的SCL和SDA,我之前一直把SCL和SDA插在这里,结果I2C就一直卡死,表示自己给自己眼睛坑了,结果去查电路图才发现
9 a" L. ^) j4 g! I/ G) E% j
7 ~# ^# |% M$ s, t
SCL和SDA分别是第二排和第三排靠内的那两个,换下接口后I2C就立马工作了,表示自己在这个上面把自己坑了半天........" M' k6 l+ A: e0 h0 S, k* z9 @
STM32F0çHALåºç¨æ·æå_é¨å1.pdf
(6.34 MB, 下载次数: 1865)
|
我的IIC也显示为“FF”,原因是每次断电或复位产生的信号干扰被误读。
木有放弃啊,已经出来了,F7现在都支持了
http://www.st.com/web/en/catalog ... _searchtype=keyword
已解决,cube设置错误,把SPI定义成了单发。