📄 general.c
字号:
#include <Reg936.h>
#define _GENERAL_DEFINE
#include <General.h>
#define GENERATE_STOP 0x54 // 置位 STO, 复位 STA 、 SI
#define RELEASE_BUS_ACK 0x44 // 复位 STO,STA,SI 并置位 AA (ack)
#define RELEASE_BUS_NOACK 0x40 // 复位 STO,STA,SI 并清除 AA (noack)
#define RELEASE_BUS_STA 0x64 // 起动总线/重新起动总线, 置位 STA
bit AckBus(void);
bit GetBus(void);
bit SendByte(uchar value);
//**********************************************************
// 总线响应
//功能:
//入口参数:无
//**********************************************************
bit AckBus(void)
{
uchar TimeOut;
TimeOut = 0xFF;
while(SI==0)
{
TimeOut--;
if( TimeOut==0x00 ) //100uS无响应,超时退出
{
I2CON = GENERATE_STOP;
return(0);
}
}
return(1); //有响应,即SI==1,返回值1
}
//**********************************************************
// 总线申请
//功 能:进行I2C总线的初始化:包括时钟选择,I2C使能,发送起
// 始信号等等;I2EN为1,设置为主机;CRSEL位为0,使用内
// 部SCL发生器.
//入口参数:无
//**********************************************************
bit GetBus(void)
{ // CCLK为7.3728MHz,参数0x14 实际总线频率为 92KHz
I2SCLH = 0x14; // 设置SCL高电平的PCLK周期数
I2SCLL = 0x14; // 设置SCL低电平的PCLK周期数
I2CON = RELEASE_BUS_STA;// 申请成为主机,起动总线。使用内部SCL发生器,I2EN和AA置位
//while( SI==0 ); // 等待起始位的发送
return(AckBus());
}
//**********************************************************
// 发送数据函数
//功 能:用于向总线发送数据
//入口参数:value 待发送的数据
//**********************************************************
bit SendByte(uchar value)
{
I2DAT = value;
I2CON = RELEASE_BUS_ACK; //清除SI位等等
//while( SI==0 ); //等待数据的发送
return(AckBus());
}
//**********************************************************
// 向有子地址器件发送多字节数据函数
//功 能:从启动总线到发送器件地址,子地址,数据,结束总线的全过程。
//入口参数:AddrPtr 地址指针
// DataPrt 数据指针
// Ptr_length 地址、数据长度
//出口参数:返回1表示操作成功,否则操作有误。
//**********************************************************
bit ISendStr(uchar idata *AddrPtr,uchar idata *DataPrt,uchar idata *Ptr_length)
{
uchar i;
uchar Addr_len;
uchar Data_len;
Addr_len = *Ptr_length; //地址长度
Ptr_length++; //数据长度
Data_len = *Ptr_length;
if(GetBus()==0) return(0); //启动总线
if(SendByte(*AddrPtr)==0) return(0); //发送器件地址
if( I2STAT!=0x18 )
{
I2CON = GENERATE_STOP;
return(0);
}
for(i=1;i<Addr_len;i++)
{
AddrPtr++;
if(SendByte(*AddrPtr)==0) return(0); //发送器件子地址
if(I2STAT!=0x28)
{
I2CON = GENERATE_STOP;
return(0);
}
}
for(i=0; i<Data_len; i++)
{
if(SendByte(*DataPrt)==0) return(0); //发送数据
if( I2STAT!=0x28 )
{
I2CON = GENERATE_STOP;
return(0);
}
DataPrt++;
}
I2CON = GENERATE_STOP; //结束总线
return(1);
}
//**********************************************************
// 向有子地址器件读取多字节数据函数
//功 能:从启动总线到发送地址,子地址,读数据,结束总线的全过程。
//入口参数:AddrPtr 地址指针
// DataPrt 数据指针
// Ptr_length 地址、数据长度
//出口参数:函数返回1表示操作成功,否则操作有误。
//**********************************************************
bit IRcvStr(uchar idata *AddrPtr,uchar idata *DataPrt,uchar idata *Ptr_length)
{
uchar i;
uchar Addr_len;
uchar Data_len;
uchar read;
read = *AddrPtr+1; //取从器件地址
Addr_len = *Ptr_length; //地址长度
Ptr_length++; //数据长度
Data_len = *Ptr_length;
if(GetBus()==0) return(0); // 启动总线
if(SendByte(*AddrPtr)==0) return(0); //发送器件地址
if( I2STAT!=0x18 )
{
I2CON = GENERATE_STOP;
return(0);
}
for(i=1;i<Addr_len;i++) //发送器件子地址
{
AddrPtr++;
if(SendByte(*AddrPtr)==0) return(0);
if( I2STAT!=0x28 )
{
I2CON = GENERATE_STOP;
return(0);
}
}
I2CON = RELEASE_BUS_STA; //重新启动总线
//while( SI==0 );
if(AckBus()==0) return(0);
if(SendByte(read)==0) return(0);
if( I2STAT!=0x40 )
{
I2CON = GENERATE_STOP;
return(0);
}
for(i=0; i<Data_len-1; i++)
{
I2CON = RELEASE_BUS_ACK; //接收一字节数据并发送应答位(预置应答位)
//while( SI==0 ); //等待接收数据
if(AckBus()==0) return(0);
if(I2STAT!=0x50)
{
I2CON = GENERATE_STOP;
return(0);
}
*DataPrt = I2DAT; //读取数据
DataPrt++;
}
I2CON = RELEASE_BUS_NOACK; //接收最后一字节数据并发送非应答位
//while( SI==0 );
if(AckBus()==0) return(0);
*DataPrt = I2DAT; //读取最后一个数据
I2CON = GENERATE_STOP; //结束总线
return(1);
}
//**********************************************************
//名称:DelayNmS()
//功能:
//说明:
//**********************************************************
void DelayNms(uchar value)
{
uchar i;
uchar j;
while(value--)
{
//1ms=10*100us
for(i=0;i<10;i++)
{
//100us
j=184;
while(--j);
}
}
}
//**********************************************************
//名称:ArrayInit()
//功能:
//说明:数组清零
//**********************************************************
void ArrayInit(uchar *ptr,uchar len)
{
uchar i;
i= 0x00;
do
{
*ptr = 0x00;
ptr++;
i++;
}while(i<len);
}
//**********************************************************
//名称:BCDCHK()
//功能:
//说明:BCD检查
//**********************************************************
bit BCDCHK(uchar idata *ptr,uchar len)
{
uchar i;
uchar Temp;
i=0x00;
do
{
Temp = *ptr;
if( (Temp&0x0F)>0x09 || (Temp&0xF0)>0x90 ) return(0);
ptr++;
i++;
}while(i<len);
return(1);
}
//**********************************************************
//名称:BCD2HEX()
//功能:
//说明:BCD转HEX
//**********************************************************
uchar BCD2HEX(uchar BCDdata)
{
uchar Temp;
Temp = (BCDdata>>4)*10;
Temp += BCDdata&0x0F;
return Temp;
}
//**********************************************************
//名称:HEX2BCD()
//功能:
//说明:HEX转BCD
//**********************************************************
uchar HEX2BCD(uchar HEXdata)
{
uchar Temp,tHEXdata;
tHEXdata = HEXdata;
if(tHEXdata>99) tHEXdata = 99;
Temp = (tHEXdata/10)<<4;
Temp += tHEXdata%10;
return Temp;
}
//**********************************************************
//名称: BCDINC()
//功能: 多字节BCD码加1子程序
//说明: 要求BCD数组低字节在前,高字节在后
// pSbuf1--->数组首地址, Svar1--->数组长度
// 返回值: 1-->有进位, 0-->无进位
//**********************************************************
uchar BCDINC(uchar idata *pSbuf1,uchar Svar1)
{
//if(Svar1==0) return 0;
while (Svar1!=0)
{
(*pSbuf1)++;
if((*pSbuf1&0x0F)>=10)
{
*pSbuf1 += 6;
if(*pSbuf1>=0xA0)
{
*pSbuf1=0;
pSbuf1++;
Svar1--;
}
else
return 0;
}
else
return 0;
}
return 1;
}
//**********************************************************
//名称: BCDAdd()
//功能: 多字节BCD码加法子程序
//说明: pSbuf1,pSbuf2为2个加数的首地址,低字节在前,2个数组的
// 长度必须相等,为Svar2。
// 返回值: 1-->有进位, 0-->无进位
//**********************************************************
#ifdef BCDADD1
uchar BCDAdd(uchar idata *pSbuf1,uchar idata *pSbuf2,uchar Svar2)
{
uchar Svar4,Svar5;
uint iSvar1;
Svar4=0;
while (Svar2!=0)
{
Svar2--;
Svar5=(*pSbuf1&0x0F)+(*pSbuf2&0x0F)+Svar4;
if(Svar5>=10)
{
*pSbuf1 += 0x10;
Svar5 -= 10;
}
iSvar1=(uint)(*pSbuf1&0xF0)+(*pSbuf2&0xF0)+Svar5;
if(iSvar1>=0xA0)
{
iSvar1-=0xA0;
Svar4=1;
}
else
Svar4=0;
*pSbuf1=(uchar)iSvar1;
pSbuf1++;pSbuf2++;
}
if(Svar4) return 1;
else return 0;
}
#endif
//**********************************************************
//名称: BCDAdd()
//功能: 多字节BCD码加法子程序
//说明: pSbuf1,pSbuf2为2个加数的首地址,低字节在前,
// Svar1,Svar2为2数的长度字数,必须Svar1>=Svar2
// 返回值: 1-->有进位, 0-->无进位
//**********************************************************
#ifdef BCDADD2
uchar BCDAdd(uchar idata *pSbuf1,uchar idata *pSbuf2,uchar Svar1,uchar Svar2)
{
uchar Svar4,Svar5,*rAddr,rLen;
uint iSvar1;
//if((Svar2>Svar1)||(Svar1==0)||(Svar2==0)) return 0;
rAddr = pSbuf1+Svar2; //剩余字节首址
rLen = Svar1-Svar2; //剩余长度
Svar4=0;
while (Svar2!=0)
{
Svar2--;
//Svar1--;
Svar5=(*pSbuf1&0x0F)+(*pSbuf2&0x0F)+Svar4;
if(Svar5>=10)
{
*pSbuf1 += 0x10;
Svar5 -= 10;
}
iSvar1=(uint)(*pSbuf1&0xF0)+(*pSbuf2&0xF0)+Svar5;
if(iSvar1>=0xA0)
{
iSvar1-=0xA0;
Svar4=1;
}
else
Svar4=0;
*pSbuf1=(uchar)iSvar1;
pSbuf1++;pSbuf2++;
}
/*
if(Svar4)
{
if(rLen==0)
return 1;
else
return BCDINC(rAddr,rLen);
}
*/
if(Svar4)
return BCDINC(rAddr,rLen);
else
return 0;
}
#endif
//**********************************************************
//名称:SumCHK()
//功能:返回数据校验和
//说明:
//**********************************************************
uchar SumCHK(uchar idata *ptr, uchar len)
{
uchar i;
uchar TmpData;
uchar SumData;
TmpData = 0x00;
SumData = 0x00;
i = 0x00;
do
{
TmpData = *ptr;
SumData += TmpData;
ptr++;
i++;
} while(i<len);
return SumData;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -