📄 main.s
字号:
.module main.c
.area data(ram, con, rel)
_UartRecvIndex::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_gbRecvPCFrameCmd::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_I2cReceiveDataIndex::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_I2cReceiveDataLength::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_I2cSendDataIndex::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_I2cSendDataLength::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_gbi2cSendCmdStatus::
.blkb 1
.area idata
.byte 1
.area data(ram, con, rel)
_gbi2cRecvByteStatus::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_gbi2cSendByteStatus::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_gTmr0OvrCount::
.blkb 2
.area idata
.word 0
.area data(ram, con, rel)
_gTmr2OvrCount::
.blkb 2
.area idata
.word 0
.area data(ram, con, rel)
_cKeyRiseEvent::
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
_gnCurrentFlashPage::
.blkb 2
.area idata
.word 0
.area data(ram, con, rel)
_gnCurrentBytesBlock::
.blkb 2
.area idata
.word 0
.area data(ram, con, rel)
_gnHistoryFlashPage::
.blkb 2
.area idata
.word 0
.area data(ram, con, rel)
_gnHistoryBytesBlock::
.blkb 2
.area idata
.word 0
.area data(ram, con, rel)
.area text(rom, con, rel)
; loop -> R16,R17
.even
_SoftDelay::
; /**********************************************************************************************************
; 陕 西 立 方 电 子 有 限 公 司
; Copyright (C), 2000-2008, LiFang Tech. Co., Ltd.
; File name: // main.c
; Author:zhuxz Version:v3.1 Date: 2008-8-29
; Description: // 用于详细说明此程序文件完成的主要功能,与其他模块
; // 或函数的接口,输出值、取值范围、含义及参数间的控
; // 制、顺序、独立或依赖等关系
; Others: // 其它内容的说明
; 集成开发环境:ICCAVR6.31A
; 主控芯片型号: ATMega16
; 晶振频率: 外部 7.3728MHZ
; 波特率: 9600
; **********************************************************************************************************/
;
; #include <macros.h>
; #include <string.h>
; #include <stdlib.h>
; #include <iom16v.h>
; #include "main.h"
; #include "initial.h"
; #include "m500a.h"
;
;
; #define TW_MR_SLA_ACK 0x40
; #define TW_MR_SLA_NACK 0x48
; #define TW_MR_DATA_ACK 0x50
; #define TW_MR_DATA_NACK 0x58
; #define TW_MTR_ARB_LOST 0x38
; #define TW_MT_DATA_NACK 0x30
; #define TW_MT_DATA_ACK 0x28
; #define TW_MT_SLA_NACK 0x20
; #define TW_MT_SLA_ACK 0x18
; #define TW_REP_START 0x10
; #define TW_START 0x08
;
; /*******************************************************************************
; * AT45Db081数据存储格式:第1页记录当前已写入页号和字节数;
; * 第2页到第21页未黑名单记录;
; * 第22页开始为消费记录;
; * 其中,消费记录数据为4字节IC卡号+4字节余额+12字节时间,共20字节。
; * 例如:2008年9月1日 14点40分30秒 刷卡剩余20.56元,字符串为:
; * "t4s22056080901144030"
; *******************************************************************************/
; /*******************************************************************************
; * 串口通信格式格式:1> 要求上传消费记录命令格式为:"$000000000000$",共14个字节;
; * 2> 擦除芯片所有数据命令格式为:"@000000000000@",共14个字节;
; * 3> 设定时钟芯片的时间格式为:"%08090114403000%",共14个字节;
; * 4> 初始化芯片的命令格式为:"#000000000000#",共14个字节;
; * 5> 消费记录数据格式见AT45D081存储格式部分描述。
; * 6> 对应命令的回应信息格式为:成功-"$!"/"@!"/"%!",
; * 失败-"$x"/"@x"/"%x"。
; * 7> 传输结束的信息格式为:"@#$%"。
; *******************************************************************************/
; #define RECVBUFFERLEN 14
; //UART接收到PC缓冲区的长度
; uchar UartRecvBuffer[RECVBUFFERLEN];
; //UART接收缓冲区的索引
; uchar UartRecvIndex = 0;
; //接收PC传来的UART完整一桢数据包标志
; uchar gbRecvPCFrameCmd = 0;
;
;
; //MFRC500芯片的串号
; uchar Snr_RC500[4];
;
;
; //定义I2C总线的数据
; //MCU I2C接收数据的缓存参数定义
; uchar I2cReceiveDataIndex = 0;
; uchar I2cReceiveDataLength= 0;
; uchar I2cReceiveData[16];
; //MCU I2C发送数据的缓存参数定义
; uchar I2cSendData[16];
; uchar I2cSendDataIndex = 0;
; uchar I2cSendDataLength = 0;
;
; //表明与I2C器件的通信状态(成功:TRUE/失败:FALSE)
; uchar gbi2cSendCmdStatus = TRUE;
; //MCU接收到I2C器件字节标志
; uchar gbi2cRecvByteStatus = FALSE;
; //MCU发送出字节标志
; uchar gbi2cSendByteStatus = FALSE;
;
; //Timer0溢出次数,用来控制刷卡时间
; uint gTmr0OvrCount = 0;
; //Timer2溢出次数,用来控制流水时间
; uint gTmr2OvrCount = 0;
;
; //键盘中断标志
; uchar cKeyRiseEvent = 0;
;
;
; //FLASH地址操作的变量
; uint gnCurrentFlashPage = 0; //当前操作的页地址
; uint gnCurrentBytesBlock = 0; //当前页内的字节块
;
; uint gnHistoryFlashPage = 0; //历史操作的页地址
; uint gnHistoryBytesBlock = 0; //历史页内的字节块
;
;
;
; //Timer2定时产生间隔来读取M41T0器件的当前时间
;
;
;
; void SoftDelay(void)
; {
; uint loop = 0;
clr R16
clr R17
xjmp L5
L2:
L3:
subi R16,255 ; offset = 1
sbci R17,255
L5:
;
; for (loop = 0; loop <1000; loop++);
cpi R16,232
ldi R30,3
cpc R17,R30
brlo L2
L1:
.dbline 0 ; func end
ret
; senddata -> R16
.even
_Uart_Send::
; }
;
; /*******************************************************************************
; ** 串口发送字节子程序
; *******************************************************************************/
; void Uart_Send(uchar senddata)
; {
; UDR = senddata;
out 0xc,R16
L7:
L8:
;
; while(!(UCSRA & (1<<UDRE))); //等待发送完
sbis 0xb,5
rjmp L7
;
; UCSRA |= 0x40; //清“发送完”标志位
sbi 0xb,6
L6:
.dbline 0 ; func end
ret
; cData -> R16
.even
_SPI_MasterTransmit::
; }
;
;
; /*******************************************************************************
; ** SPI发送字节子程序
; *******************************************************************************/
; void SPI_MasterTransmit(uchar cData)
; {
; /* 启动数据传输 */
; SPDR = cData;
out 0xf,R16
L11:
L12:
; /* 等待传输结束 */
; while(!(SPSR & (1<<SPIF)));
sbis 0xe,7
rjmp L11
L10:
.dbline 0 ; func end
ret
; cData -> R20
; byteAddr -> R22,R23
; page -> R10,R11
.even
_SPI_ReadPageCtx::
xcall push_gset3
movw R22,R18
movw R10,R16
; }
;
; //读取某页内字节地址的命令
; uchar SPI_ReadPageCtx(uint page/*0~4095*/, uint byteAddr/*0~263*/)
; {
; uchar cData=0;
clr R20
;
; CLRBIT(PORTB,4);
cbi 0x18,4
;
; SPI_MasterTransmit(0x52); //CMD, 1st
ldi R16,82
xcall _SPI_MasterTransmit
;
; cData = 0x1F & ((char)(page>>7));
ldi R18,7
ldi R19,0
movw R16,R10
xcall lsr16
mov R20,R16
andi R20,31
; SPI_MasterTransmit(cData);//Page Addr High,2nd
mov R16,R20
xcall _SPI_MasterTransmit
;
; cData = ((char)(page & 0x7F))<<1;
mov R20,R10
andi R20,127
andi R21,0
lsl R20
; cData |= (char)((byteAddr & 0x1FF)>>8);
movw R24,R22
andi R25,1
mov R24,R25
clr R25
or R20,R24
; SPI_MasterTransmit(cData);//Page Addr low,3rd
mov R16,R20
xcall _SPI_MasterTransmit
;
; cData = (char)(byteAddr & 0xFF);
mov R20,R22
andi R21,0
; SPI_MasterTransmit(cData);//byte Addr High,4th
mov R16,R20
xcall _SPI_MasterTransmit
;
; //空命令,凑足剩余4字节
; SPI_MasterTransmit(0);
clr R16
xcall _SPI_MasterTransmit
; SPI_MasterTransmit(0);
clr R16
xcall _SPI_MasterTransmit
; SPI_MasterTransmit(0);
clr R16
xcall _SPI_MasterTransmit
; SPI_MasterTransmit(0);
clr R16
xcall _SPI_MasterTransmit
L15:
L16:
;
; /* 等待传输结束 */
; while(!(SPSR & (1<<SPIF)));
sbis 0xe,7
rjmp L15
; cData = SPDR;
in R20,0xf
;
; SETBIT(PORTB,4);
sbi 0x18,4
; return cData;
mov R16,R20
L14:
xcall pop_gset3
.dbline 0 ; func end
ret
; cData -> R20
; cByte -> y+6
; byteAddr -> R22,R23
; page -> R10,R11
.even
_SPI_WritePageCtx::
xcall push_gset3
movw R22,R18
movw R10,R16
; }
;
; //写入某页内某字节地址的命令
; void SPI_WritePageCtx(uint page/*0~4095*/, uint byteAddr/*0~263*/, uchar cByte)
; {
; uchar cData =0;
clr R20
;
; CLRBIT(PORTB,4);
cbi 0x18,4
;
; //把数据写入Buffer1
; SPI_MasterTransmit(0x84); //CMD, 1st
ldi R16,132
xcall _SPI_MasterTransmit
; SPI_MasterTransmit(0); //Not Care
clr R16
xcall _SPI_MasterTransmit
;
; cData |= (char)((byteAddr & 0x100)>>8);
movw R24,R22
andi R24,0
andi R25,1
mov R24,R25
clr R25
or R20,R24
; SPI_MasterTransmit(cData);//Byte Addr High,3rd
mov R16,R20
xcall _SPI_MasterTransmit
;
; cData = (char)(byteAddr & 0xFF);
mov R20,R22
andi R21,0
; SPI_MasterTransmit(cData);//Byte Addr High,4th
mov R16,R20
xcall _SPI_MasterTransmit
;
; //传输字节
; SPI_MasterTransmit(cByte);//Byte Data
ldd R16,y+6
xcall _SPI_MasterTransmit
;
; SETBIT(PORTB,4);
sbi 0x18,4
L18:
xcall pop_gset3
.dbline 0 ; func end
ret
; bResult -> R22
; page -> R10
; cData -> R20
.even
_EraseFlashCtx::
xcall push_gset4
; }
;
; //擦除FLASH芯片所有内容
; char EraseFlashCtx(void)
; {
; uchar bResult = 1;
ldi R22,1
; uchar cData = 0;
clr R20
; char page = 0;
clr R10
;
; CLRBIT(PORTB,4);
cbi 0x18,4
;
; for (page =0; page<4096; page++)
xjmp L23
L20:
; {
; SPI_MasterTransmit(0x58); //CMD, 1st
ldi R16,88
xcall _SPI_MasterTransmit
; cData = 0x1F & ((char)(page>>7));
ldi R18,7
ldi R19,0
mov R16,R10
clr R17
xcall asr16
mov R20,R16
andi R20,31
; SPI_MasterTransmit(cData);//Page Addr High,2nd
mov R16,R20
xcall _SPI_MasterTransmit
;
; cData = ((char)(page>>7))<<1;
ldi R18,7
ldi R19,0
mov R16,R10
clr R17
xcall asr16
mov R20,R16
lsl R20
; SPI_MasterTransmit(cData);//Page Addr low,3rd
mov R16,R20
xcall _SPI_MasterTransmit
;
; SPI_MasterTransmit(0); //not care
clr R16
xcall _SPI_MasterTransmit
;
; //读取状态寄存器
; SPI_MasterTransmit(0x57);
ldi R16,87
xcall _SPI_MasterTransmit
L24:
L25:
;
; /* 等待传输结束 */
; while(!(SPSR & (1<<SPIF)));
sbis 0xe,7
rjmp L24
; cData = SPDR;
in R20,0xf
;
; cData &= 0x40;
andi R20,64
; bResult &= (cData == 0);
brne L27
ldi R24,1
ldi R25,0
movw R12,R24
xjmp L28
L27:
clr R12
clr R13
L28:
mov R2,R22
clr R3
and R2,R12
and R3,R13
mov R22,R2
L21:
inc R10
L23:
mov R24,R10
cpi R24,0
brlt L20
; }
;
; SETBIT(PORTB,4);
sbi 0x18,4
; return bResult;
mov R16,R22
L19:
xcall pop_gset4
.dbline 0 ; func end
ret
; curBlockIndex -> R20
; curpage -> R22,R23
.even
_WriteContextInfo::
xcall push_gset2
mov R20,R18
movw R22,R16
sbiw R28,1
; }
;
; //向FLASH中写入已使用的总页数和字节数,或下一个页数和字节地址
; void WriteContextInfo(uint curpage/*当前页地址*/,
; uchar curBlockIndex/*当前页内字节块的索引号*/)
; {
; //页地址高字节和低字节(范围:22..4095),20个字节的倍数(范围:0..12)
; SPI_WritePageCtx(0, 0, (uchar)(curpage>>8));
movw R2,R22
mov R2,R3
clr R3
std y+0,R2
clr R18
clr R19
clr R16
clr R17
xcall _SPI_WritePageCtx
; SPI_WritePageCtx(0, 1, (uchar)(curpage&0xFF));
movw R24,R22
andi R25,0
std y+0,R24
ldi R18,1
ldi R19,0
clr R16
clr R17
xcall _SPI_WritePageCtx
; SPI_WritePageCtx(0, 2, curBlockIndex);
std y+0,R20
ldi R18,2
ldi R19,0
clr R16
clr R17
xcall _SPI_WritePageCtx
L29:
adiw R28,1
xcall pop_gset2
.dbline 0 ; func end
ret
; CmpData -> y+2
; cByteNum -> R22
; num -> y+34
; szBytes -> R12,R13
; curBlockIndex -> R14
; curpage -> R10,R11
.even
_CommitPaidSuccess::
xcall push_gset5
mov R14,R18
movw R10,R16
sbiw R28,22
ldd R12,y+32
ldd R13,y+33
; }
;
; //确认当前消费记录写操作成功,完成写入和读出的记录钱数要相等。
; //成功:1, 失败:0。
; char CommitPaidSuccess(uint curpage/*当前页地址*/,
; uchar curBlockIndex/*当前页内字节块的索引号*/, uchar *szBytes, uchar num)
; {
; char cByteNum = 0;
clr R22
; uchar CmpData[20];
;
; //先写入当前的记录
; for (cByteNum = 0; cByteNum<20; cByteNum++)
xjmp L34
L31:
movw R30,R12
ld R2,Z+
movw R12,R30
std y+0,R2
ldi R24,20
mul R24,R14
movw R18,R0
mov R2,R22
clr R3
add R18,R2
adc R19,R3
movw R16,R10
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -