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のタイミング
    ヘッダファイル
    #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など他の容量のチップにも対応しています.対応するチップのページサイズに応じてマクロ定義を変更するだけでいいです.