基于STM32f103的AT24C02的硬件IIC实验(标准库)

第一步,初始化AT24C02

void I2C_Configuration(void)
{
   I2C_InitTypeDef  I2C_InitStructure;//IIC初始化
   GPIO_InitTypeDef  GPIO_InitStructure; //GPIO初始化

   RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);//使能IIC时钟
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);//使能GPIOB和复用IO时钟

   GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;//硬件IIC1:PB6->SCL,PB7->SDA
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//频率50MHZ
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//复用开漏模式
   GPIO_Init(GPIOB, &GPIO_InitStructure);
		
   I2C_DeInit(I2C1);//清楚IIC1原来配置
   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//设置为IIC模式
   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//占空比:low/high=2:1
   I2C_InitStructure.I2C_OwnAddress1 = 0x00;//主机地址:0x00
   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//IIC应答使能
   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//7位地址应答
   I2C_InitStructure.I2C_ClockSpeed = 100000;//时钟频率100KHZ

   I2C_Cmd(I2C1, ENABLE);//IIC使能
   I2C_Init(I2C1, &I2C_InitStructure);

   I2C_AcknowledgeConfig(I2C1, ENABLE);//IIC应答使能
}

第二步,IIC写数据

参考主机发送时序图

uint8_t I2C_WriteOneByte(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t value)
{
  	I2C_GenerateSTART(I2Cx, ENABLE);//产生起始位
  	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));//等待EV5  

  	I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);//发送7位从机地址(I2C_Addr:0xA0),主机发送模式
  	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待EV6
  
  	I2C_SendData(I2Cx, addr);//发送写入数据地址
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待EV8_2

  	I2C_SendData(I2Cx, value);//发送数据
  	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待EV8_2
	
  	I2C_GenerateSTOP(I2Cx, ENABLE);//产生停止位
  
  	I2C_AcknowledgePolling(I2Cx,I2C_Addr);//等待从机应答

	I2C_delay(1000);

	return 0;
}

uint8_t I2C_Write(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num)
{
	uint8_t err=0;
	
	while(num--)//循环一字节一字节写入数据
	{
		if(I2C_WriteOneByte(I2Cx, I2C_Addr,addr++,*buf++))
		{
			err++;
		}
	}
	if(err)
		return 1;
	else 
		return 0;	
}

第三步,IIC读数据

参考主机接收时序图

uint8_t I2C_Read(I2C_TypeDef *I2Cx,uint8_t I2C_Addr,uint8_t addr,uint8_t *buf,uint16_t num)
{
    if(num==0)
	return 1;
	
	while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));//总线上无数据通信,则继续执行
		
	I2C_AcknowledgeConfig(I2Cx, ENABLE);//使能I2C应答


    I2C_GenerateSTART(I2Cx, ENABLE);//使能I2C开始
    while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));//等待EV5
	
    I2C_Send7bitAddress(I2Cx,  I2C_Addr, I2C_Direction_Transmitter);//发送设备7位地址,主发送模式
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待 EV6 

	I2C_SendData(I2Cx, addr);//发送I2C数据地址
    while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待EV8_2
		
	I2C_GenerateSTART(I2Cx, ENABLE);//使能I2C开始
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));//等待EV5
	
	I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Receiver);//发送设备7位地址,主接收模式
	while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));//等待 EV6
		
    while (num)
    {
		if(num==1)
		{
     		I2C_AcknowledgeConfig(I2Cx, DISABLE);//失能应答
    		I2C_GenerateSTOP(I2Cx, ENABLE);//产生停止位
		}
	    
		while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));  //等待EV7
	    *buf = I2C_ReceiveData(I2Cx);//接收一字节数据
	    buf++;//buf指针后移
	    num--;//剩余数据-1
    }

	I2C_AcknowledgeConfig(I2Cx, ENABLE);//使能应答

	return 0;
}	

第四步,等待从机应答

static void I2C_AcknowledgePolling(I2C_TypeDef *I2Cx,uint8_t I2C_Addr)
{
  do
  {   
    I2C_GenerateSTART(I2Cx, ENABLE);//使能I2Cx开始

	I2C_Send7bitAddress(I2Cx, I2C_Addr, I2C_Direction_Transmitter);//7位地址,主发送模式

  }while(!(I2C_ReadRegister(I2Cx, I2C_Register_SR1) & 0x0002));//未发送完成,则继续循环执行
  
  I2C_ClearFlag(I2Cx, I2C_FLAG_AF);//清除应答标志位(SR1)
    
  I2C_GenerateSTOP(I2Cx, ENABLE);//产生停止位
}

参考实验

#include "stm32f10x.h"
#include "24C02.h"
#include <string.h>
#include <stdio.h>

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

void USART_Configuration(void);

void  Delay (uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

int main(void)
	{
	uint16_t Addr;
	uint8_t WriteBuffer[256],ReadBuffer[256];

	USART_Configuration();
	I2C_Configuration();

	for(Addr=0; Addr<256; Addr++)
	WriteBuffer[Addr]=Addr;	 /* 填充WriteBuffer */

	/* 开始向AT24C02写入数据 */
	printf("\r\n EEPROM 24C02 Write Test \r\n");
	I2C_Write(I2C1,ADDR_24LC02,0,WriteBuffer,sizeof(WriteBuffer) );
	printf("\r\n EEPROM 24C02 Write Test OK \r\n");

	/* 开始读取AT24C02的数据 */
	printf("\r\n EEPROM 24C02 Read Test \r\n");
	I2C_Read(I2C1,ADDR_24LC02,0,ReadBuffer,sizeof(WriteBuffer) );

	if(  memcmp(WriteBuffer,ReadBuffer,sizeof(WriteBuffer)) == 0 ) /* 匹配数据 */
	{
		printf("\r\n EEPROM 24C02 Read Test OK\r\n");
		for(int i=0;i<256;i++){
		printf("%d\n",ReadBuffer[i]);
			Delay(500000);
		}
		printf("\r\n EEPROM 24C02 Read Test END\r\n");
	}
	else
	printf("\r\n EEPROM 24C02 Read Test False\r\n");
}

实验现象

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值