| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- #include "includes.h"
- #include "AT24C128.h"
- #include "stdio.h"
- //#include "sys.h"
- #include "delay.h"
- //#include "sys.h"
- /* AT24C128C organized as 256 pages of 64-bytes each
- AT24C512C, organized as 512 pages of 128 bytes each
- 不同的的EEPROM对应的页大小不一样,注意修改
- */
- #define PAGE_SIZE 64
- void I2C_init(void)
- {
-
- rcu_periph_clock_enable(RCU_GPIOB);//使能GPIOB时钟
- // rcu_periph_clock_enable(RCU_GPIOE);
- //解除写保护
- gpio_init(IIC_WP_PORT,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,IIC_WP_PIN);
- //打开写保护
- IIC_WRITE_PROTECT_ENABLE();
-
- //关闭写保护
- // IIC_WRITE_PROTECT_DISABLE();
- //IIC时钟信号位
- gpio_bit_set(IIC_SCL_PORT,IIC_SCL_PIN);
- gpio_init(IIC_SCL_PORT,GPIO_MODE_OUT_OD,GPIO_OSPEED_50MHZ,IIC_SCL_PIN);
-
- //IIC数据信号位
- gpio_bit_set(IIC_SDA_PORT,IIC_SDA_PIN);
- gpio_init(IIC_SDA_PORT,GPIO_MODE_OUT_OD,GPIO_OSPEED_50MHZ,IIC_SDA_PIN);
-
-
- }
- u8 iic_cmd_delay=0;
- /***********************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线输出
- // IIC_SDA_HIGH;
- // IIC_SCL_HIGH;
- // delay_us(4);
- // IIC_SDA_LOW;//START:when CLK is high,DATA change form high to low
- // delay_us(4);
- // IIC_SCL_LOW;//钳住I2C总线,准备发送或接收数据
-
- SDA_OUT();
- IIC_SDA(1);//IIC_SDA = 1;
- IIC_SCL(1);//IIC_SCL = 1;
- delay_us(4);
- IIC_SDA(0);//IIC_SDA = 0;//START:when CLK is high,DATA change form high to low
- delay_us(4);
- IIC_SCL(0);//IIC_SCL = 0;
- }
- //产生IIC停止信号
- void IIC_Stop(void)
- {
- // SDA_OUT();//sda线输出
- // IIC_SDA_LOW;
- // IIC_SCL_LOW;
- // delay_us(4);
- // IIC_SCL_HIGH;
- // IIC_SDA_HIGH;//发送I2C总线结束信号
- // delay_us(4);
- // iic_cmd_delay=0;
-
- SDA_OUT();
- IIC_SDA(0);//IIC_SDA = 0;
- IIC_SCL(0);//IIC_SCL = 0;
- delay_us(4);
- IIC_SCL(1);//IIC_SCL = 1;
- delay_us(4);
- IIC_SDA(1);//IIC_SDA = 1;
- delay_us(4);
- }
- //等待应答信号到来
- //返回值:
- // 1,接收应答失败
- // 0,接收应答成功
- u8 IIC_Wait_Ack(void)
- {
- // u8 ucErrTime=0;
- // SDA_IN(); //SDA设置为输入
- // IIC_SDA_HIGH;delay_us(1);
- // IIC_SCL_HIGH;delay_us(1);
- // while(READ_SDA)
- // {
- // ucErrTime++;
- // if(ucErrTime>250)
- // {
- // IIC_Stop();
- // return 1;
- // }
- // }
- // IIC_SCL_LOW;//时钟输出0
- // return 0;
-
- uint8_t ucErrTime=0;
- SDA_IN(); // SDA 配置成输入
- IIC_SDA(1);//IIC_SDA=1;
- delay_us(1);
- IIC_SCL(1);//IIC_SCL=1;
- delay_us(1);
- while(READ_SDA)
- {
- ucErrTime++;
- if(ucErrTime>250)
- {
- IIC_Stop();
- return 1;
- }
- }
- IIC_SCL(0);//IIC_SCL=0;
- return 0;
-
- }
- //产生ACK应答
- void IIC_Ack(void)
- {
- // IIC_SCL_LOW;
- // SDA_OUT();//sda线输出
- // IIC_SDA_LOW;
- // delay_us(4);
- // IIC_SCL_HIGH;
- // delay_us(2);
- // IIC_SCL_LOW;
-
- IIC_SCL(0);//IIC_SCL = 0;
- SDA_OUT();
- IIC_SDA(0);//IIC_SDA = 0;
- delay_us(4);
- IIC_SCL(1);//IIC_SCL = 1;
- delay_us(2);
- IIC_SCL(0);//IIC_SCL = 0;
- }
- //不产生ACK应答
- void IIC_NAck(void)
- {
- // IIC_SCL_LOW;
- // SDA_OUT();//sda线输出
- // IIC_SDA_HIGH;
- // delay_us(4);
- // IIC_SCL_HIGH;
- // delay_us(2);
- // IIC_SCL_LOW;
-
- IIC_SCL(0);//IIC_SCL = 0;
- SDA_OUT();
- IIC_SDA(1);//IIC_SDA = 1;
- delay_us(4);
- IIC_SCL(1);//IIC_SCL = 1;
- delay_us(2);
- IIC_SCL(0);//IIC_SCL = 0;
- }
- //IIC发送一个字节
- //返回从机有无应答
- //1,有应答
- //0,无应答
- void IIC_Send_Byte(u8 txd)
- {
- // u8 t;
- // IIC_SCL_LOW;//拉低时钟开始数据传输
- // SDA_OUT();
- // for(t=0;t<8;t++)
- // {
- //// IIC_SDA=(txd&0x80)>>7;
- //// SDA_OUT();
- // if((txd&0x80)>>7)
- // IIC_SDA_HIGH;
- // else
- // IIC_SDA_LOW;
- // txd<<=1;
- // delay_us(4); //对TEA5767这三个延时都是必须的
- // IIC_SCL_HIGH;
- // delay_us(2);
- // IIC_SCL_LOW;
- // delay_us(2);
- // }
-
- uint8_t t;
- IIC_SCL(0);//IIC_SCL=0;// 电平置低,开始传输数据
- SDA_OUT();
- for(t=0;t<8;t++)
- {
- // IIC_SDA=(txd&0x80)>>7;
- if((txd&0x80)>>7) IIC_SDA(1);
- else IIC_SDA(0);
- txd<<=1;
- delay_us(4); //
- IIC_SCL(1);//IIC_SCL=1;
- delay_us(2);
- IIC_SCL(0);//IIC_SCL=0;
- delay_us(2);
- }
- }
- //读1个字节,ack=1时,发送ACK,ack=0,发送nACK
- u8 IIC_Read_Byte(u8 ack)
- {
- // u8 i,receive=0;
- // SDA_IN();//SDA设置为输入
- // for(i=0;i<8;i++ )
- // {
- // IIC_SCL_LOW;
- // delay_us(4);
- // IIC_SCL_HIGH;
- // receive<<=1;
- // if(READ_SDA)receive++;
- // delay_us(1);
- // }
- // if (!ack)
- // IIC_NAck();//发送nACK
- // else
- // IIC_Ack(); //发送ACK
- // return receive;
-
- uint8_t i,receive=0;
- SDA_IN();//SDA设置为输入
- for(i=0;i<8;i++ )
- {
- IIC_SCL(0);//IIC_SCL=0;
- delay_us(4);
- IIC_SCL(1);//IIC_SCL=1;
- receive<<=1;
- if(READ_SDA)receive++;
- delay_us(1);
- }
- if(!ack)
- IIC_NAck();//发送nACK
- else
- IIC_Ack(); //发送ACK
- return receive;
- }
- /***********************以上为IIC驱动**************************/
- /***********************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();//产生一个停止条件
- delay_us(4);
- 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();//产生一个停止条件
-
- delay_ms(10);//两次写操作,必须加间隔,否则写不进去
- }
- //在AT24CXX里面的指定地址开始读出指定个数的数据
- //ReadAddr :开始读出的地址 对24c02为0~255
- //pBuffer :数据数组首地址
- //NumToRead:要读出数据的个数
- void AT24CXX_Read(u32 ReadAddr,u8 *pBuffer,u16 NumToRead)
- {
- // OS_ERR err;
- u8 addrH,addrL;
- u16 lentmp,lentow,lens;
- u8 tmp;
- if(NumToRead==0)
- return;
-
- // I2C_init();
- // OSTimeDlyHMSM(0, 0, 0, 40, OS_OPT_TIME_DLY, &err);
- // delay_ms(1);//40
- delay_us(500);
-
- lentmp=NumToRead;
- while(lentmp)
- {
- tmp=ReadAddr%PAGE_SIZE;
- tmp=PAGE_SIZE-tmp;
- if(tmp>=lentmp)//当页剩余空间大于要写入的长度
- {
- lentow=lentmp;
- }
- else
- {
- lentow=tmp;//写入长度只能是剩余空间长度
- }
- lentmp=lentmp-lentow;//计算要在下一页写入的长度
- lens=lentow;
- 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();
- delay_us(4);
- IIC_Start();
- IIC_Send_Byte(0xa1); //读 //进入接收模式
- IIC_Wait_Ack();
- while(lentow)
- {
- *pBuffer=IIC_Read_Byte(1);
- pBuffer++;
- //ReadAddr++;
- lentow--;
-
- }
- IIC_Read_Byte(0);
- IIC_Stop();//产生一个停止条件
- delay_us(4);
- //printf("at24 read %d %d\r\n", ReadAddr, lens);
- ReadAddr=ReadAddr+lens;//下一页的地址
- }
- //打开写保护
- // IIC_WRITE_PROTECT_ENABLE();
- }
- //在AT24CXX里面的指定地址开始写入指定个数的数据
- //WriteAddr :开始写入的地址 对24c02为0~255
- //pBuffer :数据数组首地址
- //NumToWrite:要写入数据的个数
- // 每128bytes为一个page,写操作不能跨页
- void AT24CXX_Write(u32 WriteAddr,u8 *pBuffer,u16 NumToWrite)
- {
- // OS_ERR err;
- u8 addrH,addrL;
- u16 lentmp,lentow,lens;
- u8 tmp;
-
- if(NumToWrite==0)
- return;
-
- // I2C_init();
- //关闭写保护
- IIC_WRITE_PROTECT_DISABLE();
- // OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_DLY, &err);
- // delay_ms(1);//10
- delay_us(500);
- 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();//产生一个停止条件
- delay_ms(10);
- // OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_DLY, &err);
- //printf("at24 write %d %d %d, %d\r\n", WriteAddr, lens, addrH, addrL);
- WriteAddr=WriteAddr+lens;//下一页的地址
- }
-
- // delay_ms(10);//两次写操作,必须加间隔,否则写不进去
- // OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_DLY, &err);
-
- //打开写保护
- IIC_WRITE_PROTECT_ENABLE();
- }
- void AT24CXX_clr(u32 WriteAddr,u32 NumToWrite)
- {
- u8 addrH,addrL;
- u16 lentmp,lentow,lens;
- u8 tmp;
-
- //关闭写保护
- IIC_WRITE_PROTECT_DISABLE();
- 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();//产生一个停止条件
- delay_ms(10);
- WriteAddr=WriteAddr+lens;
- }
- //打开写保护
- IIC_WRITE_PROTECT_ENABLE();
- delay_ms(10);
- }
- //----------------------EEPROM---------------------------//
- //--------------------------------------------------------EEPROM DATA
- /*********************************************END OF FILE**********************/
- #define I2C_DATA_LEN 256
- u8 I2c_Buf_Write[I2C_DATA_LEN], I2c_Buf_Read[I2C_DATA_LEN];
- /**
- * @brief I2C(AT24C02)读写测试
- * @param 无
- * @retval 正常返回 1 ,不正常返回 0
- */
- uint8_t I2C_Test(void)
- {
- u16 i;
- I2C_init();
- EEPROM_INFO("\r\nI2C(AT24C128)字节读写测试\r\n");
- memset(I2c_Buf_Write, 0, I2C_DATA_LEN);
- memset(I2c_Buf_Read, 0, I2C_DATA_LEN);
- // for ( i=0; i< I2C_DATA_LEN; i++ ) //填充缓冲
- // {
- // I2c_Buf_Write[i] = i+9;
- // AT24CXX_WriteOneByte(i, i);
- // I2c_Buf_Read[i] = AT24CXX_ReadOneByte(i);
- // }
- // data_dump("I2C Write", I2c_Buf_Write, I2C_DATA_LEN);
- // data_dump("I2C Read", I2c_Buf_Read, I2C_DATA_LEN);
- EEPROM_INFO("\r\nI2C(AT24C128)连续地址读写测试\r\n");
- memset(I2c_Buf_Write, 0, I2C_DATA_LEN);
- memset(I2c_Buf_Read, 0, I2C_DATA_LEN);
- for ( i=0; i< I2C_DATA_LEN; i++ ) //填充缓冲
- {
- I2c_Buf_Write[i] = i+1;
- }
- AT24CXX_clr(512, I2C_DATA_LEN);
- delay_ms(10);
- AT24CXX_Read(512, I2c_Buf_Read, I2C_DATA_LEN);
- data_dump("I2C Read", I2c_Buf_Read, I2C_DATA_LEN);
- delay_ms(10);
-
- AT24CXX_Write(512, I2c_Buf_Write, I2C_DATA_LEN);
- delay_ms(10);
- AT24CXX_Read(512, I2c_Buf_Read, I2C_DATA_LEN);
- data_dump("I2C Write", I2c_Buf_Write, I2C_DATA_LEN);
- data_dump("I2C Read", I2c_Buf_Read, I2C_DATA_LEN);
-
- EEPROM_INFO("\r\nI2C(AT24C128)读写测试成功\r\n");
- return 1;
- }
|