STM32模拟IIC读写24CXX -
[导读]
文件(iic.h):#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X80000000;}#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X30000000;}#define IIC_SCL PBout(6)#define IIC_SDA P
文件(iic.h):
本文引用地址: http://www.21ic.com/app/mcu/201806/764746.htm
#define SDA_IN() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X80000000;}
#define SDA_OUT() {GPIOB->CRL&=0X0FFFFFFF;GPIOB->CRL|=0X30000000;}
#define IIC_SCL PBout(6)
#define IIC_SDA PBout(7)
#define READ_SDA PBin(7)
void bsp_iic_init(void);
void bsp_iic_start(void);
void bsp_iic_stop(void);
void bsp_iic_sendByte(u8 txd);
u8 bsp_iic_readByte(unsigned char ack);
u8 bsp_iic_waitAck(void);
void bsp_iic_ack(void);
void bsp_iic_nAck(void);
文件(iic.c):
/*
****************************************************************
** brief : IIC 初始化,IO模拟IIC
** note : SDA-PB7,SCL-PB6
****************************************************************
*/
void bsp_iic_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
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;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);
}
/*
***************************************************************
** brief : IIC开始信号
** note : SCL为高电平时,SDA由高电平向低电平跳变
***************************************************************
*/
void bsp_iic_Start(void)
{
delay_5us();
SDA_OUT();
IIC_SDA=1;
IIC_SCL=1;
delay_5us();
IIC_SDA=0;
delay_5us();
IIC_SCL=0;
}
/*
***************************************************************
** brief : IIC停止信号
** note : SCL为高电平时,SDA由低电平向高电平跳变
***************************************************************
*/
void bsp_iic_stop(void)
{
delay_5us();
SDA_OUT();
IIC_SCL=0;
IIC_SDA=0;
delay_5us();
IIC_SCL=1;
delay_5us();
IIC_SDA=1;
delay_5us();
}
/*
**********************************************************
** brief : 等待应答信号到来
** ret : 1.接收应答失败
** 0.接收应答成功
*********************************************************
*/
u8 bsp_iic_waitAck(void)
{
u8 ucErrTime=0;
delay_5us();
SDA_IN();
IIC_SDA=1;
delay_5us();
IIC_SCL=1;
delay_5us();
while(READ_SDA)
{
ucErrTime++;
if(ucErrTime>100)
{
bsp_iic_stop();
return 1;
}
}
delay_5us();
IIC_SCL=0;
return 0;
}
/* brief : 产生应答信号*/
void bsp_iic_ack(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=0;
delay_5us();
IIC_SCL=1;
delay_5us();
IIC_SCL=0;
}
/* brief : 产生非应答信号*/
void bsp_iic_nAck(void)
{
IIC_SCL=0;
SDA_OUT();
IIC_SDA=1;
delay_5us();
IIC_SCL=1;
delay_5us();
IIC_SCL=0;
}
/*
*************************************************
** breif : IIC发送一个字节
*************************************************
*/
void bsp_iic_sendByte( u8 txd )
{
u8 t;
delay_5us();
SDA_OUT();
IIC_SCL=0;
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
IIC_SDA=1;
else
IIC_SDA=0;
txd<<=1;
delay_5us();
IIC_SCL=1;
delay_5us();
IIC_SCL=0;
delay_5us();
}
}
/*
**************************************************************************************
** brief : 读1个字节
** ack :1.发送ACK,0.发送NACK
** note : 主机作为接收方,发送一个非应答信号表示数据传输结束
** 发送一个应答信号表示数据接收成功
** 从机作为接收方,发送一个非应答信号表示数据接受失败
** 发送一个应答信号表示数据接收成功
**************************************************************************************
*/
u8 bsp_iic_readByte(unsigned char ack)
{
unsigned char i,receive=0;
delay_5us();
SDA_IN();
for(i=0;i<8;i++ )
{
IIC_SCL=0;
delay_5us();
IIC_SCL=1;
receive<<=1;
delay_5us();
if(READ_SDA)receive++;
delay_5us();
}
if (!ack)
bsp_iic_nAck();
else
bsp_iic_ack();
return receive;
}
文件(24cxx.h)
u8 bsp_eeprom_readOneByte(u16 ReadAddr);
void bsp_eeprom_writeOneByte(u16 WriteAddr,u8 DataToWrite);
void bsp_eeprom_writeLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len);
u32 bsp_eeprom_readLenByte(u16 ReadAddr,u8 Len);
void bsp_eeprom_write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);
void bsp_eeprom_read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);
u8 bsp_eeprom_writePage_zero(u16 WriteAddr, u8 data, u16 NumToWrite);
void bsp_eeprom_init(void);
void bsp_eeprom_reset(void);
文件(24cxx.c)
#define AT24C01 127
#define AT24C02 255
#define AT24C04 511
#define AT24C08 1023
#define AT24C16 2047
#define AT24C32 4095
#define AT24C64 8191
#define AT24C128 16383
#define AT24C256 32767
#define EE_TYPE AT24C256
#define EE_PAGE_SIZE 64
/*
**************************************************************************
** note : 1. EEPROM高四位地址固定为1010
** 2. 主设备在从从设备接收到最后一个字节后发送
** 一个NACK 。接收到NACK 后,从设备释放对SCL和SDA
** 线的控制;主设备就可以发送一个停止/ 重起始
** 条件
** 3. 在EEPROM的一次写循环中可以写多个字节,但一次
** 写入的字节数不能超过EEPROM的页大小
*************************************************************************
*/
void bsp_eeprom_init(void)
{
bsp_eeprom_reset();
delay_ms(1);
}
/* brief : EEPROM复位*/
void bsp_eeprom_reset(void)
{
u32 i;
//OSSchedLock();
bsp_iic_Start();
SDA_OUT();
delay_us(1);
IIC_SDA = 1;
for(i=0; i<9; ++i) {
delay_us(1);
IIC_SCL = 1;
delay_us(1);
IIC_SCL = 0;
}
SDA_IN();
bsp_iic_Start();
IIC_Stop();
//OSSchedUnlock();
}
/*
**********************************************************
** brief : 读数据
** ReadAddr : 待读数据地址
** ret : 读出的数据
**********************************************************
*/
u8 bsp_eeprom_readOneByte(u16 ReadAddr)
{
u8 temp=0;
//OSSchedLock();
bsp_iic_Start();
if(EE_TYPE>AT24C16)
{
bsp_iic_sendByte(0XA0); /*发送写命令*/
bsp_iic_waitAck();
bsp_iic_sendByte(ReadAddr>>8);/*发送高地址*/
} else {
bsp_iic_sendByte(0XA0+((Re
查看评论 回复