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); //延迟
}