当前位置: 首页> 教育> 就业 > stm32实现IIC读写

stm32实现IIC读写

时间:2025/7/21 17:37:30来源:https://blog.csdn.net/m0_46145044/article/details/140287693 浏览次数:0次

IIC.c

#include "Driver_I2C2.h"
#include "Delay.h"#define I2C_DELAY Delay_us(10)/*** @description: 初始化* @return {*}*/
void Driver_I2C2_Init(void)
{/*PB10->SCLPB11->SDA开漏输出: 既可以用于输出也可以输入. 外界要有上拉电阻.用于输入的时候,最好先输出一个1,把线的控制权交给外界.MODE=11 CNF=01*/RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;GPIOB->CRH |= (GPIO_CRH_MODE10 | GPIO_CRH_MODE11 | GPIO_CRH_CNF10_0 | GPIO_CRH_CNF11_0);GPIOB->CRH &= ~(GPIO_CRH_CNF10_1 | GPIO_CRH_CNF11_1);
}/*** @description: 起始信号* @return {*}*/
void Driver_I2C2_Start(void)
{/* 1. 拉高sda和scl */SDA_HIGH;SCL_HIGH;/* 2. 延时 */I2C_DELAY;/* 3. 拉低sda */SDA_LOW;/* 4. 延时 */I2C_DELAY;
}/*** @description: 停止信号* @return {*}*/
void Driver_I2C2_Stop(void)
{/* 1. scl 拉高 sda拉低 */SCL_HIGH;SDA_LOW;/* 2. 延时 */I2C_DELAY;/* 3. 拉高sda */SDA_HIGH;/* 4.  延时 */I2C_DELAY;
}/*** @description: 接收方产生应答信号*/
void Driver_I2C2_Ack(void)
{/* 1. 拉高sda和拉低scl */SDA_HIGH;SCL_LOW;/* 2. 延时 */I2C_DELAY;/* 3. sda拉低 */SDA_LOW;/* 4. 延时 */I2C_DELAY;/* 5. scl拉高 */SCL_HIGH;/* 6. 延时 */I2C_DELAY;/* 7. scl拉低 */SCL_LOW;/* 8. 延时 */I2C_DELAY;/* 9. sda 拉高 */SDA_HIGH;/* 10. 延时 */I2C_DELAY;
}/*** @description: 接收方产生非应答信号*/
void Driver_I2C2_NAck(void)
{/* 1. 拉高sda和拉低scl */SDA_HIGH;SCL_LOW;/* 2. 延时 */I2C_DELAY;/* 3. scl拉高 */SCL_HIGH;/* 4. 延时 */I2C_DELAY;/* 5. scl拉低*/SCL_LOW;/* 6. 延时 */I2C_DELAY;
}/*** @description: 等待接收方法的应答* @return {*} 应答或非应答*/
uint8_t Driver_I2C2_WaitAck(void)
{/* 1. 把sda拉高, sda的主动权交给对方(e2prom芯片) */SDA_HIGH;/* 2. scl拉低  */SCL_LOW;/* 3. 延时 */I2C_DELAY;/* 4. 拉高scl */SCL_HIGH;/* 5. 延时 */I2C_DELAY;/* 6. 读取sda的电平 */uint8_t ack = ACK;if (READ_SDA){ack = NACK;}/* 7. 拉低scl */SCL_LOW;/* 8. 延时 */I2C_DELAY;return ack;
}/*** @description: 发送一个字节的数据* @param {uint8_t} byte 要发送的字节*/
void Driver_I2C_SendByte(uint8_t byte)
{for (uint8_t i = 0; i < 8; i++){/* 1. sda和scl 拉低 */SDA_LOW;SCL_LOW;I2C_DELAY;/* 2. 向sda写数据 */if (byte & 0x80){SDA_HIGH;}else{SDA_LOW;}I2C_DELAY;/* 3. 时钟拉高 */SCL_HIGH;I2C_DELAY;/* 4. 时钟拉低 */SCL_LOW;I2C_DELAY;/* 5. 左移1位, 为下一次发送做准备 */byte <<= 1;}
}/*** @description: 读一个字节的数据* @param {uint8_t} byte 要发送的字节*/
uint8_t Driver_I2C_ReadByte(void)
{uint8_t data = 0;for (uint8_t i = 0; i < 8; i++){/* 1. 拉低scl */SCL_LOW;/* 2. 延时 */I2C_DELAY;/* 3. 拉高scl */SCL_HIGH;/* 4. 延时 */I2C_DELAY;/* 5. 读取sda */data <<= 1;if (READ_SDA){data |= 0x01;}/* 6. 拉低scl */SCL_LOW;/* 7. 延时 */I2C_DELAY;}return data;
}

IIC.h

#ifndef __DRIVER_I2C2_H
#define __DRIVER_I2C2_H#include "Delay.h"
#include "stm32f10x.h"
#include "Driver_USART.h"#define ACK 0
#define NACK 1#define SCL_HIGH  (GPIOB->ODR |= GPIO_ODR_ODR10)
#define SCL_LOW  (GPIOB->ODR &= ~GPIO_ODR_ODR10)#define SDA_HIGH  (GPIOB->ODR |= GPIO_ODR_ODR11)
#define SDA_LOW  (GPIOB->ODR &= ~GPIO_ODR_ODR11)#define READ_SDA (GPIOB->IDR & GPIO_IDR_IDR11)void Driver_I2C2_Init(void);void Driver_I2C2_Start(void);void Driver_I2C2_Stop(void);void Driver_I2C2_Ack(void);void Driver_I2C2_NAck(void);uint8_t Driver_I2C2_WaitAck(void);void Driver_I2C_SendByte(uint8_t byte);uint8_t Driver_I2C_ReadByte(void);#endif

读写操作

Inf_W24C02.c

#include "Inf_W24C02.h"void Inf_W24C02_Init(void)
{Driver_I2C2_Init();
}void Inf_W24C02_WriteByte(uint8_t innerAddr, uint8_t byte)
{/* 1. 开始信号 */Driver_I2C2_Start();/* 2. 发送写地址 */Driver_I2C_SendByte(ADDR);/* 3. 等待响应 */uint8_t ack = Driver_I2C2_WaitAck();if (ack == ACK){/* 4. 发送内部地址 */Driver_I2C_SendByte(innerAddr);/* 5. 等待响应 */Driver_I2C2_WaitAck();/* 6. 发送具体数据 */Driver_I2C_SendByte(byte);/* 7. 等待响应 */Driver_I2C2_WaitAck();/* 8. 停止信号 */Driver_I2C2_Stop();}Delay_ms(5);
}uint8_t Inf_W24C02_ReadByte(uint8_t innerAddr)
{/* 1. 起始信号 */Driver_I2C2_Start();/* 2. 发送一个写地址   假写 */Driver_I2C_SendByte(ADDR);/* 3. 等待响应 */Driver_I2C2_WaitAck();/* 4. 发送内部地址 */Driver_I2C_SendByte(innerAddr);/* 5. 等待响应 */Driver_I2C2_WaitAck();/* 6. 起始信号 */Driver_I2C2_Start();/* 7. 发送读地址  真读 */Driver_I2C_SendByte(ADDR + 1);/* 8. 等待响应 */Driver_I2C2_WaitAck();/* 9. 读取一个字节 */uint8_t byte = Driver_I2C_ReadByte();/* 10. 给对方一个非应答 */Driver_I2C2_NAck();/* 11. 停止信号 */Driver_I2C2_Stop();return byte;
}/*** @description: 页写入.一次写入多个字节* @param {uint8_t} innerAddr* @param {uint8_t} *bytes* @param {uint8_t} len* @return {*}*/
void Inf_W24C02_WriteBytes(uint8_t innerAddr, uint8_t *bytes, uint8_t len)
{/* 1. 开始信号 */Driver_I2C2_Start();/* 2. 发送写地址 */Driver_I2C_SendByte(ADDR);/* 3. 等待响应 */uint8_t ack = Driver_I2C2_WaitAck();if (ack == ACK){/* 4. 发送内部地址 */Driver_I2C_SendByte(innerAddr);/* 5. 等待响应 */Driver_I2C2_WaitAck();for (uint8_t i = 0; i < len; i++){/* 6. 发送具体数据 */Driver_I2C_SendByte(bytes[i]);/* 7. 等待响应 */Driver_I2C2_WaitAck();}/* 8. 停止信号 */Driver_I2C2_Stop();}Delay_ms(5);
}/*** @description: 一次性读取多个字节的数据* @param {uint8_t} innerAddr 起始位置* @param {uint8_t} *bytes 存储读到的数据* @param {uint8_t} len 读取的字节数* @return {*}*/
void Inf_W24C02_ReadBytes(uint8_t innerAddr, uint8_t *bytes, uint8_t len)
{/* 1. 起始信号 */Driver_I2C2_Start();/* 2. 发送一个写地址   假写 */Driver_I2C_SendByte(ADDR);/* 3. 等待响应 */Driver_I2C2_WaitAck();/* 4. 发送内部地址 */Driver_I2C_SendByte(innerAddr);/* 5. 等待响应 */Driver_I2C2_WaitAck();/* 6. 起始信号 */Driver_I2C2_Start();/* 7. 发送读地址  真读 */Driver_I2C_SendByte(ADDR + 1);/* 8. 等待响应 */Driver_I2C2_WaitAck();for (uint8_t i = 0; i < len; i++){/* 9. 读取一个字节 */bytes[i] = Driver_I2C_ReadByte();if (i < len - 1){Driver_I2C2_Ack();}else{Driver_I2C2_NAck();}}/* 11. 停止信号 */Driver_I2C2_Stop();
}void Inf_W24C02_WriteBytesAutoPage(uint8_t innerAddr, uint8_t *bytes, uint8_t len)
{// 不需要自动换页if ((innerAddr % 16) + len <= 16){Inf_W24C02_ReadBytes(innerAddr, bytes, len);return;}// 需要换页处理//uint8_t apge = (len - innerAddr % 16) / 16 + 1  ;// 一共需要page页}

Inf_W24C02.h

#ifndef __INF_W24C02_H
#define __INF_W24C02_H#include "Driver_I2C2.h"
#include "string.h"#define ADDR 0xA0
void Inf_W24C02_Init(void);
void Inf_W24C02_WriteByte(uint8_t innerAddr, uint8_t byte);uint8_t Inf_W24C02_ReadByte(uint8_t innerAddr);void Inf_W24C02_WriteBytes(uint8_t innerAddr, uint8_t *bytes, uint8_t len);void Inf_W24C02_ReadBytes(uint8_t innerAddr, uint8_t *bytes, uint8_t len);#endif
关键字:stm32实现IIC读写

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: