📄 xiugai.c
字号:
//计数器0中断服务程序
void clock_int(void) interrupt 1 using 0
{
TH0=0xff; //设置的计数初值(65506),每?个外部脉冲溢出
TL0=0xfa;
IE=0x82;
TF0=0;
/*for(i=0;i<=3;i++)
{
water[i]=Read24c02(i);
}*/
waterperkwh=water[3]+10*water[2]+100*water[1]+1000*water[0]; //来一个中断时水的增加量
//P1_7=0; //P1-7口接了继电器
water_value=water_value+waterperkwh;
b=water_value;
//judge xiaoying wei
if(b<10000) wei=0x0F;
else if(b>=10000&&b<100000) wei=0x1F;
else if(b>=100000&&b<1000000) wei=0x3F;
else if(b>=1000000&&b<10000000) wei=0x7F;
else if(b>=10000000&&b<100000000) wei=0xFF;
for(i=0;i<=7;i++)
{
write7279(SEGON,31);
write7279(DECODE0+i,b%10);
write7279(ACTCTL,wei);
b=b/10;
}
//减钱
moneypkh[0]=Read24c02(4);
moneypkh[1]=Read24c02(5);
moneyperkwh=10*moneypkh[0]+moneypkh[1];
money_value=money_value-moneyperkwh;
f++;
//c=money_value;
//wei=0x00;
//if(c<1000) wei=0x07;
//else if(c>=1000&&c<10000) wei=0x0F;
//else wei=0x1F;
//把余额写入USERID中
c=money_value-v; //卡上的余额
for(i=8;i>=4;i--)
{
USERID[i]=c%10;
c=c/10;
}
}
//显示error子函数
void DisplayErrorCard(void)
{
write7279(DECODE1,10);
write7279(DECODE1+1,0);
write7279(DECODE1+2,10);
write7279(DECODE1+3,10);
write7279(DECODE1+4,14);
}
//24C02子程序
//定时函数
void DelayMs(unsigned int number)
{
unsigned char temp;
for(;number!=0;number--)
{
for(temp=112;temp!=0;temp--) ;
}
}
//开始总线
void Start()
{
SDA=1;
SCL=1;
SDA=0;
SCL=0;
}
//结束总线
void Stop()
{
SCL=0;
SDA=0;
SCL=1;
SDA=1;
}
//发 ACK0
void NoAck()
{
SDA=1;
SCL=1;
SCL=0;
}
//测试 ACK
bit TestAck()
{
bit ErrorBit;
SDA=1;
SCL=1;
ErrorBit=SDA;
SCL=0;
return(ErrorBit);
}
//写入 8 个 bit 到 24c02
Write8Bit(unsigned char input)
{
unsigned char temp;
for(temp=8;temp!=0;temp--)
{
SDA=(bit)(input&0x80);
SCL=1;
SCL=0;
input=input<<1;
}
}
//写入一个字节到 24c02 中
void Write24c02(uchar ch,uchar address)
{
Start();
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(address);
TestAck();
Write8Bit(ch);
TestAck();
Stop();
DelayMs(10);
}
//从 24c02 中读出 8 个 bit
uchar Read8Bit()
{
unsigned char temp,rbyte=0;
for(temp=8;temp!=0;temp--)
{
SCL=1;
rbyte=rbyte<<1;
rbyte=rbyte|((unsigned char)(SDA));
SCL=0;
}
return(rbyte);
}
//从 24c02 中读出 1 个字节
uchar Read24c02(uchar address)
{
uchar ch;
Start();
Write8Bit(WriteDeviceAddress);
TestAck();
Write8Bit(address);
TestAck();
Start();
Write8Bit(ReadDviceAddress);
TestAck();
ch=Read8Bit();
NoAck();
Stop();
return(ch);
}
//7279子函数//
void write7279(unsigned char cmd,unsigned char dta)
{
send_byte(cmd);
send_byte(dta);
}
void send_byte(unsigned char out_byte)
{
unsigned char i;
cs=0;
long_delay();
for(i=0;i<8;i++)
{
if(out_byte&0x80)
{
dat=1;
}
else
{
dat=0;
}
clk=1;
short_delay();
clk=0;
short_delay();
out_byte=out_byte*2;
}
dat=0;
}
unsigned char receive_byte(void)
{
unsigned char i,in_byte;
dat=1;
long_delay();
for(i=0;i<8;i++)
{
clk=1;
short_delay();
in_byte=in_byte*2;
if(dat)
{
in_byte=in_byte|0x01;
}
clk=0;
short_delay();
}
dat=0;
return(in_byte);
}
void long_delay(void)
{
unsigned char i;
for(i=0;i<0x30;i++);
}
void short_delay(void)
{
unsigned char i;
for(i=0;i<8;i++);
}
void delay10ms(unsigned char time)
{
unsigned char i;
unsigned int j;
for(i=0;i<time;i++)
{
for(j=0;j<0x390;j++)
{
if(!key)
{
key_int();
}
}
}
}
//IC Card 子程序
/*****************************************************************************
*function: IIC start condition
*IIC起始条件
*****************************************************************************/
void I2CStart(void)
{
SDA = 1;
SCL = 1;
SDA = 0;
_nop_();
SCL = 0;
}
/*****************************************************************************
*function: IIC stop condition
*IIC停止条件
*****************************************************************************/
void I2CStop(void)
{
SCL = 0;
SDA = 0;
_nop_();
SCL = 1;
SDA = 1;
}
/*****************************************************************************
*function: IIC wait ACK
*等待IIC从器件的"ACK"
*****************************************************************************/
bit I2CWaitAck(void)
{
unsigned char cErrTime = 255;
SDA = 1;
_nop_();
SCL = 1;
while(SDA)
{
cErrTime--;
if (0 == cErrTime)
{
I2CStop();
return 1;
}
}
SCL = 0;
return SUCCESS;
}
/*****************************************************************************
*function: IIC send ACK
*发送"ACK"
*****************************************************************************/
void I2CSendAck(void)
{
SDA = 0;
_nop_();
SCL = 1;
SCL = 0;
}
/*****************************************************************************
*function: IIC send Not ACK
*发送"NOT ACK"
*****************************************************************************/
void I2CSendNotAck(void)
{
SDA = 1;
_nop_();
SCL = 1;
SCL = 0;
}
/*****************************************************************************
*function: send a byte over IIC bus
*发送一个字节
*****************************************************************************/
void I2CSendByte(unsigned char cSendByte)
{
unsigned char data i = 8;
while (i--)
{
SCL = 0;
SDA = (bit)(cSendByte & 0x80);
cSendByte += cSendByte;
_nop_();
SCL = 1;
}
SCL = 0;
}
/*****************************************************************************
*function: receive a byte over IIC bus
*接收一个字节
*****************************************************************************/
unsigned char I2CReceiveByte(void)
{
unsigned char data i = 8;
unsigned char data cR_Byte = 0;
SDA = 1;
while (i--)
{
cR_Byte += cR_Byte;
SCL = 0;
_nop_();
_nop_();
SCL = 1;
cR_Byte |= (unsigned char)SDA;
}
SCL = 0;
return cR_Byte;
}
/*****************************************************************************
*function: send data to JMY-5xx over IIC bus
*这是向模块发送数据的函数,所有操作模块的命令均由此函数发送
*程序输入的参数是一个指针,由通讯协议所定,指针指向的第一个字节是发送的数据包的长度(不包含最后的校验字节)
*在所有的数据发送完毕之后,再发送校验字节
*****************************************************************************/
unsigned char JMY_TRANS(unsigned char * cP)
{
/*
command of read block 4: 0A210004FFFFFFFFFFFF (No Xor Checksum, it is calculate by this function)
*/
unsigned char cCnt;
unsigned char cCheckSum = 0; //发送校验和的存储和计算的基准位
unsigned char jCheckSum = 0; //9.27日修改,新加了个接受校验和的存储和计算的基准位
I2CStart(); //IIC 起始条件
I2CSendByte(WRITE_JMY5xx); //发送IIC的“写”指令
if (I2CWaitAck() != SUCCESS) //如果模块没有正确的"ACK"回应
{
return 0x01;
}
else
{
for(cCnt=0; cCnt<cP[0]; cCnt++) //发送数据字节,长度为输入的指针的第一个字节
{
cCheckSum ^= cP[cCnt]; //计算“异或”的校验和
I2CSendByte(cP[cCnt]); //发送一个字节
if (I2CWaitAck() != SUCCESS) //等待从器件的"ACK"
{
return 0x02; //如果从器件没有正确的"ACK"则返回
}
}
I2CSendByte(cCheckSum); //发送完数据字节之后,发送计算出的异或校验和
if (I2CWaitAck() != SUCCESS) //如果没有收到"ACK"则返回
{
return 0x03;
}
I2CStop(); //发送IIC停止条件
}
// 以下为接收模块的数据部分
for (cCnt=0; cCnt<0xFF; cCnt++) //等待模块工作(操作卡片),如果超时则返回“失败”
{
I2CStart(); //发送起始条件
I2CSendByte(READ_JMY5xx); //发送IIC的“读”命令
if (I2CWaitAck() == SUCCESS) //如果正确收到了模块返回的"ACK",则模块的工作(操作卡片)已经完成,可以读取返回结果了
{
break;
}
}
if (0xFF == cCnt) //如果等待模块工作达到了25毫秒,则认为模块工作超时,返回失败
{
return 4;
}
cP[0]=2; //赋予读取字节数 初值“2”,但实际读取的字节数会大于此值,因为读到的第一个字节就是数据包的实际值,而后会被覆盖
for (cCnt=0; cCnt<cP[0]; cCnt++) //以接收到的第一个字节为长度,读取模块的返回数据
{
cP[cCnt] = I2CReceiveByte(); //接收一个字节
I2CSendAck(); //发送"ACK"
jCheckSum^= cP[cCnt]; //计算校验和
}
cP[cCnt] = I2CReceiveByte(); //接收校验和
I2CSendNotAck(); //发送"NOT ACK"
I2CStop(); //IIC 停止条件
if (jCheckSum!= cP[cCnt]) //比较校验和
{
return 5; //如果比较不等,则返回“失败”
}
else
{
return SUCCESS; //如果相等,则返回成功
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -