STM32——IIC通信

admin2024-07-03  30

IIC协议代码:

/*-------------------------------------------------*/
/*                                                 */
/*            实现IIc总线功能的源文件              */
/*                                                 */
/*-------------------------------------------------*/

#include "stm32f10x.h"  //包含需要的头文件
#include "delay.h"      //包含需要的头文件
#include "iic.h"        //包含需要的头文件

/*-------------------------------------------------*/
/*函数名:初始化IIC接口                            */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void IIC_Init(void)
{			
	GPIO_InitTypeDef  GPIO_InitStructure;                      //定义一个设置IO的变量

	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );    //使能GPIOB时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;    //准备设置PB6 PB7
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;           //推免输出方式  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;          //IO速率50M
	GPIO_Init(GPIOB, &GPIO_InitStructure);                     //设置PB6 PB7
	
	IIC_SCL_H;   //SCL拉高
	IIC_SDA_H;   //SDA拉高
}
/*-------------------------------------------------*/
/*函数名:IIC起始信号                              */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void IIC_Start(void)
{
	SDA_OUT();     //SDA线输出模式
    IIC_SDA_H;	   //SDA拉高  
	IIC_SCL_H;     //SCL拉高	  
	Delay_Us(4);   //延时
 	IIC_SDA_L;     //SCL高电平的时候,SDA由高到低,起始信号
}
/*-------------------------------------------------*/
/*函数名:IIC停止信号                              */
/*参  数:无                                       */
/*返回值:无                                       */
/*-------------------------------------------------*/
void IIC_Stop(void)
{
	SDA_OUT();     //SDA线输出模式
	IIC_SDA_L;     //SDA拉低
	IIC_SCL_H;     //SCL拉高
 	Delay_Us(4);   //延时
	IIC_SDA_H;     //SCL高电平的时候,SDA由低到高,发出停止信号					   	
}
/*-------------------------------------------------*/
/*函数名:等待应答                                 */
/*参  数:无                                       */
/*返回值:0:成功  1:失败                         */
/*-------------------------------------------------*/
char IIC_Wait_Ack(void)
{
	unsigned char timeout=0; //定义一个变量,用于计算超时时间
	
	IIC_SDA_H;	             //SDA拉高
	SDA_IN();                //SDA线输入模式 
	IIC_SCL_H;	             //SCL拉高
	 
	while(READ_SDA){         //等待SDA变低电平,表示应答到来,不然一直while循环,直到超时	
		timeout++;           //超时计数+1
		if(timeout>250){     //如果大于250	
			IIC_Stop();      //发送停止信号
			return 1;        //返回1,表示失败
		}
		Delay_Us(2);         //延时
	}
	IIC_SCL_L;               //SCL拉低
	Delay_Us(20);            //延时	
	return 0;                //返回0,表示成功
} 	
/*-------------------------------------------------*/
/*函数名:发送一个字节                             */
/*参  数:txd:发送的字节                          */
/*返回值:无                                       */
/*-------------------------------------------------*/ 			  
void IIC_Send_Byte(unsigned char txd)
{                        
    unsigned char t;                   //定义一个变量用于for循环 
	
	SDA_OUT(); 	                       //SDA线输出模式 
    IIC_SCL_L;                         //SCL拉低,开始数据传输
    for(t=0;t<8;t++){                  //for循环,一位一位的发送,从最高位 位7开始                 
        IIC_SDA_OUT(((txd&0x80)>>7));  //给SDA数据线
        txd<<=1; 	                   //左移一位,准备下一次发送
		Delay_Us(2);                   //延时
		IIC_SCL_H;                     //SCL拉高
		Delay_Us(2);                   //延时
		IIC_SCL_L;	                   //SCL拉低
    }	 
} 	    
/*-------------------------------------------------*/
/*函数名:读取一个字节                             */
/*参  数:ack:是否发送应答 1:发 0:不发           */
/*返回值:读取的数据                               */
/*-------------------------------------------------*/   
unsigned char IIC_Read_Byte(unsigned char ack)
{
	unsigned char i;           //定义一个变量用于for循环 
	unsigned char receive;     //定义一个变量用于保存接收到的数据
		
	receive = 0;               //清除receive,准备接收数据
	SDA_IN();                  //SDA设置为输入
    IIC_SCL_L;                 //SCL拉低
    Delay_Us(20);               //延时	
	for(i=0;i<8;i++){          //for循环,一位一位的读取	 
		IIC_SCL_H;             //SCL拉高 
		Delay_Us(20);           //延时
        receive<<=1;           //左移一位,准备下次的读取
        if(READ_SDA)receive++; //读取数据
		Delay_Us(20);           //延时
		IIC_SCL_L;             //SCL拉低  
		Delay_Us(20);           //延时 		
    }					 
    if(!ack){        //不需要发送
		SDA_OUT();   //SDA线输出模式 
		IIC_SDA_H;   //时钟脉冲的高电平期间保持稳定的高电平
		IIC_SCL_H;   //SCL拉高
		Delay_Us(2); //延时
		IIC_SCL_L;   //SCL拉低 
	}else{           //需要发送
		SDA_OUT();   //SDA线输出模式 
		IIC_SDA_L;   //时钟脉冲的高电平期间保持稳定的低电平
		IIC_SCL_H;   //SCL拉高
		Delay_Us(2); //延时
		IIC_SCL_L;   //SCL拉低
		IIC_SDA_H;   //SDA拉高
	}
    return receive;
}

24C02利用IIC进行存储代码:

/*-------------------------------------------------*/
/*                                                 */
/*             实现24c02功能的源文件               */
/*                                                 */
/*-------------------------------------------------*/

#include "stm32f10x.h"  //包含需要的头文件
#include "24c02.h"      //包含需要的头文件
#include "delay.h" 	    //包含需要的头文件			 
#include "iic.h"        //包含需要的头文件

/*-------------------------------------------------*/
/*函数名:从24c02指定的地址读一字节数据            */
/*参  数:ReadAddr:需要读数据的地址                */
/*返回值:读到的数据                               */
/*-------------------------------------------------*/
unsigned char AT24C02_ReadOneByte(unsigned char ReadAddr)
{				  
	unsigned char receive;         //定义一个变量用于保存接收到的数据
		
	receive = 0;                   //清除receive,准备接收数据
	IIC_Start();                   //IIC开始信号
	IIC_Send_Byte(AT24C02_WADDR);  //发送24c02器件地址+写操作	   	
	IIC_Wait_Ack();                //等待应答
    IIC_Send_Byte(ReadAddr);       //发送需要读数据的地址 
	IIC_Wait_Ack();	               //等待应答 
	IIC_Start();  	 	           //IIC开始信号
	IIC_Send_Byte(AT24C02_RADDR);  //发送24c02器件地址+读操作				   
	IIC_Wait_Ack();	               //等待应答
    receive=IIC_Read_Byte(0);	   //读一字节数据,保存在receive变量中   
    IIC_Stop();                    //停止信号
	Delay_Ms(5);                   //延迟
	return receive;                //返回读取的数据
}

/*-------------------------------------------------*/
/*函数名:指定地址写入一个数据                     */
/*参  数:WriteAddr  :写入数据的目的地址           */
/*参  数:DataToWrite:要写入的数据                 */
/*返回值:无                                       */
/*-------------------------------------------------*/
void AT24C02_WriteOneByte(unsigned char WriteAddr,unsigned char DataToWrite)
{				   	  	    																 
    IIC_Start();                    //开始信号
	IIC_Send_Byte(AT24C02_WADDR);   //发送器件地址+写操作	 
	IIC_Wait_Ack();	                //等待应答
    IIC_Send_Byte(WriteAddr);       //发送写入数据的目的地址
	IIC_Wait_Ack(); 	 	        //等待应答									  		   
	IIC_Send_Byte(DataToWrite);     //发送要写入的数据							   
	IIC_Wait_Ack();  		        //等待应答	   
    IIC_Stop();                     //停止信号  
	Delay_Ms(5);                    //延迟
}

/*-------------------------------------------------*/
/*函数名:指定地址写入一页数据(8字节)            */
/*参  数:WriteAddr  :写入数据的起始地址           */
/*参  数:DataToWrite:要写入的数据(8个字节)      */
/*返回值:无                                       */
/*-------------------------------------------------*/
void AT24C02_WritePage(unsigned char WriteAddr,unsigned char *DataToWrite)
{				   	  	    																 
	unsigned char i;                   //定义一个变量用于for循环   
 
	IIC_Start();                       //开始信号
	IIC_Send_Byte(AT24C02_WADDR);      //发送器件地址+写操作	 
	IIC_Wait_Ack();	                   //等待应答
    IIC_Send_Byte(WriteAddr);          //发送写入数据的目的地址
	IIC_Wait_Ack(); 	 	           //等待应答	
			Delay_Us(20);
	for(i=0;i<8;i++){                  //24c02一页8个字节,循环写入
		IIC_Send_Byte(DataToWrite[i]); //发送要写入的数据							   
		IIC_Wait_Ack();  		       //等待应答

	}	
    IIC_Stop();                        //停止信号 
	Delay_Ms(5);                       //延迟	
}
/*-------------------------------------------------*/
/*函数名:从指定的地址读一页数据(8字节)            */
/*参  数:ReadAddr:需要读数据的地址                */
/*参  数:Redata:保存接收到的数据                  */
/*返回值:读到的数据                               */
/*-------------------------------------------------*/
void AT24C02_ReadPage(unsigned char ReadAddr, unsigned char *Redata)
{				  		
	unsigned char i;               //定义一个变量用于for循环   
	
	IIC_Start();                   //IIC开始信号
	IIC_Send_Byte(AT24C02_WADDR);  //发送器件地址+写操作	   	
	IIC_Wait_Ack();                //等待应答
    IIC_Send_Byte(ReadAddr);       //发送需要读数据的地址 
	IIC_Wait_Ack();	               //等待应答 
	IIC_Start();  	 	           //IIC开始信号
	IIC_Send_Byte(AT24C02_RADDR);  //发送器件地址+读操作				   
	IIC_Wait_Ack();	               //等待应答
	for(i=0;i<7;i++){              //24c02一页8个字节,循环读取前7个字节	
		Redata[i]=IIC_Read_Byte(1);//读一字节数据,发送ACK信号 
    }	
	Redata[7]=IIC_Read_Byte(0);    //读最后一字节数据,不发送ACK信号 
    IIC_Stop();                    //停止信号
	Delay_Ms(5);                   //延迟
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明原文出处。如若内容造成侵权/违法违规/事实不符,请联系SD编程学习网:675289112@qq.com进行投诉反馈,一经查实,立即删除!