⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 2464.c

📁 eeprom 24c64 by avr. c source code
💻 C
字号:
//******************************************************************* 
//********File name        :24C64 eeprom's write and read 
//********File create date :2008/5/27 
//********Design dept      :ATE  
//********Systm explain    :Atmage 88 ,8m/8 
//******************************************************************* 
#include "C.h" 
//******************************************************************* 
//上位机发送:"AA+55+读取字节数高字节+读取字节数低字节+CHKSUM"后, 
//下位机开始读24C64,相应的字节数发送给上位机. 
//******************************************************************* 
//通信波特率:4800,N,8,1 内部时种分频 
//******************************************************************* 
int  Eepaddress=0x0000;   //要读取的24C64内部存贮器单元地址 
int  Eep_long;            //保存上位机发数来的,将要读取的字节个数数据 
char Eepdata[32]; 
int  read_byte=32; 

int usart_bit=0;                      //计录串口接收数据个数 
int step_bit_0=0; 

char command_dataH;        
char command_dataL; 
char RXD_chksum; 

//******************************************************************* 
void main() 
{ 
    Mcu_init(); 
    initial_usart(); 
    Sei(); 
    while(1) 
    { 
          if(step_bit_0==0x01)                           //上位机发送的命今接收成功 
                 { 
                      step_bit_0=0x00; 
                      char chksum_sum=0xAA+0X55+command_dataH+command_dataL; 
                      if(RXD_chksum==chksum_sum)         //whether the chksum is right of data,if the data is right for It's downflow,then return 
                      { 
                              Eepaddress=0x0000; 
                              Eep_long=command_dataH*256+command_dataL; 
                              // 以下程序如果上位机发送的要读取的字节数小于32字节,程序单字节读取.每次所读取的数据放在Eepdata[0]中; 
                              //如果大于32字节按块读取,先读32倍数的字节数,余数按单节读取. 
                              //如果大于24C64的存贮器最大范围(8192字节).下位机不读取数取,也不发送. 
                              //******************************************** 
                              if(Eep_long<=32)           //小于32时,一位一位读取 
                              { 
                                  for(int b=0;b<Eep_long;b++) 
                                      { 
                                          AT24C64_R(Eepaddress); 
                                          UDR0=Eepdata[0]; 
                                          while(!CHKBIT(UCSR0A,TXC0));//wait for sending 
                                          SETBIT(UCSR0A,TXC0); 
                                      } 
                              } 
                              else                       //大于32是按块读取 
                              { 
                                  if(!(Eep_long>8192))   //大于24C64读取范围时,不读取数据,也不回复给上位机 
                                     { 
                                          for(int a=0;a<(Eep_long/32);a++) 
                                          { 
                                             AT24C64_RB(Eepaddress,read_byte); 
                                             for(int b=0;b<read_byte;b++) 
                                             { 
                                                UDR0=Eepdata[b]; 
                                                while(!CHKBIT(UCSR0A,TXC0));//wait for sending 
                                                SETBIT(UCSR0A,TXC0); 
                                             } 
                                          } 
                                          for(int b=0;b<(Eep_long%32);b++) 
                                          { 
                                             AT24C64_R(Eepaddress); 
                                             UDR0=Eepdata[0]; 
                                             while(!CHKBIT(UCSR0A,TXC0));//wait for sending 
                                             SETBIT(UCSR0A,TXC0); 
                                          } 
                                     } 
                              } 
                      } 
                 } 
          Nop(); 
    } 

} 


//******************************************************************** 
//串口通信说明: 
//串口通信:4800,N,8,1 
//接收中断使能,允许发送和接收 
//******************************************************************** 
void initial_usart(void) 
    { 
      UBRR0H=0; 
      UBRR0L=12;        //BAUD 4800 
      UCSR0B=(1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0);//ENABLE 
      UCSR0C=(3<<UCSZ00);//no check bit, 8 bits, 1 stop 
    } 

//******************************************************************* 
//引脚定义 
//******************************************************************* 
void  Mcu_init() 
{ 
    OUT_SDA; 
    OUT_SCL; 
} 

//******************************************************************** 
//接收数据中断: 
//******************************************************************** 
#pragma vector=USART_RX_vect 
__interrupt 
void USART_RX(void) 
      {   
         unsigned char command=UDR0; 
         if(usart_bit==0) 
              { 
                if(command==0XAA) 
                usart_bit=1; 
                else 
                usart_bit=0; 
              } 
         else if(usart_bit==1) 
              { 
                if(command==0x55) 
                usart_bit=2; 
                else 
                usart_bit=0; 
              } 
         else if(usart_bit==2) 
              { 
                command_dataH=command; 
                usart_bit=3; 
              } 
         else if(usart_bit==3) 
              { 
                command_dataL=command; 
                usart_bit=4;      //只接收4个字节,如还有数据则从数据头开始检测 
              } 
         else if(usart_bit==4) 
              { 
                RXD_chksum=command; 
                step_bit_0=0x01; //接收成功 
                usart_bit=0;     //只接收5个字节,如还有数据则从数据头开始检测 
              } 
      } 


//******************************************************************* 
//单字节写程序 
//PartAdd_W 为器件地址+写命今 
//AT24C64_address为要操作的I2C芯片的内部存贮单元,为双字节(24C64) 
//Data 为要写入的数据 
//******************************************************************* 
void AT24C64_W(int AT24C64_address,int Data) 
{ 
                I2C_Start(); 
                I2C_Send_Byte(0xa0 ); 
                I2C_Send_Byte(AT24C64_address/256 ); 
                I2C_Send_Byte(AT24C64_address %256 ); 
                I2C_Send_Byte(Data); 
                I2C_Stop(); 
                Delay_N_mS(10);        
} 


//****************************************************************** 
//单字节读程序: 
//AT24C64_address为要操作的I2C芯片的内部存贮单元,为双字节(24C64) 
//****************************************************************** 
void AT24C64_R(int AT24C64_address) 
{ 
                I2C_Start(); 
                I2C_Send_Byte(0xa0); 
                I2C_Send_Byte(AT24C64_address/256 ); 
                I2C_Send_Byte(AT24C64_address % 256 ); 
                I2C_Start(); 
                I2C_Send_Byte(0xa1); 
                Eepdata[0]=I2C_Receive_Byte(); 
                I2C_Nack(); 
                I2C_Stop();      
                Eepaddress++;                //读取一个字节时不需此步.调用完此子程序后.你所要读取单元字节的数据已放入Eepdata[0].直接用 
} 


//******************************************************************** 
//32字节(块)读程序 
//******************************************************************** 
void AT24C64_RB(int AT24C64_address,int eep_byte) 
{ 
                I2C_Start(); 
                I2C_Send_Byte(0xa0); 
                I2C_Send_Byte(AT24C64_address/256 ); 
                I2C_Send_Byte(AT24C64_address%256 ); 
                I2C_Start(); 
                I2C_Send_Byte(0xa1); 
                for(int a=0;a<eep_byte;a++) 
                { 
                    Eepdata[a]= I2C_Receive_Byte(); 
                    I2C_Ack(); 
                    Eepaddress++;                     //地址加1 
                } 
                I2C_Stop();             
} 


//******************************************************************** 
//接收数据: 
//用来接收数据 
//******************************************************************** 
char I2C_Receive_Byte(void) 
{ 
    char Data_C=0; 
    char Bitcont; 
    IN_SDA;                //切换数据线为输入状态 
    for(Bitcont=0;Bitcont<8;Bitcont++) 
    { 
        Nop(); 
        SCL_0; 
        Delay_10_uS(); 
        SCL_1; 
        Delay_10_uS(); 
        Data_C=Data_C<<1; 
        if(!(CHK_SDA==0)) 
           Data_C=Data_C+1; 
        Nop(); 
        Nop(); 
    } 
    SCL_0; 
    Delay_10_uS(); 
    OUT_SDA;             //恢复数据线为输出状态 
    return Data_C; 
} 

//******************************************************************** 
//*起始说明:                                                         * 
//*在时钟为高时,数据线由高变低.                                      * 
//******************************************************************** 
void I2C_Start(void) 
{ 
        Delay_10_uS(); 
        SDA_1;//        I2C_SDA =1;        
        Delay_10_uS(); 
        SCL_1;//        I2C_SCK =1; 
        Delay_10_uS(); 
        SDA_0;//        I2C_SDA = 0; 
        Delay_10_uS(); 
        SCL_0;//        I2C_SCK = 0; 
        Delay_10_uS(); 
} 


//******************************************************************** 
//*结束说明:                                                         * 
//*在时钟为高时,数据线由低变高                                       * 
//******************************************************************** 
void  I2C_Stop(void) 
{ 
        Delay_10_uS(); 
        SDA_0;//        I2C_SDA = 0; 
        Delay_10_uS(); 
        SCL_1;//        I2C_SCK = 1; 
        Delay_10_uS(); 
        SDA_1;//        I2C_SDA = 1; 
        Delay_10_uS(); 
} 


//******************************************************************** 
//主机发送应答位 
//******************************************************************** 
void I2C_Ack(void) 
{ 
        Delay_10_uS(); 
        SDA_0;//        I2C_SDA=0; 
        Delay_10_uS(); 
        SCL_1;//        I2C_SCK=1; 
        Delay_10_uS(); 
        SCL_0;//        I2C_SCK=0; 
        Delay_10_uS(); 
} 

//******************************************************************** 
//主机发送非应答位 
//******************************************************************** 
void I2C_Nack(void) 
{ 
        Delay_10_uS(); 
        SDA_1;//        I2C_SDA=1; 
        Delay_10_uS(); 
        SCL_1;//        I2C_SCK=1; 
        Delay_10_uS(); 
        SCL_1;//        I2C_SCK=0; 
        Delay_10_uS(); 
} 

//******************************************************************** 
//*发送说明: 
//*在发送数据时,时钟线在高时,数据不能变化,只有在时钟为低时,数据才可变* 
//******************************************************************** 
void I2C_Send_Byte(char d) 
{ 
        char i = 8; 
        while( i-- ) 
        { 
                Delay_10_uS(); 
                if ( d &0x80 )   SDA_1;//I2C_SDA =1; 
                else             SDA_0;//I2C_SDA =0; 
                Delay_10_uS(); 
                SCL_1;//                I2C_SCK = 1; 
                Delay_10_uS(); 
                Nop(); 
                Nop(); 
                Nop(); 
                Nop(); 
                Nop(); 
                Nop(); 
                Nop(); 
                Nop(); 
                Nop(); 
                Nop(); 
                Nop(); 
                SCL_0;//                I2C_SCK = 0; 
                d = d << 1; 
        } 
        Delay_10_uS(); 
        SDA_1;//        I2C_SDA = 1; 
        Delay_10_uS(); 
        SCL_1;//        I2C_SCK = 1; 
        Delay_10_uS(); 
        Nop(); 
        Nop(); 
        Nop(); 
        Nop(); 
        Nop(); 
        Nop(); 
        Nop(); 
        Nop(); 
        Nop(); 
        SCL_0;//        I2C_SCK =0; 
        //Delay_10_uS(); 
} 

//******************************************************************** 
//延时 
//******************************************************************** 
void  Delay_10_uS(void) 
{ 
        Nop(); 
        Nop(); 
} 

//******************************************************************** 
//延时程序 
//******************************************************************** 
void Delay_N_mS( int n_milisecond)  /* n mS delay */ 
{ 
        char i; 
        while(n_milisecond--) 
        { 
                i=8; 
                while(i--); 
        } 
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -