|
Stm32具有IIC接口,接口有以下主要特性 多主机功能:该模块既可做主设备也可做从设备 主设备功能 C地址检测 产生和检测7位/10位地址和广播呼叫 支持不同的通讯速度 状态标志: 发送器/接收器模式标志 字节发送结束标志 总线忙标志 错误标志 2个中断向量 可选的拉长时钟功能 具单字节缓冲器的DMA 虽然很多人说STM的硬件IIC不好用,但是对于这么一个设备去探索一下还是很有必要的,指不定哪天就用上了呢, IIC借口一共有九个寄存器,比较重要的几个寄存器分别如下 7 L) V+ R3 L" M: ~0 w+ p2 x
1. CR1 * `# P0 O7 |3 s( d
5 n$ s1 n! m/ Z1 m4 @% F \由这几个位我们可以正常产生标准IIC的START条件STOP条件,ACK与NOACK
: {4 D. A0 G( X8 v: d
CR2
( w' P, |7 S: d* u% d3 k
4 j5 Q, p- j4 Y% Q
控制IIC的通行频率 这两位检测IIC总线是否收到数据 
( Q' s- v+ P' _0 ^& [) A ! L6 \7 I7 ?# R7 M1 p
$ O+ q5 u4 {& ^( x. V7 d/ N( Y7 y
' m% v# D$ t6 A$ ]) a3 u# N7 s( f- c" a1 P% N4 g
1. 对于硬件IIC的初始化流程包括 1. 配置IO口,配置为GPIO_Mode_AF_OD模式 2. 选择IIC模式 3. 选择是否使能自动应答以及设备地址长度 4. 设置IIC总线的传输速率 2. 硬件IIC的读写操作其实逻辑上和标准总线类似,也是发送地址等待ack发送数据等待ACK,但是因为有硬件的自动参与,所以我们不需要延时了 9 y/ e2 Y1 A; c5 ?
具体代码如下 - void HmcIICInit(void)7 [9 k1 O1 s% W, A( ^1 _
- {
$ ] T, j7 ?+ ?" a5 `+ @ - /*GPIO初始化*/
9 C" Z% H) E! R# h$ m' V7 f - GPIO_InitTypeDef GPIO_InitStructure;; t$ k- L# n, S- x( x( c
- /* 配置硬件IIC需要的变量 */
4 K" J' Z9 \& H/ ~0 r3 T - I2C_InitTypeDef I2C_InitStructure;
; f5 W* C( _$ \- P: T# o" s - 9 x, A, R$ o$ C0 `
- /* 使能与 I2C1 有关的时钟 */
4 S: U9 j1 J$ F+ `8 P - RCC_APB2PeriphClockCmd (RCC_APB2Periph_GPIOB,ENABLE );
/ N" E4 ^' Z$ m' G8 |; I - RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
0 I, F! g3 o9 K6 b& ?
) V+ p6 @( W1 B5 T* _- /* PB6-I2C1_SCL、PB7-I2C1_SDA*/
1 ?7 U# ^- x. p) [ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
1 \1 v2 a$ F1 c5 c+ H( } - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
5 H) c. |' G5 B& z - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
7 ]) l6 N) Z6 l( H4 e( W& d2 W - GPIO_Init(GPIOB, &GPIO_InitStructure); 1 \. P8 W0 g) }8 ^& Q+ Y
. \# `% X5 E% ]% q1 `- /*IIC外设初始化*/
" D" ^0 [: p* w+ W' C" c0 ?4 B
! f) M6 d" ^) O% G- /* I2C 配置 */
( f: Z: J6 j% i3 A! B4 T+ E! h3 \ - I2C_InitStructure.I2C_Mode = I2C_Mode_I2C ; //配置为普通IIC模式
+ Z, z% a/ ?$ x - //I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
; N; W4 C4 s" T7 C8 Y7 V" U& Z" t7 F - //I2C_InitStructure.I2C_OwnAddress1 = SlaveAddress; # U! N; `* t, l! P, z/ f! ~
- I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //使能自动应答
7 s# ~4 ]0 u/ q& z1 g$ Q - I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
, C0 v5 D* m3 h1 e3 J& \2 u - I2C_InitStructure.I2C_ClockSpeed = 50000; //5K的速度?1 P) p+ n3 i& ` i
- # |& N+ [/ { V$ C/ q# \2 |1 J
# I4 ?+ f, \" K( B' l- /* I2C1 初始化 */
( W9 ]2 A' A1 [: o* L/ G - I2C_Init(I2C1, &I2C_InitStructure);
8 i7 {) h" } A9 i$ b7 J5 B - / i( @ X" O% C) ]
- /* 使能 I2C1 */3 h3 q9 i' U" ^0 z& P* c8 ?% v( a
- I2C_Cmd (I2C1,ENABLE); # H, h& j0 I: j z' T* r
- /*允许应答模式*/
0 \9 C A; y1 F - I2C_AcknowledgeConfig(I2C1, ENABLE);
* y2 i, B% S1 `: L - }
! L2 |5 b7 [2 n. O: Z* z z9 c Z - 7 G" r. }1 t. r: b
- void HmcByteWrite(u8 addr,u8 dataValue)
, T! v) ]3 O) x9 A1 L. R2 p- |: g- s - {4 i+ ~' y/ u/ Z! G5 K
- I2C_GenerateSTART(I2C1,ENABLE);7 k" |! m. D8 I
- 2 T1 ?8 {' z. i3 `/ D: j
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));, J/ q+ o( B- j# J% A Y, G4 q
- X' e- e9 T$ t. c7 }& F
- I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);
! h( d# I( p7 @* R" {% K - 0 @, \9 H. ^8 \: K1 d
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
# m9 k; [5 }9 P) k. j- z+ c - , r R- i" t l4 g% F, ]
- I2C_SendData(I2C1,addr);
& U$ C. e" O/ p, I8 v
* D T! z& h3 |+ h( Z, d- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
* \4 |+ a2 u+ @8 c - 2 D5 p; a: c6 s) u- G/ h9 l% |
- I2C_SendData(I2C1,dataValue);
7 x0 z! e% p) j# w( F" W# L
8 B+ T/ R3 _3 e6 G% E4 { c- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
9 B& r! d" N2 [4 ~) i% a
* [. v5 E- w9 c. M$ b% W! l# w- I2C_GenerateSTOP(I2C1,ENABLE);- j* ^! P! ?# m7 n8 F; G7 U4 z
, Y& n1 t3 D+ T5 A, [4 n- }
# m _9 ?6 [0 [8 k' {! w - ) n5 W$ P" \( Z! d5 {
- u8 HmcByteRead(u8 addr)6 Q+ u1 i, J- J |0 T
- {
3 g$ e: v. ]# O3 {) |9 }6 N - u8 dataValue;) R8 L' q' E( o1 t; `4 O+ ~
- 5 M9 a: _3 C- b$ ^
- while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
) }8 f/ [2 N y5 ?/ |4 |) b4 s
- {- h4 u2 E/ N. f. D) ?9 d n- I2C_GenerateSTART(I2C1,ENABLE);//起始信号
+ W2 Z n& q8 l8 i. g0 S# a( ]
5 @1 p. M1 r, t- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));) A, ` H( h, B1 @
- H" k4 i9 F& G; V$ k2 v7 [+ h
- I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Transmitter);//发送设备地址+写信号
: A6 } L5 Z+ P- U! S - ( h2 m) w( P, ]
- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//
4 M# w) b, k5 h8 k1 L6 m- {; ` - 4 S* u& z `# F$ K
- I2C_Cmd(I2C1,ENABLE);
3 \# u7 j x0 ~- E% P - # U! k. F1 E( ]/ v' F& Z
- I2C_SendData(I2C1,addr);//发送存储单元地址,从0开始
2 X5 U }& A& h) k: W5 q; K
, F1 }7 v: n/ \7 J# y- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED));
& m8 h1 F# F' q+ e6 Z/ w0 f8 U
. j0 D6 l' S( k7 ]1 |9 c- I2C_GenerateSTART(I2C1,ENABLE);//起始信号
. C! m4 p+ m2 c' D, W6 T9 f$ Z
7 Z; Q- i: I. ` y, a' j1 S, T- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));
! q& ~) e5 }0 P; U+ r7 E" W/ ~
7 @9 R9 C' g0 J( ]- I2C_Send7bitAddress(I2C1,HMC_ADDR,I2C_Direction_Receiver);//发送设备地址+读信号
% v* [, v x! Y. L9 s
6 X7 @$ W9 ~" l8 L$ K# V- while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/ ]+ t0 Y. a+ i9 I - 4 D7 \& s) W9 Z) a9 m, {: a
- I2C_AcknowledgeConfig(I2C1,DISABLE);
! p& H9 R/ p8 @1 W4 G) n# R1 V/ k - ( n/ D- L5 f% E
- I2C_GenerateSTOP(I2C1,ENABLE); s1 h1 O9 c. Q3 T: ?4 k8 }
1 {0 U- k! I; E& I- while(!(I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED)));
+ w5 J$ l% z1 o# U5 z
% o' G! i+ D9 k' @* ~7 P7 x# _- dataValue=I2C_ReceiveData(I2C1);//读出寄存器数据
2 e$ e! n" e( N2 T% P - 1 b1 E9 U' S, s G
- return dataValue;! s- K" @6 X& \* } K7 B! W% @7 ^
- }
: [ h+ P' e! D) w" P b# f& g - ( \, A% v2 v. }% r# P: F& s
复制代码
1 h/ v# ?2 u& E) v
' Z" k9 x" m4 u0 m |
66666