手动直达. UCOSII移植到STM32F103C8T6上之应用记录(二).
原因:发现公司的板子上面有一个AT24C256C,闲着也是闲着,就写一下呗。。
AT24C256Cdatasheet和AT24Cxx中文版 提取码: mwqg
一,AT24C256C
AT24C256C是一个EEPROM,通过IIC通讯。
256K,地址16位,设备地址0xA0,512页,一页64字节。
因为我们的硬件工程师IIC引脚画反了,所以我选择软件IIC。
AT24C256C:16位地址其中有效数据只有15位,
低6(0~5)位地址表示的容量是0~63,
连续的9(6~14)位地址表示页码的范围是0~511,
在数据连续存储过程中,相同的页面内,存储地址自动完成累加过程;
数据在不同页面的存储时,地址不能自动累加,
如果不做正确处理,数据将从本页开始的地址重新开始覆盖已经存在的数据。
二,软件
用的是上一章UCOS的模板。也没啥好说的,记录下程序。
2.1引脚配置
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(I2C_SCL_GPIO_CLK | I2C_SDA_GPIO_CLK, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN;
GPIO_Init(I2C_SCL_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN;
GPIO_Init(I2C_SDA_GPIO_PORT, &GPIO_InitStructure);
}
2.2检测总线上是否有设备
/**
* @brief I2C_CheckDevice 检测总线上是否有设备
* @input _Address 设备地址
* @output true有 false没有
*/
bool I2C_CheckDevice(uint8_t _Address)
{
bool ucAck;
I2C_Start();
I2C_SendByte(_Address);
ucAck = I2C_WaitAck();
I2C_Stop();
return ucAck;
}
2.3写一个字节
/**
* @brief AT24CXX_WriteOneByte 写一个字节
* @input WriteAddr写地址 DataToWrite写数据
* @output true写成功 false写失败
*/
bool AT24C_WriteOneByte(uint16_t WriteAddr,uint8_t DataToWrite)
{
I2C_Start();
/*发送写命令*/
I2C_SendByte(0XA0);
if(I2C_WaitAck()==false) goto Run_Failure;
/*发送地址*/
I2C_SendByte(WriteAddr>>8);
if(I2C_WaitAck()==false) goto Run_Failure;
I2C_SendByte(WriteAddr%256);
if(I2C_WaitAck()==false) goto Run_Failure;
/*发送数据*/
I2C_SendByte(DataToWrite);
if(I2C_WaitAck()==false) goto Run_Failure;
I2C_Stop();
return true;
Run_Failure:
I2C_Stop();
return false;
}
2.4读一个字节
/**
* @brief AT24C_ReadOneByte 读一个字节
* @input ReadAddr 读地址
* @output temp 读到的数据
*/
uint8_t AT24C_ReadOneByte(uint16_t ReadAddr)
{
uint8_t temp=0;
I2C_Start();
/*发送写命令*/
I2C_SendByte(0XA0);
if(I2C_WaitAck()==false) goto Run_Failure;
/*发送地址*/
I2C_SendByte(ReadAddr>>8);
if(I2C_WaitAck()==false) goto Run_Failure;
I2C_SendByte(ReadAddr%256);
if(I2C_WaitAck()==false) goto Run_Failure;
I2C_Start();
/*发送读命令*/
I2C_SendByte(0XA1);
if(I2C_WaitAck()==false) goto Run_Failure;
temp=I2C_ReceiveByte();
I2C_Stop();
return temp;
Run_Failure:
I2C_Stop();
return 0;
}
2.5连续写字节
/**
* @brief AT24C_WritePageByte 连续写字节(小于等于64字节)
* @input WriteAddr写地址 DataAddr数据地址 DataSize数据长度
* @output true写成功 false写失败
*/
bool AT24C_WritePageByte(uint16_t WriteAddr,uint8_t *DataAddr,uint8_t DataSize)
{
uint8_t i;
if(DataSize>=64||DataSize==0) return false;
I2C_Start();
/*发送写命令*/
I2C_SendByte(0XA0);
if(I2C_WaitAck()==false) goto Run_Failure;
/*发送地址*/
I2C_SendByte(WriteAddr>>8);
if(I2C_WaitAck()==false) goto Run_Failure;
I2C_SendByte(WriteAddr%256);
if(I2C_WaitAck()==false) goto Run_Failure;
/*发送数据*/
for(i=0;i<DataSize;i++)
{
I2C_SendByte(DataAddr[i]);
// if(I2C_WaitAck()==false) goto Run_Failure;
I2C_Ack();
}
I2C_Stop();
return true;
Run_Failure:
I2C_Stop();
printf("Run_Failure:%02X\r\n",i);
return false;
}
2.6连续读字节
/**
* @brief AT24C_ReadPageByte 连续读字节(小于等于64字节)
* @input ReadAddr 读地址 DataAddr数据地址 DataSize数据长度
* @output temp 读到的数据
*/
void AT24C_ReadPageByte(uint16_t ReadAddr,uint8_t *DataAddr,uint8_t DataSize)
{
uint8_t i;
if(DataSize>=64||DataSize==0) return;
I2C_Start();
/*发送写命令*/
I2C_SendByte(0XA0);
if(I2C_WaitAck()==false) goto Run_Failure;
/*发送地址*/
I2C_SendByte(ReadAddr>>8);
if(I2C_WaitAck()==false) goto Run_Failure;
I2C_SendByte(ReadAddr%256);
if(I2C_WaitAck()==false) goto Run_Failure;
I2C_Start();
/*发送读命令*/
I2C_SendByte(0XA1);
if(I2C_WaitAck()==false) goto Run_Failure;
for(i=0;i<DataSize;i++)
{
DataAddr[i]=I2C_ReceiveByte();
if (i != DataSize - 1)
I2C_Ack();
else
I2C_NoAck();
}
I2C_Stop();
Run_Failure:
I2C_Stop();
}
2.7调用
void IICrom_App(void *padat)
{
uint8_t a[3],b[3]={0x33,0x44,0x55},err;
for (;;)
{
OSMutexPend(DispMutex, 0, &err);
if(I2C_CheckDevice(EE_DEV_ADDR) == false)
printf("ERROR_EEPROM!\r\n");
if(AT24C_WriteOneByte(0x0000,0x40) == false)
printf("ERROR_Send!\r\n");
Delay_ms(10);
printf("Save:%02X\r\n",AT24C_ReadOneByte(0x0000));
AT24C_WritePageByte(0x0000,b,3);
Delay_ms(10);
AT24C_ReadPageByte(0x0000,a,3);
printf("Save:");
Printf_Buff_Display(a,3);
OSMutexPost(DispMutex);
OSTimeDlyHMSM(0,0,1,100);
}
}