下面文件是at24c02iic.h的头文件
#ifndef __AT24C02ICC_H
#define __AT24C02ICC_H
#include "sys.h"
?? ? ? ?? ??? ? ??
//IO方向设置 通过设置寄存器来实现
#define AT24C02_SDA_IN() ?{GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)8<<28;}?
#define AT24C02_SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=(u32)3<<28;}
//IO操作函数?? ??
#define AT24C02_IIC_SCL ? ?PBout(6) ?? ??? ?//SCL?
#define AT24C02_IIC_SDA ? ?PBout(7) ?? ??? ?//SDA?? ??
#define AT24C02_READ_SDA ? PBin(7) ?? ??? ?//输入SDA PB2
//IIC所有操作函数
void AT24C02_IIC_Delay(void);?? ??? ??? ??? ?//MPU IIC延时函数
void AT24C02_IIC_Init(void); ? ? ? ? ? ? ? ?//初始化IIC的IO口?? ??? ??? ??? ??
void AT24C02_IIC_Start(void);?? ??? ??? ??? ?//发送IIC开始信号
void AT24C02_IIC_Stop(void);?? ? ??? ??? ??? ?//发送IIC停止信号
void AT24C02_IIC_Send_Byte(u8 txd);?? ??? ??? ?//IIC发送一个字节
u8 AT24C02_IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
u8 AT24C02_IIC_Wait_Ack(void); ?? ??? ??? ??? ?//IIC等待ACK信号
void AT24C02_IIC_Ack(void);?? ??? ??? ??? ??? ?//IIC发送ACK信号
void AT24C02_IIC_NAck(void);?? ??? ??? ??? ?//IIC不发送ACK信号
//void IMPU_IC_Write_One_Byte(u8 daddr,u8 addr,u8 data);
//u8 MPU_IIC_Read_One_Byte(u8 daddr,u8 addr);?? ? ?
#endif
下面文件是at24c02iic.c的源文件
#include "at24c02iic.h"
#include "delay.h"
? //MPU IIC 延时函数
void AT24C02_IIC_Delay(void)
{
?? ?delay_us(2);
}
//初始化IIC
void AT24C02_IIC_Init(void)
{?? ??? ??? ??? ??? ? ? ??
? GPIO_InitTypeDef ?GPIO_InitStructure;
?? ?
?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//先使能外设IO PORTB时钟?
?? ??? ?
? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;?? ? // 端口配置
? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ?? ??? ? //推挽输出
? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;?? ??? ? //IO口速度为50MHz
? GPIO_Init(GPIOB, &GPIO_InitStructure);?? ??? ??? ??? ??? ? //根据设定参数初始化GPIO?
?? ?
? GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);?? ??? ??? ??? ??? ??? ? //PB7,PB6 输出高?? ?
?
}
//产生IIC起始信号
void AT24C02_IIC_Start(void)
{
?? ?AT24C02_SDA_OUT(); ? ? //sda线输出
?? ?AT24C02_IIC_SDA=1;?? ? ??? ? ?
?? ?AT24C02_IIC_SCL=1;
?? ?AT24C02_IIC_Delay(); ?//廷时是很必要的,如果没有它,执行两次开始信号时,因为单片机执行时间很快,没有把它们置于空闲状态
??? ?AT24C02_IIC_SDA=0;//START:when CLK is high,DATA change form high to low?
?? ?AT24C02_IIC_Delay();
?? ?AT24C02_IIC_SCL=0;//钳住I2C总线,准备发送或接收数据?
}?? ? ?
//产生IIC停止信号
void AT24C02_IIC_Stop(void)
{
?? ?AT24C02_SDA_OUT();//sda线输出
?? ?AT24C02_IIC_SCL=0;
?? ?AT24C02_IIC_SDA=0;//STOP:when CLK is high DATA change form low to high
??? ?AT24C02_IIC_Delay();
?? ?AT24C02_IIC_SCL=1; ?
?? ?AT24C02_IIC_SDA=1;//发送I2C总线结束信号
?? ?AT24C02_IIC_Delay();?? ??? ??? ??? ??? ??? ??? ? ? ?? ?
}
//等待应答信号到来
//返回值:1,接收应答失败
// ? ? ? ?0,接收应答成功
u8 AT24C02_IIC_Wait_Ack(void)
{
?? ?u8 ucErrTime=0;
?? ?AT24C02_SDA_IN(); ? ? ?//SDA设置为输入 ?
?? ?AT24C02_IIC_SDA=1;AT24C02_IIC_Delay();?? ? ??
?? ?AT24C02_IIC_SCL=1;AT24C02_IIC_Delay();?? ??
?? ?while(AT24C02_READ_SDA)
?? ?{
?? ??? ?ucErrTime++;
?? ??? ?if(ucErrTime>250)
?? ??? ?{
?? ??? ??? ?AT24C02_IIC_Stop();
?? ??? ??? ?return 1;
?? ??? ?}
?? ?}
?? ?AT24C02_IIC_SCL=0;//时钟输出0 ?? ? ??
?? ?return 0; ?
}?
//产生ACK应答
void AT24C02_IIC_Ack(void)
{
?? ?AT24C02_IIC_SCL=0;
?? ?AT24C02_SDA_OUT();
?? ?AT24C02_IIC_SDA=0;
?? ?AT24C02_IIC_Delay();
?? ?AT24C02_IIC_SCL=1;
?? ?AT24C02_IIC_Delay();
?? ?AT24C02_IIC_SCL=0;
}
//不产生ACK应答?? ??? ? ? ?
void AT24C02_IIC_NAck(void)
{
?? ?AT24C02_IIC_SCL=0;
?? ?AT24C02_SDA_OUT();
?? ?AT24C02_IIC_SDA=1;
?? ?AT24C02_IIC_Delay();
?? ?AT24C02_IIC_SCL=1;
?? ?AT24C02_IIC_Delay();
?? ?AT24C02_IIC_SCL=0;
}?? ??? ??? ??? ??? ? ?? ??? ??? ??? ? ? ??
//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答?? ??? ??? ? ?
void AT24C02_IIC_Send_Byte(u8 txd)
{ ? ? ? ? ? ? ? ? ? ? ? ?
? ? u8 t; ??
?? ?AT24C02_SDA_OUT(); ?? ? ? ?
? ? AT24C02_IIC_SCL=0;//拉低时钟开始数据传输
? ? for(t=0;t<8;t++)
? ? { ? ? ? ? ? ? ?
? ? ? ? AT24C02_IIC_SDA=(txd&0x80)>>7;
? ? ? ? txd<<=1; ?? ? ?
?? ??? ?AT24C02_IIC_SCL=1;
?? ??? ?AT24C02_IIC_Delay();?
?? ??? ?AT24C02_IIC_SCL=0;?? ?
?? ??? ?AT24C02_IIC_Delay();
? ? }?? ??
} ?? ? ? ?
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK ??
u8 AT24C02_IIC_Read_Byte(unsigned char ack)
{
?? ?unsigned char i,receive=0;
?? ?AT24C02_SDA_IN();//SDA设置为输入
? ? for(i=0;i<8;i++ )
?? ?{
? ? ? ? AT24C02_IIC_SCL=0;?
? ? ? ? AT24C02_IIC_Delay();
?? ??? ?AT24C02_IIC_SCL=1;
? ? ? ? receive<<=1;
? ? ? ? if(AT24C02_READ_SDA)receive++; ??
?? ??? ?AT24C02_IIC_Delay();?
? ? }?? ??? ??? ??? ??? ??
? ? if (!ack)
? ? ? ? AT24C02_IIC_NAck();//发送nACK
? ? else
? ? ? ? AT24C02_IIC_Ack(); //发送ACK ??
? ? return receive;
}
?