河北水利局项目

This commit is contained in:
2025-12-15 16:07:49 +08:00
commit f11a7c2b95
1146 changed files with 452892 additions and 0 deletions

673
APP/bl24c512.c Normal file
View File

@@ -0,0 +1,673 @@
#include "bl24c512.h"
#include "include.h"
static u32 last_write_time;
bool I2C_eeprom_write_byte( u16 addr, u8 data);
bool I2C_eeprom_Read_byte(u16 addr, u8 *data);
void eeprom_da_mode(bool in_mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = (in_mode == TRUE) ? GPIO_Mode_IN_FLOATING : GPIO_Mode_Out_OD;
GPIO_Init(SDA_PIN_PORT, &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SCL_PIN_PORT , &GPIO_InitStructure );
}
/*************************************************************
函数功能:延时连个指令周期
函数名称delayedus
函数返回:无返回值。
函数参数:延时时间
**************************************************************/
void delayed_ms(u8 n)
{
u32 dy;
u8 i;
for(i=0;i<n;i++)
{
dy=3200;
while(dy!=0)
{dy--;}
}
}
void delayedus(u8 n)
{
u8 i;
for(i=0;i<n;i++);
}
/*************************************************************
函数功能I2C总线复位。
函数名称I2C_Reset。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void I2C_Reset(void)
{
eeprom_da_mode(SDA_MODE_IN);
while(1)
{
SCL_LOW();
delayedus(1);
SCL_HIGH();
if( GET_SDA() ==1 )
{
break;
}
delayedus(1);
}
eeprom_da_mode(SDA_MODE_OUT);
}
void bl24c512_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(SDA_PIN_CLK | SCL_PIN_CLK , ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SDA_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(SDA_PIN_PORT , &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = SCL_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(SCL_PIN_PORT , &GPIO_InitStructure );
//I2C_Reset();
}
/*************************************************************
函数功能:产生起始位。
函数名称I2C_GenerateSTART。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void BL24C512I2C_GenerateSTART(void)
{
SDA_HIGH();//eeprom_da(1);
SCL_HIGH();//eeprom_clk(1);
delayedus(2);
SDA_LOW();//eeprom_da(0);
delayedus(2);
SCL_LOW();//eeprom_clk(0);
delayedus(2);
}
/*************************************************************
函数功能:产生停始位。
函数名称I2C_GenerateSTOP。
函数返回:无返回值。
函数参数:无参数
**************************************************************/
void BL24C512_I2C_GenerateSTOP(void)
{
SDA_LOW();//eeprom_da(0);
delayedus(2);
SCL_HIGH();//eeprom_clk(1);
SDA_LOW();//eeprom_da(0);
delayedus(2);
SDA_HIGH();//eeprom_da(1);
}
void self_test_eeprom(void)
{
char testBuf[] = "test eeprom";
char buf[15] = {0};
I2C_eeprom_write_buf(32896, (u8*)testBuf, sizeof(testBuf));
I2C_eeprom_read_buf( 32896, (u8*)buf, sizeof(testBuf));
if (cmp_datas((u8*)buf, (u8*)testBuf, sizeof(testBuf)))
{
printf("OK\r\n");
}
else
{
printf("ERROR\r\n");
}
}
/*************************************************************
函数功能:检测应答。
函数名称I2C_check_ack。
函数返回:返回值是应答状态。
函数参数:无参数。
**************************************************************/
unsigned char I2C_check_ack(void)
{
unsigned char ack=0;
eeprom_da_mode(SDA_MODE_IN);
SCL_HIGH();//eeprom_clk(1);
delayedus(1);
if(GET_SDA() ==1)
{
ack=0;
}
else
{
ack=1;
}
SCL_LOW();//eeprom_clk(0);
delayedus(1);
eeprom_da_mode(SDA_MODE_OUT);
return ack;
}
/*************************************************************
函数功能:发送一个应答位。
函数名称I2c_send_ack。
函数返回:无返回值。
函数参数:无。
**************************************************************/
void I2c_send_ack(void)
{
SDA_LOW();//eeprom_da(0);
delayedus(1);
SCL_LOW();//eeprom_clk(0);
delayedus(1);
SCL_HIGH();//eeprom_clk(1);
delayedus(1);
SCL_LOW();//eeprom_clk(0);
SDA_HIGH();//eeprom_da(1);
}
/*************************************************************
函数功能发送一个NO应答。
函数名称I2c_send_no_ack。
函数返回:无返回值。
函数参数:无。
*************************************************************/
void I2c_send_no_ack(void)
{
SDA_HIGH();//eeprom_da(1);
delayedus(1);
SCL_LOW();//eeprom_clk(0);
delayedus(1);
SCL_HIGH();//eeprom_clk(1);
delayedus(1);
SCL_LOW();//eeprom_clk(0);
}
/*************************************************************
函数功能I2C发送一个字节。
函数名称I2c_send_byte。
函数返回:无返回值。
函数参数:无。
*************************************************************/
void I2c_send_byte(unsigned char data )
{
unsigned char i;
SCL_LOW(); //eeprom_clk(0);//clk 0
for(i=0;i<8;i++)
{
if((data&0x80)==0x80)
{
SDA_HIGH();//eeprom_da(1);
}
else
{
SDA_LOW(); //eeprom_da(0);
}
SCL_HIGH(); //eeprom_clk(1);//clk 1
delayedus(1);
SCL_LOW(); //eeprom_clk(0);//clk 0
delayedus(1);
data<<=1;
}
delayedus(90);
}
/*************************************************************
函数功能I2C接收一个字节。
函数名称I2c_receive_byte。
函数返回:无返回值。
函数参数:无。
**************************************************************/
unsigned char I2c_receive_byte(void)
{
unsigned char i;
unsigned char rda=0;
eeprom_da_mode(SDA_MODE_IN);
SCL_LOW(); //eeprom_clk(0);//clk 0
delayedus(1);
for(i=0;i<8;i++)
{
rda<<=1;
SCL_HIGH(); //eeprom_clk(1);//clk 1
delayedus(1);
if(GET_SDA() ==1 )
{
rda|=0x01;
}
else
{
rda&=0xFE;
}
SCL_LOW(); //eeprom_clk(0);//clk 0
delayedus(1);
}
eeprom_da_mode(SDA_MODE_OUT);
return rda;
}
/*************************************************************
函数功能EEPROM检测EEPROM是否空闲可以进行读写
函数名称poll_busy。
函数返回:无返回值。
函数参数EEPROM的地址addr 对应写入数据data。
**************************************************************/
bool poll_busy(void)
{
BL24C512I2C_GenerateSTART();
I2c_send_byte(BL24C512ADDR);
if(I2C_check_ack()== 1)
{
BL24C512_I2C_GenerateSTOP();
return TRUE;
}
else
{
BL24C512_I2C_GenerateSTOP();
return FALSE;
}
}
void wait_eeprom_free(void)
{
while( last_write_time + 6/portTICK_RATE_MS > xTaskGetTickCount() );
while (1)
{
if (poll_busy())
{
break;
}
}
}
/*************************************************************
函数功能EEPROM任意地址写一字节。
函数名称I2C_eeprom_write_byte。
函数返回:无返回值。
函数参数EEPROM的地址addr 对应写入数据data。
**************************************************************/
bool I2C_eeprom_write_byte( u16 addr, u8 data)
{
unsigned char addrlow;
unsigned char addrhigh;
addrlow=(unsigned char)addr;
addrhigh=(unsigned char)(addr>>8);
wait_eeprom_free();
BL24C512I2C_GenerateSTART();
I2c_send_byte(BL24C512ADDR);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrhigh);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrlow);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(data);
if(I2C_check_ack()==0)
{
return FALSE;
}
BL24C512_I2C_GenerateSTOP();
last_write_time = xTaskGetTickCount();
return TRUE;
}
/*************************************************************
函数功能EEPROM任意地址读一字节。
函数名称I2C_eeprom_Read_byte。
函数返回:无返回值。
函数参数EEPROM的地址addr。
**************************************************************/
bool I2C_eeprom_Read_byte(u16 addr, u8 *data)
{
unsigned char devaddr=0;
unsigned char addrlow=0;
unsigned char addrhigh=0;
addrlow=(unsigned char)addr;
addrhigh=(unsigned char)(addr>>8);
wait_eeprom_free();
BL24C512I2C_GenerateSTART();
I2c_send_byte(BL24C512ADDR);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrhigh);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrlow);
if(I2C_check_ack()==0)
{
return FALSE;
}
devaddr=(BL24C512ADDR| 0X01);
BL24C512I2C_GenerateSTART();
I2c_send_byte(devaddr);
if(I2C_check_ack()==0)
{
return FALSE;
}
*data=I2c_receive_byte();
I2c_send_no_ack();
delayedus(1);
BL24C512_I2C_GenerateSTOP();
return TRUE;
}
/*************************************************************
函数功能EEPROM写入数组只能写入小于128byte数据并且不能超过页范围
函数名称I2C_eeprom_write_buf
函数返回:无返回值。
函数参数EEPROM的地址addr。
**************************************************************/
bool I2C_eeprom_write_page(u16 addr, u8 * buf, u8 length)
{
unsigned char addrlow;
unsigned char addrhigh;
addrlow=(unsigned char)addr;
addrhigh=(unsigned char)(addr>>8);
wait_eeprom_free();
BL24C512I2C_GenerateSTART();
I2c_send_byte(BL24C512ADDR);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrhigh);
if(I2C_check_ack()==0)
{
return FALSE;
}
I2c_send_byte(addrlow);
if(I2C_check_ack()==0)
{
return FALSE;
}
for (u8 i = 0; i < length; i++)
{
I2c_send_byte(buf[i]);
if(I2C_check_ack()==0)
{
return FALSE;
}
}
BL24C512_I2C_GenerateSTOP();
last_write_time = xTaskGetTickCount();
return TRUE;
}
/*************************************************************
函数功能EEPROM写入数组只能写入小于128byte数据并且不能超过页范围
函数名称I2C_eeprom_write_buf
函数返回:无返回值。
函数参数EEPROM的地址addr。
**************************************************************/
bool I2C_eeprom_write_buf(u16 startAddr, u8 * buf, u16 length)
{
bl24c512_init();
u16 current_startAddr = startAddr;
u8 first_page_byte = EEPROM_PAGE_SIZE - (startAddr % EEPROM_PAGE_SIZE);
u8 * current_data_ptr = buf;
u16 left_length = length;
u16 integrated_Pages;
u16 end_page_byte;
if (length > first_page_byte)
{
if (!I2C_eeprom_write_page(current_startAddr, current_data_ptr, first_page_byte))
{
return FALSE;
}
current_startAddr = current_startAddr + first_page_byte;
current_data_ptr += first_page_byte;
left_length = length - first_page_byte;
integrated_Pages = left_length / EEPROM_PAGE_SIZE;
end_page_byte = left_length % EEPROM_PAGE_SIZE;
for (u16 i = 0; i < integrated_Pages; i++)
{
if (!I2C_eeprom_write_page(current_startAddr, current_data_ptr, EEPROM_PAGE_SIZE))
{
return FALSE;
}
current_startAddr += EEPROM_PAGE_SIZE;
current_data_ptr += EEPROM_PAGE_SIZE;
}
if (end_page_byte > 0)
{
if (!I2C_eeprom_write_page(current_startAddr, current_data_ptr, end_page_byte))
{
return FALSE;
}
}
}
else
{
if(!I2C_eeprom_write_page(startAddr, buf, length))
{
return FALSE;
}
}
return TRUE;
}
/*************************************************************
函数功能EEPROM读出数组
函数名称I2C_eeprom_write_buf
函数返回:无返回值。
函数参数EEPROM的地址addr。
**************************************************************/
bool I2C_eeprom_read_buf(u16 addr, u8 * buf, u16 length)
{
unsigned char devaddr;
if (length == 0)
{
return FALSE;
}
wait_eeprom_free();
bl24c512_init();
if (I2C_eeprom_Read_byte(addr, buf) == FALSE)
{
return FALSE;
}
length--;
if (length > 0)
{
devaddr=(BL24C512ADDR| 0X01);
BL24C512I2C_GenerateSTART();
I2c_send_byte(devaddr);
if(I2C_check_ack()==0)
{
return FALSE;
}
for (u16 i = 0; i < length; i++)
{
buf[i+ 1] = I2c_receive_byte();
if (i < length - 1)
{
I2c_send_ack();
}
}
I2c_send_no_ack();
BL24C512_I2C_GenerateSTOP();
}
return TRUE;
}