STM32学习笔记之--软件模拟IIC总线

软件模拟IIC总线通信

一、起始与停止信号
起始信号指在SCL高电平期间SDA出现一个下跳沿信号,停止信号则指在SCL高电平期间SDA出现一个上跳沿信号。

时序图
起始信号
停止信号
二、数据传输的有效性
在利用IIC总线协议进行通信时,仅当SCL为高电平期间SDA数据有效且不能发生变化,在SCL低电平期间SDA数据无效,SDA可进行数据的变化。
数据有效性
三、CPU向总线设备发送数据
① 将等待发送的数据_ucByte与0x80进行位与操作得出最高位的数据
② 得到SDA后将SCL拉高一定时间再拉低
③ 将_ucByte左移1位再与0x80进行位与操作,循环8次后传输完成释放总线。*************************************************
4 * 函 数 名: i2c_SendByte
5 * 功能说明: CPU 向 I2C 总线设备发送 8bit 数据
6 * 形 参: _ucByte : 等待发送的字节
7 * 返 回 值: 无
8 *************************************************
9 /
10 void i2c_SendByte(uint8_t _ucByte)
11 {
12 uint8_t i;
13
14 /
先发送字节的高位 bit7 /
15 for (i = 0; i < 8; i++) {
16 if (_ucByte & 0x80) {
17 EEPROM_I2C_SDA_1(); //将SDA置1
18 } else {
19 EEPROM_I2C_SDA_0(); //将SDA清零
20 }
21 i2c_Delay();
22 EEPROM_I2C_SCL_1();
23 i2c_Delay();
24 EEPROM_I2C_SCL_0();
25 if (i == 7) {
26 EEPROM_I2C_SDA_1(); // 释放总线
27 }
28 _ucByte <<= 1; /
左移一个 bit /
29 i2c_Delay();
30 }
31 }
四、CPU从IIC总线设备读取数据
① Value左移一位用来放置第i位数据。
② EEPROM_I2C_SDA_READ()用来读取总线上SDA的状态如果为高电平,则Value=1否则Value=0。
③ 数据读取完成后将SCL拉低,并返回Value的值。
34 **********************************************
35 * 函 数 名: i2c_ReadByte
36 * 功能说明: CPU 从 I2C 总线设备读取 8bit 数据
37 * 形 参:无
38 * 返 回 值: 读到的数据
39 **********************************************
41 uint8_t i2c_ReadByte(void)
42 {
43 uint8_t i;
44 uint8_t value;
45
46 /
读到第 1 个 bit 为数据的 bit7 /
47 value = 0;
48 for (i = 0; i < 8; i++) {
49 value <<= 1;
50 EEPROM_I2C_SCL_1();
51 i2c_Delay();
52 if (EEPROM_I2C_SDA_READ()) {
53 value++;
54 }
55 EEPROM_I2C_SCL_0();
56 i2c_Delay();
57 }
58 return value;
59 }
五、应答信号
① CPU释放总线后由从机设备控制
② CPU读取SDA数据并返回相应的数据。
************************************************
4 * 函 数 名: i2c_WaitAck
5 * 功能说明:
6 CPU 产生一个时钟,并读取器件的 ACK 应答信号
7 * 形 参:无
8 * 返 回 值: 返回 0 表示正确应答, 1 表示无器件响应
9 *************************************************
10 /
11 uint8_t i2c_WaitAck(void)
12 {
13 uint8_t re;
14
15 EEPROM_I2C_SDA_1(); /
CPU 释放 SDA 总线 /
16 i2c_Delay();
17 EEPROM_I2C_SCL_1(); /
CPU 驱动 SCL = 1,
18 此时器件会返回 ACK 应答 /
19 i2c_Delay();
20 if (EEPROM_I2C_SDA_READ()) { /
CPU 读取 SDA 口线状态 /
21 re = 1;
22 } else {
23 re = 0;
24 }
25 EEPROM_I2C_SCL_0();
26 i2c_Delay();
27 return re;
28 }
29
30 /

31 ************************************************
32 * 函 数 名: i2c_Ack
33 * 功能说明: CPU 产生一个 ACK 信号
34 * 形 参:无
35 * 返 回 值: 无
36 ************************************************
37 /
38 void i2c_Ack(void)
39 {
40 EEPROM_I2C_SDA_0(); /
CPU 驱动 SDA = 0 /
41 i2c_Delay();
42 EEPROM_I2C_SCL_1(); /
CPU 产生 1 个时钟 /
43 i2c_Delay();
44 EEPROM_I2C_SCL_0();
45 i2c_Delay();
46 EEPROM_I2C_SDA_1(); /
CPU 释放 SDA 总线 /
47 }
48
49 /

50 **********************************************
51 * 函 数 名: i2c_NAck
52 * 功能说明: CPU 产生 1 个 NACK 信号
53 * 形 参:无
54 * 返 回 值: 无
55 **********************************************
56 /
57 void i2c_NAck(void)
58 {
59 EEPROM_I2C_SDA_1(); /
CPU 驱动 SDA = 1 /
60 i2c_Delay();
61 EEPROM_I2C_SCL_1(); /
CPU 产生 1 个时钟 */
62 i2c_Delay();
63 EEPROM_I2C_SCL_0();
64 i2c_Delay();
65 }

猜你喜欢

转载自blog.csdn.net/weixin_44712171/article/details/105429862