📄 1024.c
字号:
#include "1024.h"
void I2CStart(void)
{
SET_SDA_FOR_OUTPUT; //msp430复位的I/O默认状态是输入,所以
SET_SCL_FOR_OUTPUT; //先设为输出
SDA_1; //I2CStart的条件是在SCL是高电平的情况下
SCL_1; //SDA有一个从高电平向低电平的跳变
SDA_0;
SCL_0;
}
void I2CStop(void)
{
SET_SDA_FOR_OUTPUT; // 这两句也可以不要 ,加上更好
SET_SCL_FOR_OUTPUT;
SDA_0; //I2CStop的条件是在SCL是低电平的情况下
SCL_1;
SDA_1;
clr_watchdog();
}
BOOL I2CSendByte(BYTE ByteData) //I2C的基本传送方式是字节发送
{
BOOL ack;
BYTE i;
for (i = 0; i < 8; i++) //主器件通过SCL发出8个时钟脉冲将要发送的
{ //数据通过SDA发出
SCL_0;
if (ByteData&0x80)
SDA_1;
else
SDA_0;
ByteData <<= 1;
SCL_1;
}
SCL_0; //在第9个时钟时读取从件(ATC1024)发送的
SET_SDA_FOR_INPUT; //ack应答信号,此时SDA应为输入状态,SDA
//为输入状态时,SDA是高电平
//***注意在设置SDA为输入时,一定要先使SCL
SCL_1; //是低电平,千万不能使SCL为高电平,因为在
//SCL是高电平的情况下,有可能出现SDA从低
ack = READ_SDA; //到高的跳变(I2CStop状况)发送失败,
SCL_0;
SET_SDA_FOR_OUTPUT;
return (ack); //返回ack信号,低电平表示有应答,高则没有
}
BYTE I2CReceiveByte(BOOL last_char)
{
BYTE data=0, i;
SET_SDA_FOR_INPUT; //主器件通过8个时钟信号,接收从件发出的数据
for (i = 0; i < 8; i++)
{
SCL_0;
SCL_1;
data <<=1;
if (READ_SDA) data++;
}
SCL_0;
if (last_char) //如果接收是最后的一个字节时,主器件在第9个
SET_SDA_FOR_INPUT; //给从件一个高电平信号,否则给一个低电平信号,
else //表示继续接收
SET_SDA_FOR_OUTPUT;
SDA_0;
SCL_1;
SCL_0;
return data;
}
//对1024采用的是页写的方式,需要的参数是九位的页地址,八位的页内地址
//要传送数据的地址,传送数据的长度
//ATC1024分两块,每块256页,每页256个字节
BOOL TryWrite1024(UINT page, BYTE addr, BYTE *data, int len)
{
int i;
BYTE device, NUM;
while (len)
{
device = 0xa4;
if (page > 255) device += 2; //如果页数大于256,则块数加1,即device加2
I2CStart();
if (I2CSendByte(device)) return FALSE; //发送器件地址,没有应答信号表示失败
if (I2CSendByte(page & 0xFF)) return FALSE; //发送页地址,没有应答信号表示失败
if (I2CSendByte(addr)) return FALSE; //发送字节地址,没有应答信号表示失败
if (addr + len > 255) //如果所写数据跨页,进行相应的处理
NUM = 256 - addr; //先写当前页,再在下页写完余下的数据
else
NUM = len;
len -= NUM;
for(i = 0; i < NUM; i++)
if( I2CSendByte(*data++))return FALSE ;
I2CStop();
if (len)
{
page++;
addr=0;
Delay(10000); //延时1MS子程序,每次写完后需要
}
}
return TRUE; // 页写成功
}
BOOL TryRead1024(UINT page, BYTE addr, BYTE *data, int len)
{
int i;
unsigned int device, NUM;
while (len)
{
device = 0xa4;
if (page > 255) device += 2;
I2CStart();
if (I2CSendByte(device)) return FALSE; //发送器件地址,没有应答信号表示失败
if (I2CSendByte(page & 0xFF)) return FALSE; //发送页地址,没有应答信号表示失败
if (I2CSendByte(addr)) return FALSE; //发送字节地址,没有应答信号表示失败
I2CStart(); //如果所读数据跨页,进行相应的处理
if (I2CSendByte(device + 1)) return FALSE;
if (addr + len > 255)
NUM = 256 - addr;
else
NUM = len;
len -= NUM;
for (i = 0; i < NUM - 1 ; i++)
*data++ = I2CReceiveByte(FALSE); //没有读完时,主器件就发出继续读的信号
*data++ = I2CReceiveByte(TRUE); //读完了,主器件就发出停止信号
I2CStop();
if (len > 0)
{
page++;
addr=0;
Delay(10000);
}
}
return TRUE;
}
BOOL Write1024(UINT page, BYTE addr, BYTE *data, int len ,BOOL is_delay)
{
int i,t;
if(page>511) return FALSE;
// if( (CommState.DoWrParm==0) &&((page ==0) ||(page ==505)) )
if( (page ==0) ||(page ==505))
{ if(CommState.DoWrParm ==0)
return FALSE;
}
for(i=0;i<1000;i++)
{
if(WriteDelay==0) break;
Delay(500);
}
WP_Disable ;
for(t=0;t<3;t++)
{
i=TryWrite1024(page, addr, data, len);
if(i) break;
}
WriteDelay=10;
WP_Enable ;
return i;
}
BOOL Read1024(UINT page, BYTE addr, BYTE *data, int len)
{
int i,r;
if(page>511) return FALSE;
for(i=0;i<1000;i++)
{
if(WriteDelay==0) break;
Delay(500);
}
for (i = 3; i; i--)
{
r=TryRead1024(page, addr, data, len);
if (r)break;
I2CStop();
}
return r;
}
void Delay(UINT us)
{
int i;
for (i = us >> 3; i; i--)
clr_watchdog();
_NOP();
}
//历史数据:若15分钟存一次:保存7天 ,一天96条,每条记录76个字节,一页存两条记录,每天占48页,共占336页
// 若30分钟存一次:保存15天,一天48条,每条记录76个字节,一页存两条记录,每天占24页,共占360页
// 若1小时存一次:保存31天,一天24条,每条记录76个字节,一页存两条记录,每天占12页,共占372页
//统计数据:保存2个月,一天一条记录,每条记录占两页,共128页
UINT Get1024Page( STDATETIME data,char modeIsSt) //得到页首地址
{
UINT PageAddr=512;
// if(data.week_date > 31) return 512;
// if(data.month > 12) return 512;
if(modeIsSt == HISDATA)
{
PageAddr =(( (data.week_date&0x1f)%((HisCate<<3) - 1))*(48/HisCate))+1; //得到这一天的数据存贮的首地址
}
if(modeIsSt==STATICSDATA)
{
PageAddr=(data.month&0x1);
PageAddr<<=6;
PageAddr+=(373 +((data.week_date&0x1f)<<1)); //存两个月的统计数据
}
return PageAddr;
}
BYTE GetAddrInPage(STDATETIME st)//得到页内地址
{
BYTE AddrInPage = 0;
if(st.hour > 23 )
{
ptr_1024=512;
return 0;
}
switch(HisCate)
{
case 1: ptr_1024 += (st.hour<<1);
ptr_1024 += (st.minute/30);
if(st.minute == 15 || st.minute == 45)
AddrInPage += (1<<7);
break;
case 2: ptr_1024 += st.hour;
AddrInPage += ((st.minute/30)<<7);
break;
case 4: ptr_1024 += (st.hour>>1);
AddrInPage += ((st.hour&0x01)<<7);
break;
default: break;
}
return AddrInPage;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -