📄 main._c
字号:
functionName:void start_timer0(void)
description:定时器0初始化
desired value: 20mSec
actual value: 19.861mSec (0.7%)
**********************************************************************/
void start_timer0(uint _20ms)
{
TCCR0 = 0x00; //stop
TCNT0 = 0x71;
TIMSK |= 0x01; // 定时器0溢出中断
OCR0 = 0x8F; // 定时器比较值
gTmr0OvrCount = _20ms;
TCCR0 = 0x05; // Count clock/1024, start Timer0
}
/**********************************************************************
functionName:void stop_time0(void)
description:停止定时器0
**********************************************************************/
void stop_time0(void)
{
TCCR0 = 0x00; //stop
gTmr0OvrCount = 0;
}
/**********************************************************************
functionName:void start_timer2(void)
description:定时器2初始化
desired value: 20mSec
actual value: 19.861mSec (0.7%)
**********************************************************************/
void start_timer2(uint _20ms)
{
TCCR2 = 0x00; //stop
ASSR = 0x00; //set async mode
TCNT2 = 0x71;
TIMSK |= 0x40; // 定时器2溢出中断
OCR2 = 0x8F; // 定时器比较值
gTmr2OvrCount = _20ms;
TCCR2 = 0x07; // Count clock/1024, start Timer0
}
/**********************************************************************
functionName:void stop_time2(void)
description:停止定时器2
**********************************************************************/
void stop_time2(void)
{
TCCR0 = 0x00; //stop
gTmr2OvrCount = 0;
}
/**********************************************************************
functionName:void main(void)
description:主函数
**********************************************************************/
void main(void)
{
uchar counter;
char tempbuf[5];
//键盘
uchar cKeyCode = 0;
uchar OpCardOk = 0;
uint leftMoney = 0;
uchar statusOfIC = 0;
uchar cardserialno[4];
//从M41T0器件中读取的当前时间信息
uchar M41T0Data[8];
uchar CurrTimeInfo[12];
//完整的一条消费信息字节
uchar szRecordInfoBytes[20];
uchar blockdata[16];
///////////////////////////////////////////////////////////////////
//初始化硬件资源
all_init();
//得到FLASH的历史数据页号和字节地址
GetHistoryPageAndBytesAddr(&gnHistoryFlashPage, &gnHistoryBytesBlock);
while(1)
{
////////////////////////////////////////////////////////
//当有用户选择用水模式时
if (cKeyRiseEvent == 1)
{
//屏蔽int1、int0中断和UART中断,定时器Timer0,Timer2仍开始
DISINT01INT()
DISRXINT()
//清除用水标记
cKeyRiseEvent = 0;
//判断出出水模式
cKeyCode = Zlg7290_ReadKey();
//启动定时器0,等待5秒内刷卡
start_timer0(2000);
//若超时
while (gTmr0OvrCount>0)
{
leftMoney = blockdata[0];
leftMoney = leftMoney<<8+blockdata[1];
if (leftMoney < 50) //蜂鸣器响2次
{
SETBIT(PORTD,6);
SoftDelay();//每次循环延时0.8秒
CLRBIT(PORTD,6);
SoftDelay();
SETBIT(PORTD,6);
SoftDelay();
CLRBIT(PORTD,6);
break;
}
//
leftMoney -= 50;
blockdata[0] = (uchar)((leftMoney&0xFF00)>>8);
blockdata[1] = leftMoney&0xFF;
//
for (counter=0; counter<4; counter++)
szRecordInfoBytes[counter] = cardserialno[counter];
//2.>金额部分
memcpy((void *)&szRecordInfoBytes[4], (void *)utoa(tempbuf/*暂存缓冲区*/, leftMoney, 10), 4);
//3.>时间部分
for (counter=0; counter<12; counter++)
szRecordInfoBytes[8+counter] = CurrTimeInfo[counter];
//计算出当前消费的数据页和字节块号
CalcNextPageAndBytesAddr(gnHistoryFlashPage, gnHistoryBytesBlock,
&gnCurrentFlashPage, &gnCurrentBytesBlock);
//先写入FLASH中,并确认已正确写入消费记录
OpCardOk = CommitPaidSuccess(gnCurrentFlashPage, gnCurrentBytesBlock,
szRecordInfoBytes, 20);
//若写入则成功,则产生下一个新页和字节块的地址,否则维持历史页和字节块地址
if (OpCardOk == TRUE)
{
//写入0页,记录已消费的记录和字节信息
WriteContextInfo(gnCurrentFlashPage, gnCurrentBytesBlock);
//提前取出FLASH中记录的历史数据页号和字节地址,为新消费准备
GetHistoryPageAndBytesAddr(&gnHistoryFlashPage, &gnHistoryBytesBlock);
SETBIT(PORTC, cKeyCode);
}
else //写入操作失败,则蜂鸣器响3次
{
SETBIT(PORTD,6);
SoftDelay(); //每次循环延时0.8秒
CLRBIT(PORTD,6);
SoftDelay();
SETBIT(PORTD,6);
SoftDelay();
CLRBIT(PORTD,6);
SoftDelay();
SETBIT(PORTD,6);
SoftDelay();
CLRBIT(PORTD,6);
}
}//end of if
//开启int1、int0中断和UART中断
ENINT01INT()
ENRXINT()
//规定时间内完成当前操作模式,则退出操作卡限时
break;
}
stop_time0();
}//end if while
///////////////////////////////////////////////////////
//1.当操作员要求读取FLASH内的消费记录时,开始传送数据,
//结束后操作员要复位重启。
//2.当操作员校定M41T0时间时,直接写I2C器件M41T0
if (gbRecvPCFrameCmd == 1)
{
gbRecvPCFrameCmd = 0;
//读取Flash数据并上传命令
//向M41T0写校定时间
M41T0Data[0] = 0x12;
M41T0_SendInfo(M41T0Data, 8);
}
//读取M41T0时间
M41T0_ReadInfo(M41T0Data, 8);
CurrTimeInfo[0] = M41T0Data[0];
}
}
/**********************************************************************
functionName:void int0_isr(void)
description:外部键盘中断0函数
**********************************************************************/
#pragma interrupt_handler int0_isr:2
void int0_isr(void)
{
cKeyRiseEvent = 1;
}
/**********************************************************************
functionName:void int2_isr(void)
description:外部中断2函数
**********************************************************************/
#pragma interrupt_handler int2_isr:19
void int2_isr(void)
{}
/**********************************************************************
functionName:void timer0_ovf_isr(void)
description:定时器0溢出中断,20mSec
**********************************************************************/
#pragma interrupt_handler timer0_ovf_isr:10
void timer0_ovf_isr(void)
{
TCNT0 = 0x71; //溢出时,重新加载新值
if (gTmr0OvrCount)
gTmr0OvrCount --;
}
/**********************************************************************
functionName:void timer0_ovf_isr(void)
description:定时器0比较中断
**********************************************************************/
#pragma interrupt_handler timer0_comp_isr:20
void timer0_comp_isr(void)
{}
/**********************************************************************
functionName:void timer2_ovf_isr(void)
description:定时器2溢出中断,500mSec
**********************************************************************/
#pragma interrupt_handler timer2_ovf_isr:10
void timer2_ovf_isr(void)
{
TCNT2 = 0x71; //溢出时,重新加载新值
if (gTmr2OvrCount)
gTmr2OvrCount --;
}
/**********************************************************************
functionName:void spi_stc_isr(void)
description:SPI中断函数
**********************************************************************/
#pragma interrupt_handler spi_stc_isr:11
void spi_stc_isr(void)
{}
/**********************************************************************
functionName:void uart0_rx_isr(void)
description:串口接受中断函数,完成上位机的回传全部消费记录数据
**********************************************************************/
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void)
{
//接收数据后清零RXC标记
UartRecvBuffer[UartRecvIndex++] = UDR;
if (UartRecvIndex >= RECVBUFFERLEN)
{
gbRecvPCFrameCmd = 1; //接收完整一桢数据标记
UartRecvIndex = 0;
}
//RXC位清零
UCSRA &= ~(1<<RXC);
}
/**********************************************************************
functionName:void uart0_tx_isr(void)
description:串口发送中断函数
**********************************************************************/
#pragma interrupt_handler uart0_tx_isr:14
void uart0_tx_isr(void)
{}
/**********************************************************************
functionName:void adc_isr(void)
description:ADC中断函数
**********************************************************************/
#pragma interrupt_handler adc_isr:15
void adc_isr(void)
{}
#pragma interrupt_handler twi_isr:18
void twi_isr(void) //通信模式为主机发送和接收模式
{
unsigned char status;
status = TWSR & 0xf8;
switch(status)
{
case TW_START: //0x08: START 已发送
case TW_REP_START: //0x10: 重复START 已发送
i2cSendByte(I2cSendData[0]); //开始传送从地址
break;
// 主机发送模式,接收状态码
case TW_MT_SLA_ACK: //0x18: SLA+W 已发送;接收到从机ACK
case TW_MT_DATA_ACK: //0x28: 数据已发送;接收到从机ACK
if(I2cSendDataIndex < I2cSendDataLength)
{
gbi2cSendByteStatus = TRUE;
i2cSendByte(I2cSendData[1+I2cSendDataIndex] );
I2cSendDataIndex++;
}
else
{
i2cSendStop();
}
break;
case TW_MTR_ARB_LOST: //0x38: SLA+W 或数据的仲裁失败
gbi2cSendCmdStatus = FALSE;
TWCR = (TWCR&0x0F)|(1<<TWINT); // 释放总线
break;
// 主机接收模式时的状态码
case TW_MR_DATA_NACK: //0x58: 主机接收到从机数据;主机未给从机ACK
// 保存数据
I2cReceiveData[I2cReceiveDataIndex++] = TWDR;
//继续发送条件
case TW_MR_SLA_NACK: //0x48: 主机已发送SLA+R,主机未接收到从机ACK
case TW_MT_SLA_NACK: //0x20: SLA+W 已发送,未接收到从机ACK
case TW_MT_DATA_NACK: //0x30: 数据已发送,未接收从机ACK
gbi2cSendCmdStatus = FALSE;
// 发送停止条件
i2cSendStop();
break;
case TW_MR_DATA_ACK: //0x50: 主机接收到从机数据,主机已给从机ACK信号
gbi2cRecvByteStatus = TRUE;
// 保存接收到的数据位
I2cReceiveData[I2cReceiveDataIndex++] = TWDR;
// 检查是否接收完
//if(I2cReceiveDataIndex < (I2cReceiveDataLength-1))
// 数据位将接收 , 回复 ACK (传送更多字节)
//i2cAckSignal(TRUE);
//else
if(I2cReceiveDataIndex >= I2cReceiveDataLength )
{ // 数据位将接收 , 主机先回复 从机NACK (传送最后字节)
i2cAckSignal(FALSE);
// 主机再发送停止条件
i2cSendStop();
}
case TW_MR_SLA_ACK: //0x40: 主机已发送SLA+R,从机已ACK,主机准备接收数据
break;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -