新手入门
- 积分
- 4
- 金钱
- 4
- 注册时间
- 2021-4-17
- 在线时间
- 5 小时
|
12金钱
本帖最后由 OUYTYI 于 2022-3-1 19:31 编辑
.h文件内容如下
#ifndef _IIC_EEPROM
#define _IIC_EEPROM
#include "stm32f10x.h"
#define IIC_EEPROM_ADDRESS 0XA0
#define EEPROM_PAGE 8
#define IIC_GPIO_SCL_PIN GPIOB
#define IIC_GPIO_SDA_PIN GPIOB
#define IIC_GPIO_SCL_PORT GPIO_Pin_6
#define IIC_GPIO_SDA_PORT GPIO_Pin_7
#define IIC_EEPROM IIC1
#define IIC_EEPROM_BAUDRATE 400000
#define IIC_GPIO_CLK RCC_APB2Periph_GPIOB
#define IIC_CLK RCC_APB1Periph_IIC
#define IIC_SCL_0 GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define IIC_SCL_1 GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define IIC_SDA_0 GPIO_ResetBits(GPIOB,GPIO_Pin_7)
#define IIC_SDA_1 GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define IIC_Read_SDA_status (IIC_GPIO_SDA_PIN->IDR & IIC_GPIO_SDA_PORT)
void IIC_EEPROM_GPIO_Init(void);
u8 IIC_Byte_Read(void);
void IIC_Byte_Write(u8 data);
u8 IIC_ReadOneByte(u16 address);
u8 IIC_WriteOneByte(u16 address,u8 write_data);
void IIC_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);
void IIC_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);
void IIC_Start(void);
void IIC_Stop(void);
u8 AT24CXX_Check(void);
#endif
.c文件如下
#include "I2C_EEPROM.h"
#include "my_usart.h"
#include "delay.h"
u32 IIC_TIME;
void IIC_EEPROM_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);
}
void IIC_Byte_Send(u8 data)
{
u8 i;
for(i=0;i<8;i++)
{
if(data&0x80)
{
IIC_SDA_1;
}
else
{
IIC_SDA_0;
}
delay_us(5);
IIC_SCL_1;
delay_us(5);
IIC_SCL_0;
if(i==7)
{
IIC_SDA_1;
}
data<<=1;
delay_us(5);
}
}
u8 IIC_Byte_Read(void)
{
u8 i;
u8 data=0;
for(i=0;i<8;i++)
{
data<<=1;
delay_us(5);
IIC_SCL_1;
if(IIC_Read_SDA_status)
{
data++;
}
delay_us(5);
IIC_SCL_0;
}
return data;
}
u8 IIC_Wait_ack(void)
{
u8 IIC_DEVICE_RETURN;
IIC_SDA_1;
delay_us(5);
IIC_SCL_1;
delay_us(5);
IIC_SCL_0;
if(IIC_Read_SDA_status==0)
{
IIC_DEVICE_RETURN=1;
}
else
{
IIC_DEVICE_RETURN=0;
}
return IIC_DEVICE_RETURN;
}
void IIC_Start(void)
{
IIC_SCL_1;
IIC_SDA_1;
delay_ms(5);
IIC_SDA_0;
delay_ms(5);
IIC_SCL_0;
}
void IIC_Stop(void)
{
IIC_SCL_1;
IIC_SDA_0;
delay_us(5);
IIC_SDA_1;
delay_us(5);
IIC_SCL_0;
}
void IIC_Ack(void)
{
IIC_SDA_0;
IIC_SCL_1;
delay_us(5);
IIC_SCL_0;
delay_us(5);
}
void IIC_Nack(void)
{
IIC_SDA_1;
IIC_SCL_1;
delay_us(5);
IIC_SCL_0;
delay_us(5);
}
u8 IIC_WriteOneByte(u16 address,u8 write_data)
{
IIC_Start();
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
IIC_Byte_Send(0XA0);
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
IIC_Byte_Send(address);
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
IIC_Byte_Send(write_data);
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
IIC_Stop();
return 1;
IIC_FAIL:
IIC_Stop();
return 0;
}
u8 IIC_ReadOneByte(u16 address)
{
u8 DATA;
IIC_Start();
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
IIC_Byte_Send(0XA0);
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
IIC_Byte_Send(address);
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
IIC_Start();
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
IIC_Byte_Send(0XA1);
if(IIC_Wait_ack()==0)
{
goto IIC_FAIL;
}
DATA =IIC_Byte_Read();
IIC_Stop();
return DATA;
IIC_FAIL:
IIC_Stop();
return 0;
}
void IIC_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
while(NumToWrite--)
{
IIC_WriteOneByte(WriteAddr,*pBuffer);
WriteAddr++;
pBuffer++;
}
}
void IIC_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
while(NumToRead)
{
*pBuffer++=IIC_ReadOneByte(ReadAddr++);
NumToRead--;
}
}
u8 AT24CXX_Check(void)
{
u8 temp;
temp=IIC_ReadOneByte(255);//避免每次开机都写AT24CXX
if(temp==0X55)return 0;
else//排除第一次初始化的情况
{
IIC_WriteOneByte(255,0X55);
temp=IIC_ReadOneByte(255);
if(temp==0X55)return 0;
}
return 1;
}
main函数如下:
#include "stm32f10x.h"
#include "led.h"
#include "delay.h"
#include "my_usart.h"
#include "I2C_EEPROM.h"
int main(void)
{
u8 IIC_WriteData[10]={1,1,1,1,1,1,1,1,1,1};
u8 IIC_ReadData[10]={0};
delay_init();
my_usart_init();
IIC_EEPROM_GPIO_Init();
while(AT24CXX_Check()==1)
{
delay_ms(500);
printf("error\r\n");
}
printf("IIC实验\r\n");
IIC_EEPROM_GPIO_Init();
IIC_Write(0,(u8*)IIC_WriteData,8);
IIC_Read(0,IIC_ReadData,8);
for(i=0;i<10;i++)
{
printf("%d\r\n",IIC_WriteData);
printf("%d",IIC_ReadData);
}
while(1)
{
}
}
|
最佳答案
查看完整内容[请看2#楼]
为什么原子的例程里要在sda线设置输入输出状态的切换呢?我看野火的例程就没有这种操作,正常配置推挽的话,没必要切换输入输出状态吧,我把我的start函数放进原子的例程,把原子原先的例程注释,发现程序就不行了,真的好奇怪,有大佬能帮忙看一看吗,万分感谢
|