STM32 软件模拟IIC/I2C 完成寻址、读、写、按页写等操作

本文详细介绍了如何使用STM32软件模拟IIC通信协议,包括初始化、信号控制、读写操作以及寻址功能。通过示例展示了如何进行按页写入和读取数据,并提供了完整的IIC相关函数实现。此外,还展示了如何搜索总线上挂载的从设备地址。

STM32 软件模拟IIC/I2C 完成寻址、读、写、按页写等操作

使用STM32 模拟IIC进行通信,相较于自带硬件接口稳定。
寻址:想要知道总线上挂载的从机数量及其地址,需要在总线写地址,如果相应位有应答,器件地址
(地址位为7位)左移一位低位补0进行显示,无应答位使用“–”替代。

实际运行效果: (显示效果类似于树莓派,树莓派显示原7位地址,高位补0)效果
按页写完读(主函数示例):从0x00地址开始,依次写入17个字节(数组已定义赋值,非赋值数组最好放在函数外做为全局变量,这样默认初始值就为0,而在函数内则为随机值),16个字节为1页,写完1页数据保存进非易失区后,继续写入剩余字节。从0x00地址开始,依次读出17个字节。

iic.c

IIC为半双工通信,数据线SDA既用作于发又用作于收但是不能同时进行,而STM32不同于51类单片机的是,IO脚需要配置输入输出模式,所以在用IO模拟IIC时STM32比51多两个函数:
IIC_SDA_IN();IIC_SDA_OUT();

因为有些例程中通过寄存器配置的方式转换IO输入输出,不是太理解,所以改用库函数进行配置。
#include "firmware.h"//里面包含iic.h

void IIC_Init(void)
{
   
    
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE );//时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;//SDA SCL WP
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ; //
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOF, &GPIO_InitStructure); //
	GPIO_SetBits(GPIOF,GPIO_Pin_0 | GPIO_Pin_1); //
}

void IIC_SDA_IN(void)//SDA用作输入:从机返回数据,从机应答等
{
   
   
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN ; //
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOF, &GPIO_InitStructure); 	
}

void IIC_SDA_OUT(void)//SDA用作输出:写地址,写数据等
{
   
   
	GPIO_InitTypeDef GPIO_InitStructure;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT ; //
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
	GPIO_Init(GPIOF, &GPIO_InitStructure); 	
}


void IIC_Start(void)//开始信号
{
   
   
	IIC_SDA_OUT(); //SDA定义为输出
	IIC_SDA = 1; 
	IIC_SCL = 1;
	delay_us(4);
	IIC_SDA = 0;  
	delay_us(4);
	IIC_SCL = 0; 
} 

void IIC_Stop(void)//停止信号
{
   
   
	IIC_SDA_OUT(); //SDA定义为输出
	IIC_SCL = 0;
	IIC_SDA = 0; 
	delay_us(4);
	IIC_SCL = 1; 
	delay_us(4);
	IIC_SDA = 1; //发送 I2C 总线结束信号
	delay_us(4); 
}

u8 IIC_Wait_Ack(void)//等待应答信号:0-应答;1-非应答
{
   
   
	u8 ack = 0;
	IIC_SDA = 1;
	IIC_SDA_IN(
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值