软件的IIC通讯

采用软件写IIC通讯,硬件写IIC是采用的特定的接口写的,但是软件的IIC就是采用的是任意两个引脚SCL和SDA引脚模拟IIC通讯

第一步先定义初始化的引脚

//初始化软件IIC
void IIC_Init()
{
	GPIO_InitTypeDef GPIO_Init_IIC;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_Init_IIC.GPIO_Mode = GPIO_Mode_AF_OD;
	GPIO_Init_IIC.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
	GPIO_Init_IIC.GPIO_Speed = GPIO_Speed_50MHz;
	
	GPIO_Init(GPIOA,&GPIO_Init_IIC);
	
	SCL_IIC_Set(); //SCL为1
	SDA_IIC_Set(); //SDA为1

	
}

初始化写完了就写启动IIC和停止IIC我们根据有IIC的时序写

//开启IIC
void IIC_Start(void)
{
	SCL_IIC_Set(); 
	SDA_IIC_Set();
	delay_us(1);
	SDA_IIC_Reset();
	delay_us(1);
  SCL_IIC_Reset();
	delay_us(1);
}
//关闭IIC
void IIC_Stop(void)
{
    SDA_IIC_Reset();
	delay_us(1);
	SCL_IIC_Set(); 
	delay_us(1);
	SDA_IIC_Set();
	delay_us(1);
}

下一步就是写应答重占的应答,一定要记住为1是没有应答,也是看时序写程序

unsigned char IIC_Ack(void)
{
	unsigned char Ack = 0;
	SCL_IIC_Reset();
	delay_us(1);
	SDA_IIC_Set();
	delay_us(1);
	SCL_IIC_Set();
	delay_us(1);
	if(SDA_IIC_ACK())//读取SDA有没有应答
	{
		Ack = IIC_ACK;
	}
	else
	{
		Ack = IIC_NO_ACK;
	}
	SCL_IIC_Reset();
	delay_us(1);
	return Ack;
}

下面写读取函数根据以下时序写,注意写命令是0x00,写数据是0x40。

//IIC读取一个字节
void IIC_Read_Byte(unsigned char Byte)
{
	unsigned char i;
	for(i=0;i<8;i++)
	{
		SCL_IIC_Reset();
		delay_us(1);
		if(Byte&0x80)
		{
			SDA_IIC_Set();
		}
		else
		{
			SDA_IIC_Reset();
		}
		delay_us(1);
		SCL_IIC_Reset();
		delay_us(1);
		Byte<<=1;
	}
	SCL_IIC_Reset();
	delay_us(1);
	IIC_Ack();
}

//IIC写命令
void IIC_Write_Byte(unsigned char IIC_Cmd)
{
	IIC_Start();
	IIC_Read_Byte(0x78);
	IIC_Read_Byte(0x00);
	IIC_Read_Byte(IIC_Cmd);
	IIC_Stop();
}

//IIC写数据
void IIC_Write_Data(unsigned char Data)
{
	IIC_Start();
	IIC_Read_Byte(0x78);
	IIC_Read_Byte(0x40);
	IIC_Read_Byte(Data);
	IIC_Stop();
}

当涉及到软件I2C通讯时,你可以使用C语言编写以下代码来实现两个单片机之间的通讯。 首先,你需要定义I2C通讯所需的引脚和相关参数。例如,你可以定义SDA和SCL引脚的端口和引脚号,以及I2C通讯的速率等。 ```c #include <avr/io.h> #define F_CPU 8000000UL // 设置CPU频率为8 MHz #define SDA_PORT PORTC #define SDA_PIN PC0 #define SCL_PORT PORTC #define SCL_PIN PC1 #define I2C_SPEED 100000 // 设置I2C通讯速率为100kHz #define I2C_READ 1 #define I2C_WRITE 0 void I2C_Init() { // 设置SDA和SCL引脚为输出模式 DDRC |= (1 << SDA_PIN); DDRC |= (1 << SCL_PIN); // 设置I2C通讯速率 TWBR = ((F_CPU / I2C_SPEED) - 16) / 2; } void I2C_Start() { // 发送起始信号 TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN); // 等待起始信号发送完成 while (!(TWCR & (1 << TWINT))); } void I2C_Stop() { // 发送停止信号 TWCR = (1 << TWINT) | (1 << TWSTO) | (1 << TWEN); } void I2C_Write(uint8_t data) { // 写入数据到I2C总线 TWDR = data; TWCR = (1 << TWINT) | (1 << TWEN); // 等待数据发送完成 while (!(TWCR & (1 << TWINT))); } uint8_t I2C_Read(uint8_t ack) { // 从I2C总线读取数据 TWCR = (1 << TWINT) | (1 << TWEN) | (ack << TWEA); // 等待数据接收完成 while (!(TWCR & (1 << TWINT))); return TWDR; } ``` 然后,在两个单片机的主程序中,你可以使用上述函数来实现I2C通讯。一个单片机作为主设备(例如单片机A),另一个作为从设备(例如单片机B)。以下是一个简单的示例: ```c #include <avr/io.h> #include <util/delay.h> int main() { // 初始化I2C通讯 I2C_Init(); // 主设备发送数据到从设备 I2C_Start(); I2C_Write(0x50); // 发送从设备地址 I2C_Write(0x01); // 发送数据 I2C_Stop(); // 延时等待从设备处理 // 从设备接收主设备发送的数据 I2C_Start(); I2C_Write(0x51); // 发送主设备地址,读取模式 uint8_t receivedData = I2C_Read(0); I2C_Stop(); // 处理接收到的数据 while (1) { // 主程序循环 } } ``` 在从设备的主程序中,你可以参考上述代码,并做适当调整来实现从设备接收主设备发送的数据。 请注意,以上代码是一个简单的示例,实际应用中可能需要根据具体的硬件和需求进行适当的修改和扩展。同时,也需要确保两个单片机的I2C通讯参数和引脚配置是一致的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值