Stm32具有IIC接口,接口有以下主要特性 多主机功能:该模块既可做主设备也可做从设备 主设备功能 C地址检测 产生和检测7位/10位地址和广播呼叫 支持不同的通讯速度 状态标志: 发送器/接收器模式标志 字节发送结束标志 总线忙标志 错误标志 2个中断向量 可选的拉长时钟功能 具单字节缓冲器的DMA 虽然很多人说STM的硬件IIC不好用,但是对于这么一个设备去探索一下还是很有必要的,指不定哪天就用上了呢, IIC借口一共有九个寄存器,比较重要的几个寄存器分别如下
! d8 H: P9 B9 R: Q7 }. Y) C! X
1. CR1 " |+ ^( s* S* _# _5 j
/ w+ |6 z- G# J% l" u
由这几个位我们可以正常产生标准IIC的START条件STOP条件,ACK与NOACK
6 z. S. v+ ?! C$ i( _
CR2 ' k! d. f5 n7 y* m# r5 v3 h

& l v Z8 ]3 f, R/ D, s: t: [控制IIC的通行频率 这两位检测IIC总线是否收到数据 6 m0 i. {2 ~9 B* \3 i+ ]# a
& G3 f$ T! C8 W5 B$ G# _" n7 Z o" j% Z o. n) h; Q8 m
% u* _; [- W9 ^" K/ U* U
" y. L. J9 C' Q* L& [1. 对于硬件IIC的初始化流程包括 1. 配置IO口,配置为GPIO_Mode_AF_OD模式 2. 选择IIC模式 3. 选择是否使能自动应答以及设备地址长度 4. 设置IIC总线的传输速率 2. 硬件IIC的读写操作其实逻辑上和标准总线类似,也是发送地址等待ack发送数据等待ACK,但是因为有硬件的自动参与,所以我们不需要延时了
" j* Z* ]% N# \5 ?/ k具体代码如下 - void HmcIICInit(void)& ?2 B! o. e/ v/ \
- {
% n M! w: ]7 r4 {3 U h& f - /*GPIO初始化*/# S& Y5 }3 E4 ?* b% z
- GPIO_InitTypeDef GPIO_InitStructure;% E- N8 q5 B& Y7 Y- O0 q1 j0 C
- /* 配置硬件IIC需要的变量 */
9 L: b/ ^; U9 G4 T/ l/ Q d: r - I2C_InitTypeDef I2C_InitStructure;
- i4 f# u. g4 W1 g5 O
2 u. L/ F8 s. B: s; l: O+ [. s2 }- /* 使能与 I2C1 有关的时钟 */; M; e' l9 R) e
- RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE ); / s0 |7 i& d% S5 T3 q; m
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE); 3 Q9 q- U6 j9 \, B; V4 p" @
- U, Z8 S1 E2 @; w2 `$ ]- l( q- /* PB6-I2C1_SCL、PB7-I2C1_SDA*/
/ t6 S) m/ h, q0 Z+ d4 q - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; ( o! `: H8 F" ` C
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 7 G: [# j: c- e5 V/ l9 Z
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
' K' k8 C( i# m/ T$ m& w - GPIO_Init(GPIOB, &GPIO_InitStructure); , L1 ~" k2 h: V* M
: m# o& }9 s6 B% Y- /*IIC外设初始化*/
8 g$ A6 g+ s$ Z2 W. b8 K - - r$ I* [+ e, D8 n& s) k
- /* I2C 配置 */. V- _& ~4 [3 X
- I2C_InitStructure.I2C_Mode = I2C_Mode_I2C ; //配置为普通IIC模式
. j/ D% a9 \, N2 ]6 E - //I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
W- B5 u+ V% L; C8 q - //I2C_InitStructure.I2C_OwnAddress1 = SlaveAddress; : A" f& Z$ G, A" G1 T$ O
- I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //使能自动应答
) x$ T! s; j, r, R3 t8 p - I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; J/ k t3 ^8 e' U, v8 K3 H1 v
- I2C_InitStructure.I2C_ClockSpeed = 50000; //5K的速度?0 d8 ?7 x! }+ j0 n7 b
5 m3 ] g7 z4 y, ~0 Z% x" R- ' `) ~. A5 R, t
- /* I2C1 初始化 */9 [ Z! R0 ?+ a" q2 O9 D
- I2C_Init(I2C1, &I2C_InitStructure);
% n% s$ |8 w) U2 I; {# x) B& E, o
9 `3 D1 q* g2 t5 H. A- /* 使能 I2C1 */
$ w k2 D6 J; l' n$ a& C+ h - I2C_Cmd (I2C1,ENABLE);
5 ~1 b6 f+ [# V+ H0 y% b. U - /*允许应答模式*/5 @8 B# ~* A5 x$ t
- I2C_AcknowledgeConfig(I2C1, ENABLE);
- W% O) Y* M2 R% E. \/ H - }( O2 T; `1 C* S$ X1 r' T
- 3 s X2 _+ w( d: j
- void HmcByteWrite(u8 addr,u8 dataValue)1 q2 A! ]5 c$ n1 v: K' `8 N
- {9 y, e& b. V9 M, V* o6 w. t
- I2C_GenerateSTART(I2C1,ENABLE);, H, G% v* K' F) ?3 [% w
3 W4 y$ i4 {- S) ~: i- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));, O6 V+ X& l7 L- b) z
- l# ]# v) d# O1 G
- I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);. t( P9 R& g7 R+ G
- / Z) [% ]% ^& @' c9 ]* l8 o
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));7 ], F. U: d! n' C( W8 k! x
0 x) J- f( P2 h( V( P4 o/ O7 {: p3 j- I2C_SendData(I2C1,addr);
2 s/ o+ a) x! i& t3 E* m! J
" m5 {- I6 \8 }( f" t5 Z# a- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));6 n4 @# X: K$ P
- # w7 r% K' p+ s# s/ c+ i
- I2C_SendData(I2C1,dataValue);3 x- M) J+ H( o
- 3 N$ P; M* f8 m/ _' J
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
3 _1 D8 i( t+ p& H - - o M* M4 i* E* f9 K3 ~4 S
- I2C_GenerateSTOP(I2C1,ENABLE);' [3 X4 P8 g% _: y
- : P- p, L) T9 K; Y8 p
- }5 t, p5 e+ P2 V% _: A
4 R. f* ~6 E( W- u8 HmcByteRead(u8 addr)9 x1 H: d( Q+ V& c9 Y) s
- {% {; x2 N( l3 r
- u8 dataValue;
4 j- A5 G2 N( ]3 r; n; J: N& B - % [ l: G% S+ u$ P4 r4 N2 }( h
- while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
4 r& c1 c- d$ ]7 W) G6 \ b) s - 1 t- G- j9 g. P: X0 C7 y
- I2C_GenerateSTART(I2C1,ENABLE);//起始信号! V4 b6 z& p/ S: ^! [4 S, a
* H% o; I% N; E: u8 ~8 O; f8 ]. L- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
7 X5 @# K0 p% w& |% \; h
9 z) q% j, P! S+ W2 c5 I( c1 j! C9 a, L- I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);//发送设备地址+写信号
( y' X) h, l0 m - 6 f+ Y! J1 S# p, ~
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
, ^+ h; p* [0 S% i - # b n$ m7 X- f
- I2C_Cmd(I2C1,ENABLE);* ~7 z/ p+ h- b5 [0 B
/ w, u. [* E5 ^: {- I2C_SendData(I2C1,addr);//发送存储单元地址,从0开始; f7 a- Y; O: Q# d2 v* V
- ; u5 W2 n, H8 y* W: |4 k) d
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
8 L- i- t6 u8 s6 J! P5 f6 ^3 l
- Q2 b$ ^/ y8 G0 d0 W) i- I2C_GenerateSTART(I2C1,ENABLE);//起始信号
( ]& A( e. Q( @ U+ ?5 p - 9 d( y" U$ l1 j& w K) t
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
7 d* U3 V' e* {" s+ g7 g8 Z - 4 [7 z: T4 s, ]# k* p- G# C
- I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Receiver);//发送设备地址+读信号
0 L: I9 M j9 i5 p2 E0 S5 R! V0 a3 b8 @ - $ n6 H8 X( t' o! s, y! B$ a
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
9 ]/ Z8 q0 T, |; G" G6 ?( ?% O
; A1 I/ O( J2 j! e0 {) m- I2C_AcknowledgeConfig(I2C1,DISABLE);
# Y' O$ s& T( o* x) \0 d2 l; f3 J2 ? - , k. q& m7 @, W' T* t ]
- I2C_GenerateSTOP(I2C1,ENABLE);
% ?5 i) M1 Y: G4 {( x6 R& T4 g - 9 Y- K) v x' m U2 \0 A( a
- while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)));9 Y* t# }+ n3 }1 H- {! {% P, n3 l
- * i" @' }. @# x- U! K3 q7 v
- dataValue=I2C_ReceiveData(I2C1);//读出寄存器数据2 N( g; G* I/ l: j8 t
2 K7 q z2 h7 N* ]- return dataValue;
" { p2 D: J M- [ - }
) T$ D+ v) b0 J, }& R4 s m - 4 f5 r+ d' ]0 I- k o# a
复制代码 " n" ]' Y, g) [
( }7 H8 n2 n0 Z' T- ?3 t% j% o |
66666