STM 32 IO口アナログIIC読み取りAT 24 C 128を使用する
7681 ワード
STM 32 IO口アナログIIC読み取りAT 24 C 128を使用する AT 24 C 28プロファイル STM 32のIOアナログIICを使用するタイミング ヘッダファイル cファイル PS拡張内容 AT 24 C 28概要
AT 24 C 128、ATMEL社のEEPROMチップは16,384 x 8 bitで、メモリ全体は256ページで、64 BYTES.はIICプロトコルを使用しています.
STM 32を使用したIOアナログIICのタイミング
ヘッダファイル
本論文はAT 24 C 28のために書かれていますが、AT 24 C 02、AT 24 C 256など他の容量のチップにも対応しています.対応するチップのページサイズに応じてマクロ定義を変更するだけでいいです.
AT 24 C 128、ATMEL社のEEPROMチップは16,384 x 8 bitで、メモリ全体は256ページで、64 BYTES.はIICプロトコルを使用しています.
STM 32を使用したIOアナログIICのタイミング
ヘッダファイル
#ifndef EEPROM_H
#define EEPROM_H
#include "Typedef.h"
#define IIC_SDA_PORT GPIOA
#define IIC_SCL_PORT GPIOA
#define IIC_SCL_PIN GPIO_PIN_3
#define IIC_SDA_PIN GPIO_PIN_4
#define HIGH GPIO_PIN_SET
#define LOW GPIO_PIN_RESET
#define PinInput 1
#define PinOutput 0
#define SDA_IN() {GPIOA->CRL&=0XFFF0FFFF;GPIOA->CRL|=(u32)8<<16;}
#define SDA_OUT() {GPIOA->CRL&=0XFFF0FFFF;GPIOA->CRL|=(u32)3<<16;}
#define GetSDA() (HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_4)==GPIO_PIN_SET) //(GPIOA->IDR&((u32)1<<4))
#define SetSDA(state) HAL_GPIO_WritePin(IIC_SDA_PORT,IIC_SDA_PIN,state)
#define SetSCL(state) HAL_GPIO_WritePin(IIC_SCL_PORT,IIC_SCL_PIN,state)
#define E_DELAY 2 // EEPROM
extern u8 iic_cmd_delay;
extern u8 AT24CXX_ReadOneByte(u32 ReadAddr);
extern void AT24CXX_WriteOneByte(u32 WriteAddr,u8 DataToWrite);
extern void AT24CXX_Read(u32 ReadAddr,u8 *pBuffer,u16 NumToRead);
extern void AT24CXX_Write(u32 WriteAddr,u8 *pBuffer,u16 NumToWrite);
extern void AT24CXX_clr(u32 WriteAddr,u32 NumToWrite);
extern void IIC_Start1(void);
void IIC_Stop(void);
u8 IIC_Wait_Ack(void);
void IIC_Ack(void);
void IIC_NAck(void);
void IIC_Send_Byte(u8 txd);
void delay_nop(void);
void SetSDADirection(u8 direction);
#endif
cファイル
#include "main.h"
#include "eeprom.h"
/* AT24C128C organized as 256 pages of 64-bytes each
AT24C512C, organized as 512 pages of 128 bytes each
EEPROM ,
*/
#define PAGE_SIZE 64
u8 iic_cmd_delay=0;
void SetSDADirection(u8 direction)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = IIC_SDA_PIN;
if(direction)
{
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
}
else
{
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
}
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
// SDA
/***********************iic**************************/
void delay_nop(void)
{
unsigned int i;
for(i=0;i<50;i++)
__nop();
}
// IIC
void IIC_Start(void)
{
/*while(iic_cmd_delay < E_DELAY) //
{
R_WDT_Restart();
}*/
SDA_OUT();//sda
SetSDA(HIGH);
SetSCL(HIGH);
delay_nop();
SetSDA(LOW);//START:when CLK is high,DATA change form high to low
delay_nop();
SetSCL(LOW);// I2C ,
}
void IIC_Start1(void)
{
SDA_OUT(); //sda
SetSDA(HIGH);
delay_nop();
SetSCL(HIGH);
delay_nop();
SetSDA(LOW); //START:when CLK is high,DATA change form high to low
delay_nop();
SetSCL(LOW); // I2C ,
}
// IIC
void IIC_Stop(void)
{
SetSDA(LOW);
SDA_OUT();//sda
SetSCL(LOW);
delay_nop();
SetSCL(HIGH);
delay_nop();
SetSDA(HIGH);// I2C
delay_nop();
iic_cmd_delay=0;
}
//
// :
// 1,
// 0,
u8 IIC_Wait_Ack(void)
{
u8 flag;
SDA_IN(); //SDA
SetSDA(HIGH);
delay_nop();
SetSCL(HIGH);
delay_nop();
if(GetSDA())
flag=1;
else
flag=0;
SetSCL(LOW); // 0
return flag;
}
// ACK
void IIC_Ack(void)
{
SetSCL(LOW);
SDA_OUT();
SetSDA(LOW);
delay_nop();
SetSCL(HIGH);
delay_nop();
SetSCL(LOW);
}
// ACK
void IIC_NAck(void)
{
SetSCL(LOW);
SDA_OUT();
SetSDA(HIGH);
delay_nop();
SetSCL(HIGH);
delay_nop();
SetSCL(LOW);
}
//IIC
//
//1,
//0,
void IIC_Send_Byte(u8 txd)
{
u8 t;
SDA_OUT();
SetSCL(LOW);//
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
SetSDA(HIGH);
else SetSDA(LOW);
txd<<=1;
delay_nop();
SetSCL(HIGH);
delay_nop();
SetSCL(LOW);
}
}
// 1 ,ack=1 , ACK,ack=0, nACK
u8 IIC_Read_Byte(u8 ack)
{
u8 i,receive=0;
SDA_IN();
for(i=0;i<8;i++ )
{
SetSCL(LOW);
delay_nop();
SetSCL(HIGH);
delay_nop();
receive<<=1;
if(GetSDA())
receive++;
}
if (!ack)
IIC_NAck();// nACK
else
IIC_Ack(); // ACK
return receive;
}
/***********************iic**************************/
// AT24CXX
//ReadAddr:
// :
u8 AT24CXX_ReadOneByte(u32 ReadAddr)
{
u8 temp;
u8 addrH,addrL;
addrH=ReadAddr>>8;
addrL=ReadAddr&0xff;
IIC_Start();
IIC_Send_Byte(0xa0);
IIC_Wait_Ack();
IIC_Send_Byte(addrH); //
IIC_Wait_Ack();
IIC_Send_Byte(addrL); //
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0xa1); //
IIC_Wait_Ack();
temp= IIC_Read_Byte(0);
IIC_Stop();//
return temp;
}
// AT24CXX
//WriteAddr :
//DataToWrite:
void AT24CXX_WriteOneByte(u32 WriteAddr,u8 DataToWrite)
{
u8 addrH,addrL;
addrH=WriteAddr>>8;
addrL=WriteAddr&0xff;
IIC_Start();
IIC_Send_Byte(0xa0);
IIC_Wait_Ack();
IIC_Send_Byte(addrH); //
IIC_Wait_Ack();
IIC_Send_Byte(addrL); //
IIC_Wait_Ack();
IIC_Send_Byte(DataToWrite); //
IIC_Wait_Ack();
IIC_Stop();//
}
// AT24CXX
//ReadAddr : 24c02 0~255
//pBuffer :
//NumToRead:
void AT24CXX_Read(u32 ReadAddr,u8 *pBuffer,u16 NumToRead)
{
u8 addrH,addrL;
if(NumToRead==0)
return;
addrH=ReadAddr>>8;
addrL=ReadAddr&0xff;
IIC_Start();
IIC_Send_Byte(0xa0);//
IIC_Wait_Ack();
IIC_Send_Byte(addrH); //
IIC_Wait_Ack();
IIC_Send_Byte(addrL); //
IIC_Wait_Ack();
IIC_Start();
IIC_Send_Byte(0xa1); // //
IIC_Wait_Ack();
NumToRead--;
while(NumToRead)
{
*pBuffer=IIC_Read_Byte(1);
pBuffer++;
ReadAddr++;
NumToRead--;
}
*pBuffer=IIC_Read_Byte(0);
IIC_Stop();//
}
// AT24CXX
//WriteAddr : 24c02 0~255
//pBuffer :
//NumToWrite:
// 128bytes page,
void AT24CXX_Write(u32 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{
u8 addrH,addrL;
u16 lentmp,lentow,lens;
u8 tmp;
if(NumToWrite==0)
return;
lentmp=NumToWrite;
while(lentmp)
{
tmp=WriteAddr%PAGE_SIZE;
tmp=PAGE_SIZE-tmp;
if(tmp>=lentmp)//
{
lentow=lentmp;
}
else
{
lentow=tmp;//
}
lentmp=lentmp-lentow;//
lens=lentow;
addrH=WriteAddr>>8;
addrL=WriteAddr&0xff;
IIC_Start();
IIC_Send_Byte(0xa0);
IIC_Wait_Ack();
IIC_Send_Byte(addrH); //
IIC_Wait_Ack();
IIC_Send_Byte(addrL); //
IIC_Wait_Ack();
while(lentow--)
{
IIC_Send_Byte(*pBuffer);
IIC_Wait_Ack();
pBuffer++;
}
IIC_Stop();//
WriteAddr=WriteAddr+lens;//
}
}
void AT24CXX_clr(u32 WriteAddr,u32 NumToWrite)
{
u8 addrH,addrL;
u16 lentmp,lentow,lens;
u8 tmp;
lentmp=NumToWrite;
while(lentmp)
{
tmp=WriteAddr%PAGE_SIZE;
tmp=PAGE_SIZE-tmp;
if(tmp>=lentmp)
{
lentow=lentmp;
}
else
{
lentow=tmp;
}
lentmp=lentmp-lentow;
lens=lentow;
addrH=WriteAddr>>8;
addrL=WriteAddr&0xff;
IIC_Start();
IIC_Send_Byte(0xa0);
IIC_Wait_Ack();
IIC_Send_Byte(addrH); //
IIC_Wait_Ack();
IIC_Send_Byte(addrL); //
IIC_Wait_Ack();
while(lentow--)
{
IIC_Send_Byte(0xff);
IIC_Wait_Ack();
}
IIC_Stop();//
WriteAddr=WriteAddr+lens;
}
}
//----------------------EEPROM---------------------------//
//--------------------------------------------------------EEPROM DATA
PS拡張内容本論文はAT 24 C 28のために書かれていますが、AT 24 C 02、AT 24 C 256など他の容量のチップにも対応しています.対応するチップのページサイズに応じてマクロ定義を変更するだけでいいです.