📄 main.s
字号:
xcall _SPI_WritePageCtx
L32:
inc R22
L34:
cpi R22,20
brlo L31
; {
; SPI_WritePageCtx(curpage, curBlockIndex*20+cByteNum, *szBytes++);
; }
;
; //再读出当前消费记录
; for (cByteNum = 0; cByteNum<20; cByteNum++)
clr R22
xjmp L38
L35:
ldi R24,20
mul R24,R14
movw R18,R0
mov R2,R22
clr R3
add R18,R2
adc R19,R3
movw R16,R10
xcall _SPI_ReadPageCtx
movw R24,R28
adiw R24,2
mov R30,R22
clr R31
add R30,R24
adc R31,R25
std z+0,R16
L36:
inc R22
L38:
cpi R22,20
brlo L35
; {
; CmpData[cByteNum] = SPI_ReadPageCtx(curpage, curBlockIndex*20+cByteNum);
; }
;
; cByteNum = memcmp((void *)szBytes, (void *)CmpData, 20);
ldi R24,20
ldi R25,0
std y+1,R25
std y+0,R24
movw R18,R28
subi R18,254 ; offset = 2
sbci R19,255
movw R16,R12
xcall _memcmp
mov R22,R16
;
; return cByteNum == 0;
tst R16
brne L39
ldi R20,1
ldi R21,0
xjmp L40
L39:
clr R20
clr R21
L40:
mov R16,R20
L30:
adiw R28,22
xcall pop_gset5
.dbline 0 ; func end
ret
; cData -> R10
; oldByteAddr -> R20,R21
; oldpage -> R22,R23
.even
_GetHistoryPageAndBytesAddr::
xcall push_gset3
movw R20,R18
movw R22,R16
; }
;
; //读出前次消费记录的待写FLASH页地址和页内字节地址。
; void GetHistoryPageAndBytesAddr(uint *oldpage, uint *oldByteAddr)
; {
; uchar cData = 0;
clr R10
;
; *oldpage = SPI_ReadPageCtx(0, 0);
clr R18
clr R19
clr R16
clr R17
xcall _SPI_ReadPageCtx
mov R2,R16
clr R3
movw R30,R22
std z+1,R3
std z+0,R2
; cData = SPI_ReadPageCtx(0, 1);
ldi R18,1
ldi R19,0
clr R16
clr R17
xcall _SPI_ReadPageCtx
mov R10,R16
;
; *oldpage = *oldpage*256;
movw R30,R22
ldd R18,z+0
ldd R19,z+1
ldi R16,256
ldi R17,1
xcall empy16s
movw R30,R22
std z+1,R17
std z+0,R16
; *oldpage += cData;
mov R2,R10
clr R3
ldd R4,z+0
ldd R5,z+1
add R4,R2
adc R5,R3
std z+1,R5
std z+0,R4
;
; *oldByteAddr = SPI_ReadPageCtx(0, 2);
ldi R18,2
ldi R19,0
clr R16
clr R17
xcall _SPI_ReadPageCtx
mov R2,R16
clr R3
movw R30,R20
std z+1,R3
std z+0,R2
L41:
xcall pop_gset3
.dbline 0 ; func end
ret
; newByteAddr -> y+2
; newPage -> y+0
; oldByteAddr -> R18,R19
; oldpage -> R16,R17
.even
_CalcNextPageAndBytesAddr::
; }
;
; //计算出下次消费记录的待写FLASH页地址和页内字节地址。
; //注意忽略每页的后4个字节,只考虑使用前260个字节,每条记录20个字节。
; void CalcNextPageAndBytesAddr(uint oldpage, uint oldByteAddr, uint *newPage,
; uint *newByteAddr)
; {
; *newByteAddr = oldByteAddr +1;
movw R24,R18
adiw R24,1
ldd R30,y+2
ldd R31,y+3
std z+1,R25
std z+0,R24
; *newPage = oldpage;
ldd R30,y+0
ldd R31,y+1
std z+1,R17
std z+0,R16
;
; if (*newByteAddr > 12) //换页时
ldi R24,12
ldi R25,0
ldd R30,y+2
ldd R31,y+3
ldd R2,z+0
ldd R3,z+1
cp R24,R2
cpc R25,R3
brsh L43
; {
; *newPage = oldpage + 1;
movw R24,R16
adiw R24,1
ldd R30,y+0
ldd R31,y+1
std z+1,R25
std z+0,R24
; *newByteAddr = 0;
clr R2
clr R3
ldd R30,y+2
ldd R31,y+3
std z+1,R3
std z+0,R2
; }
L43:
L42:
.dbline 0 ; func end
ret
; data -> R16
.even
_i2cSendByte::
; }
;
;
;
;
;
;
;
; /*******************************************************************************
; ** 与I2C通信的子程序
; *******************************************************************************/
; void i2cSendByte(uchar data)
; {
; // 装载数据到 TWDR
; TWDR=data;
out 0x3,R16
; // 发送开始
; TWCR = (TWCR&0x0F)|(1<<TWINT);
in R24,0x36
andi R24,15
ori R24,128
out 0x36,R24
L45:
.dbline 0 ; func end
ret
.even
_i2cSendStart::
; }
;
; // 发送开始信号
; void i2cSendStart(void)
; {
; TWCR = (TWCR&0x0F)|(1<<TWINT)|(1<<TWSTA);
in R24,0x36
andi R24,15
ori R24,160
out 0x36,R24
L46:
.dbline 0 ; func end
ret
.even
_i2cSendStop::
; }
;
; // 发送停止信号
; void i2cSendStop(void)
; {
; TWCR = (TWCR&0x0F)|(1<<TWINT)|(1<<TWEA)|(1<<TWSTO);
in R24,0x36
andi R24,15
ori R24,208
out 0x36,R24
L47:
.dbline 0 ; func end
ret
; ackFlag -> R16
.even
_i2cAckSignal::
; }
;
; // 产生应答信号否
; void i2cAckSignal(uchar ackFlag)
; {
; if( ackFlag )
tst R16
breq L49
; TWCR = (TWCR&0x0F)|(1<<TWINT)|(1<<TWEA);
in R24,0x36
andi R24,15
ori R24,192
out 0x36,R24
xjmp L50
L49:
; else
; TWCR = (TWCR&0x0F)|(1<<TWINT);
in R24,0x36
andi R24,15
ori R24,128
out 0x36,R24
L50:
L48:
.dbline 0 ; func end
ret
; num -> y+8
; szBuff -> y+6
; suba -> R20
; wsla -> R22
.even
_I2C_SendInfo::
xcall push_gset2
mov R20,R18
mov R22,R16
sbiw R28,2
; }
;
; //向I2C器件发送字符串
; void I2C_SendInfo(uchar wsla, uchar suba, uchar *szBuff, uchar num)
; {
; I2cSendData[0] = wsla;
sts _I2cSendData,R22
; I2cSendData[1] = suba;
sts _I2cSendData+1,R20
; if (num > 0)
clr R2
ldd R0,y+8
cp R2,R0
brsh L53
; memcpy((void *)&I2cSendData[2], (void *)szBuff, num);
mov R2,R0
clr R3
std y+1,R3
std y+0,R2
ldd R18,y+6
ldd R19,y+7
ldi R16,<_I2cSendData+2
ldi R17,>_I2cSendData+2
xcall _memcpy
L53:
;
; I2cSendDataLength = num+1;
ldd R24,y+8
subi R24,255 ; addi 1
sts _I2cSendDataLength,R24
; I2cSendDataIndex = 0; //从从地址开始计算
clr R2
sts _I2cSendDataIndex,R2
;
; //启动I2C传送
; i2cSendStart();
xcall _i2cSendStart
L51:
adiw R28,2
xcall pop_gset2
.dbline 0 ; func end
ret
; num -> y+6
; szBuff -> y+4
; suba -> R22
; wsla -> R20
.even
_I2C_RecvInfo::
xcall push_gset2
mov R22,R18
mov R20,R16
; }
;
; //向I2C器件发送字符串
; void I2C_RecvInfo(uchar wsla, uchar suba, uchar *szBuff, uchar num)
; {
; I2cSendData[0] = wsla;
sts _I2cSendData,R20
; I2cSendData[1] = suba;
sts _I2cSendData+1,R22
;
; //接收功能的变量
; I2cReceiveDataLength = num;
ldd R0,y+6
sts _I2cReceiveDataLength,R0
; I2cReceiveDataIndex = 0; //从0开始计算
clr R2
sts _I2cReceiveDataIndex,R2
;
; //发送命令的变量
; I2cSendDataIndex = 0; //专为子地址才有此代码
sts _I2cSendDataIndex,R2
; I2cSendDataLength = 1;
ldi R24,1
sts _I2cSendDataLength,R24
; gbi2cSendByteStatus = FALSE;
sts _gbi2cSendByteStatus,R2
;
; //先启动I2C传送写从地址和子地址
; i2cSendStart();
xcall _i2cSendStart
L58:
L59:
;
; //再重启I2C传送,仅写从地址
; while(!gbi2cSendByteStatus); //等到已发送子地址后,可以接收数据
lds R2,_gbi2cSendByteStatus
tst R2
breq L58
;
; I2cSendData[0] = wsla+1;
mov R24,R20
subi R24,255 ; addi 1
sts _I2cSendData,R24
; i2cSendStart();
xcall _i2cSendStart
L56:
xcall pop_gset2
.dbline 0 ; func end
ret
; cByte -> y+5
; SegNo -> R20
.even
_Zlg7290_SendChar::
st -y,r19
st -y,r18
xcall push_gset1
mov R20,R16
sbiw R28,3
; }
;
; //向ZLG7290发送单个字节
; void Zlg7290_SendChar(uchar SegNo, uchar cByte)
; {
; I2C_SendInfo(WriteZlg7290Addr, DPRAM0+SegNo, &cByte, 1);
ldi R24,1
std y+2,R24
movw R24,R28
adiw R24,5
std y+1,R25
std y+0,R24
mov R18,R20
subi R18,240 ; addi 16
ldi R16,112
xcall _I2C_SendInfo
L61:
adiw R28,3
xcall pop_gset1
adiw R28,2
.dbline 0 ; func end
ret
.even
_Zlg7290_ReadKey::
sbiw R28,3
; }
;
; //从ZLG7290读取单个字节
; uchar Zlg7290_ReadKey(void)
; {
; gbi2cRecvByteStatus = FALSE;
clr R2
sts _gbi2cRecvByteStatus,R2
;
; //需从键值寄存器读取哪个键被按下
; I2C_RecvInfo(WriteZlg7290Addr, 0x01, 0, 1);
ldi R24,1
std y+2,R24
clr R3
std y+1,R3
std y+0,R2
ldi R18,1
ldi R16,112
xcall _I2C_RecvInfo
L63:
L64:
;
; //等到接收到回应
; while (!gbi2cRecvByteStatus && I2cReceiveDataIndex < 1);
lds R2,_gbi2cRecvByteStatus
tst R2
brne L66
lds R24,_I2cReceiveDataIndex
cpi R24,1
brlo L63
L66:
;
; return I2cReceiveData[0];
lds R16,_I2cReceiveData
L62:
adiw R28,3
.dbline 0 ; func end
ret
; num -> R22
; szData -> R20,R21
.even
_M41T0_SendInfo::
xcall push_gset2
mov R22,R18
movw R20,R16
sbiw R28,3
; }
;
; //向M41T0发送多个字节,此处为时间(格式为:秒-分-小时-星期-日-月-年-控制字)
; void M41T0_SendInfo(uchar *szData, uchar num)
; {
; I2C_SendInfo(WriteM41T0Addr, 0/*从秒开始*/, szData, num);
std y+2,R22
std y+1,R21
std y+0,R20
clr R18
ldi R16,208
xcall _I2C_SendInfo
L67:
adiw R28,3
xcall pop_gset2
.dbline 0 ; func end
ret
; num -> R22
; szData -> R20,R21
.even
_M41T0_ReadInfo::
xcall push_gset2
mov R22,R18
movw R20,R16
sbiw R28,3
; }
;
; //从M41T0读取多个字节,此处为时间(格式为:秒-分-小时-星期-日-月-年-控制字)
; void M41T0_ReadInfo(uchar *szData, uchar num)
; {
; if (num != 8)
cpi R22,8
breq L69
; return;
xjmp L68
L69:
;
; gbi2cRecvByteStatus = FALSE;
clr R2
sts _gbi2cRecvByteStatus,R2
;
; //需从寄存器读取时间
; I2C_RecvInfo(WriteM41T0Addr, 0x0/*从秒开始*/, 0/*忽略*/, 8);
ldi R24,8
std y+2,R24
clr R3
std y+1,R3
std y+0,R2
clr R18
ldi R16,208
xcall _I2C_RecvInfo
L71:
L72:
;
; //等到接收到回应
; while (!gbi2cRecvByteStatus && I2cReceiveDataIndex < 8);
lds R2,_gbi2cRecvByteStatus
tst R2
brne L74
lds R24,_I2cReceiveDataIndex
cpi R24,8
brlo L71
L74:
;
; memcpy((void *)szData, (void *)I2cReceiveData, num);
mov R2,R22
clr R3
std y+1,R3
std y+0,R2
ldi R18,<_I2cReceiveData
ldi R19,>_I2cReceiveData
movw R16,R20
xcall _memcpy
L68:
adiw R28,3
xcall pop_gset2
.dbline 0 ; func end
ret
; _20ms -> R16,R17
.even
_start_timer0::
; }
;
;
;
;
;
;
;
;
;
; /**********************************************************************
; functionName:void start_timer0(void)
; description:定时器0初始化
; desired value: 20mSec
; actual value: 19.861mSec (0.7%)
; **********************************************************************/
; void start_timer0(uint _20ms)
; {
; TCCR0 = 0x00; //stop
clr R2
out 0x33,R2
; TCNT0 = 0x71;
ldi R24,113
out 0x32,R24
;
; TIMSK |= 0x01; // 定时器0溢出中断
in R24,0x39
ori R24,1
out 0x39,R24
; OCR0 = 0x8F; // 定时器比较值
ldi R24,143
out 0x3c,R24
;
; gTmr0OvrCount = _20ms;
sts _gTmr0OvrCount+1,R17
sts _gTmr0OvrCount,R16
;
; TCCR0 = 0x05; // Count clock/1024, start Timer0
ldi R24,5
out 0x33,R24
L75:
.dbline 0 ; func end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -