📄 ds1302.lst
字号:
__start:
__text_start:
0043 E5CF LDI R28,0x5F
0044 E0D4 LDI R29,4
0045 BFCD OUT P3D,R28
0046 BFDE OUT P3E,R29
0047 51C0 SUBI R28,0x10
0048 40D0 SBCI R29,0
0049 EA0A LDI R16,0xAA
004A 8308 STD R16,0+Y
004B 2400 CLR R0
004C E6E3 LDI R30,0x63
004D E0F0 LDI R31,0
004E E010 LDI R17,0
004F 36E3 CPI R30,0x63
0050 07F1 CPC R31,R17
0051 F011 BEQ 0x0054
0052 9201 ST R0,Z+
0053 CFFB RJMP 0x004F
0054 8300 STD R16,0+Z
0055 E8E2 LDI R30,0x82
0056 E0F0 LDI R31,0
0057 E6A0 LDI R26,0x60
0058 E0B0 LDI R27,0
0059 E010 LDI R17,0
005A 38E5 CPI R30,0x85
005B 07F1 CPC R31,R17
005C F021 BEQ 0x0061
005D 95C8 LPM
005E 9631 ADIW R30,1
005F 920D ST R0,X+
0060 CFF9 RJMP 0x005A
0061 940E026C CALL _main
_exit:
0063 CFFF RJMP _exit
FILE: I:\AVR视频教程\视频教程\lesson11\ds1302\ds1302\YJ1602.C
(0001)
(0002) #define LCDa_CTRL PORTD //1602控制端口定义
(0003) #define LCDa_CTRL_DDR DDRD //控制端口方向寄存器定义
(0004) #define LCDa_RS PD4 //定义三个控制引脚
(0005) #define LCDa_RW PD5
(0006) #define LCDa_E PD6
(0007)
(0008) #define LCDa_L1 0x80 //第一行的地址:0x80+addr ,addr为列数
(0009) #define LCDa_L2 0xC0 //第二行的地址:0x80+0x40+addr
(0010)
(0011) #define LCDa_CGRAM_ADDR 0x40 //CGRAM的开始地址
(0012) #define LCDa_CGMAX 64 //CGRAM存储的最大字节数
(0013)
(0014) #define LCDa_SET_RS LCDa_CTRL|=BIT(LCDa_RS) //三个控制管脚的控制操作
(0015) #define LCDa_SET_RW LCDa_CTRL|=BIT(LCDa_RW)
(0016) #define LCDa_SET_E LCDa_CTRL|=BIT(LCDa_E)
(0017) #define LCDa_CLR_RS LCDa_CTRL&=~BIT(LCDa_RS)
(0018) #define LCDa_CLR_RW LCDa_CTRL&=~BIT(LCDa_RW)
(0019) #define LCDa_CLR_E LCDa_CTRL&=~BIT(LCDa_E)
(0020)
(0021) #define LCDa_DO PORTB //输出数据总线端口定义
(0022) #define LCDa_DI PINB //输入数据总线端口定义
(0023) #define LCDa_DATA_DDR DDRB //数据总线方向寄存器定义
(0024)
(0025) #define LCDa_FUNCTION 0x38 // 液晶模式为8位,2行,5*8字符
(0026)
(0027) #define iDat 1 //数据标志
(0028) #define iCmd 0 //指令标志
(0029)
(0030) #define LCDa_CLS 0x01 // 清屏
(0031) #define LCDa_HOME 0x02 // 地址返回原点,不改变DDRAM内容
(0032) #define LCDa_ENTRY 0x06 // 设定输入模式,光标加,屏幕不移动
(0033) #define LCDa_C2L 0x10 // 光标左移
(0034) #define LCDa_C2R 0x14 // 光标右移
(0035) #define LCDa_D2L 0x18 // 屏幕左移
(0036) #define LCDa_D2R 0x1C // 屏幕又移
(0037)
(0038) #define LCDa_ON 0x0C // 打开显示
(0039) #define LCDa_OFF 0x08 // 关闭显示
(0040) #define LCDa_CURON 0x0E // 显示光标
(0041) #define LCDa_CURFLA 0x0F // 打开光标闪烁
(0042)
(0043) /*******************************************
(0044) 函数名称: LCD1602_portini
(0045) 功 能: 初始化1602液晶用到的IO口
(0046) 参 数: 无
(0047) 返回值 : 无
(0048) /********************************************/
(0049) void LCD1602_portini(void)
(0050) {
(0051) LCDa_CTRL_DDR |= BIT(LCDa_RS)|BIT(LCDa_RW)|BIT(LCDa_E);//配置控制管脚为输出
_LCD1602_portini:
0064 B381 IN R24,P11
0065 6780 ORI R24,0x70
0066 BB81 OUT P11,R24
(0052) LCDa_DATA_DDR |= 0xFF;//配置数据管脚为输出
0067 B387 IN R24,P17
0068 6F8F ORI R24,0xFF
0069 BB87 OUT P17,R24
(0053) }
006A 9508 RET
_LCD1602_readbyte:
dByte --> R20
DatCmd --> R20
006B 940E02B7 CALL push_gset1
006D 2F40 MOV R20,R16
(0054) /*******************************************
(0055) 函数名称: LCD1602_readbyte
(0056) 功 能: 从1602液晶读出一个字节数据或者指令
(0057) 参 数: DatCmd--为iDat时是数据,为iCmd时是指令
(0058) 返回值 : dByte--读回的数据或者指令
(0059) /********************************************/
(0060) uchar LCD1602_readbyte(uchar DatCmd)
(0061) {
(0062) uchar dByte;
(0063) if (DatCmd == iCmd) //指令操作
006E 2344 TST R20
006F F411 BNE 0x0072
(0064) LCDa_CLR_RS;
0070 9894 CBI P12,4
0071 C001 RJMP 0x0073
(0065) else
(0066) LCDa_SET_RS;
0072 9A94 SBI P12,4
(0067)
(0068) LCDa_SET_RW; //读操作
0073 9A95 SBI P12,5
(0069) LCDa_SET_E;
0074 9A96 SBI P12,6
(0070) LCDa_DATA_DDR=0x00; //数据总线定义为输入
0075 2422 CLR R2
0076 BA27 OUT P17,R2
(0071) dByte=LCDa_DI; //读数据或者指令
0077 B346 IN R20,P16
(0072) Delayms(1); //时序调整
0078 E001 LDI R16,1
0079 E010 LDI R17,0
007A D084 RCALL _Delayms
(0073) LCDa_CLR_E;
007B 9896 CBI P12,6
(0074) LCDa_DATA_DDR|=0xff; //数据总线还原为输出
007C B387 IN R24,P17
007D 6F8F ORI R24,0xFF
007E BB87 OUT P17,R24
(0075) return dByte;
007F 2F04 MOV R16,R20
0080 940E02BA CALL pop_gset1
0082 9508 RET
_LCD1602_sendbyte:
dByte --> R20
DatCmd --> R22
0083 940E02CE CALL push_gset2
0085 2F42 MOV R20,R18
0086 2F60 MOV R22,R16
(0076) }
(0077) /*******************************************
(0078) 函数名称: LCD1602_sendbyte
(0079) 功 能: 向1602液晶写入一个字节数据或者指令
(0080) 参 数: DatCmd--为iDat时是数据,为iCmd时是指令
(0081) dByte--为写入1602的数据或者指令
(0082) 返回值 : 无
(0083) /********************************************/
(0084) void LCD1602_sendbyte(uchar DatCmd, uchar dByte)
(0085) {
(0086) if (DatCmd == iCmd) //指令操作
0087 2366 TST R22
0088 F411 BNE 0x008B
(0087) LCDa_CLR_RS;
0089 9894 CBI P12,4
008A C001 RJMP 0x008C
(0088) else
(0089) LCDa_SET_RS;
008B 9A94 SBI P12,4
(0090)
(0091) LCDa_CLR_RW; //写操作
008C 9895 CBI P12,5
(0092) LCDa_SET_E;
008D 9A96 SBI P12,6
(0093) LCDa_DO = dByte; //写入数据
008E BB48 OUT P18,R20
(0094) Delayms(1);
008F E001 LDI R16,1
0090 E010 LDI R17,0
0091 D06D RCALL _Delayms
(0095) LCDa_CLR_E;
0092 9896 CBI P12,6
(0096) }
0093 940E02D6 CALL pop_gset2
0095 9508 RET
_LCD1602_sendstr:
ptString --> R20
0096 940E02B7 CALL push_gset1
0098 01A8 MOVW R20,R16
(0097) /*******************************************
(0098) 函数名称: LCD1602_sendstr
(0099) 功 能: 向1602液晶写入一个字符串
(0100) 参 数: ptString--字符串指针
(0101) 返回值 : 无
(0102) /********************************************/
(0103) void LCD1602_sendstr(uchar *ptString)
(0104) {
0099 C005 RJMP 0x009F
(0105) while((*ptString)!='\0') //字符串未结束
(0106) {
(0107) LCD1602_sendbyte(iDat, *ptString++);
009A 01FA MOVW R30,R20
009B 9121 LD R18,Z+
009C 01AF MOVW R20,R30
009D E001 LDI R16,1
009E DFE4 RCALL _LCD1602_sendbyte
009F 01FA MOVW R30,R20
00A0 8020 LDD R2,0+Z
00A1 2022 TST R2
00A2 F7B9 BNE 0x009A
(0108) }
(0109) }
00A3 940E02BA CALL pop_gset1
00A5 9508 RET
(0110) /*******************************************
(0111) 函数名称: LCD1602_clear
(0112) 功 能: 1602液晶清屏
(0113) 参 数: 无
(0114) 返回值 : 无
(0115) /********************************************/
(0116) void LCD1602_clear(void)
(0117) {
(0118) LCD1602_sendbyte(iCmd,LCDa_CLS);
_LCD1602_clear:
00A6 E021 LDI R18,1
00A7 2700 CLR R16
00A8 DFDA RCALL _LCD1602_sendbyte
(0119) Delayms(2);// 清屏指令写入后,2ms 的延时是很必要的!!!
00A9 E002 LDI R16,2
00AA E010 LDI R17,0
(0120) }
00AB C053 RJMP _Delayms
_LCD1602_readBF:
busy --> R20
00AC 940E02B7 CALL push_gset1
(0121) /*******************************************
(0122) 函数名称: LCD1602_readBF
(0123) 功 能: 1602液晶清屏
(0124) 参 数: 无
(0125) 返回值 : busy--为1时忙,为0时可以接收指令
(0126) /********************************************/
(0127) uchar LCD1602_readBF(void)
(0128) {
(0129) uchar busy;
(0130) busy=LCD1602_readbyte(iCmd); //读回BF标志和地址
00AE 2700 CLR R16
00AF DFBB RCALL _LCD1602_readbyte
00B0 2F40 MOV R20,R16
(0131) if(busy&0x80) //忙
00B1 FF07 SBRS R16,7
00B2 C002 RJMP 0x00B5
(0132) busy=1;
00B3 E041 LDI R20,1
00B4 C001 RJMP 0x00B6
(0133) else //不忙,可以写入
(0134) busy=0;
00B5 2744 CLR R20
(0135) return busy;
00B6 2F04 MOV R16,R20
00B7 940E02BA CALL pop_gset1
00B9 9508 RET
_LCD1602_gotoXY:
Col --> R20
Row --> R22
00BA 940E02CE CALL push_gset2
00BC 2F42 MOV R20,R18
00BD 2F60 MOV R22,R16
(0136) }
(0137) /*******************************************
(0138) 函数名称: LCD1602_gotoXY
(0139) 功 能: 移动到指定位置
(0140) 参 数: Row--指定的行
(0141) Col--指定的列
(0142) 返回值 : 无
(0143) /********************************************/
(0144) void LCD1602_gotoXY(uchar Row, uchar Col)
(0145) {
(0146) switch (Row) //选择行
00BE 2777 CLR R23
00BF 3062 CPI R22,2
00C0 E0E0 LDI R30,0
00C1 077E CPC R23,R30
00C2 F009 BEQ 0x00C4
00C3 C005 RJMP 0x00C9
(0147) {
(0148) case 2:
(0149) LCD1602_sendbyte(iCmd, LCDa_L2 + Col); break; //写入第2行的指定列
00C4 2F24 MOV R18,R20
00C5 5420 SUBI R18,0x40
00C6 2700 CLR R16
00C7 DFBB RCALL _LCD1602_sendbyte
00C8 C004 RJMP 0x00CD
(0150) default:
(0151) LCD1602_sendbyte(iCmd, LCDa_L1 + Col); break; //写入第1行的指定列
00C9 2F24 MOV R18,R20
00CA 5820 SUBI R18,0x80
00CB 2700 CLR R16
00CC DFB6 RCALL _LCD1602_sendbyte
(0152) }
(0153) }
00CD 940E02D6 CALL pop_gset2
00CF 9508 RET
(0154) /*******************************************
(0155) 函数名称: LCD1602_initial
(0156) 功 能: 1602液晶初始化
(0157) 参 数: 无
(0158) 返回值 : 无
(0159) /********************************************/
(0160) void LCD1602_initial(void)
(0161) {
(0162) Delayms(100); // 等待内部复位
_LCD1602_initial:
00D0 E604 LDI R16,0x64
00D1 E010 LDI R17,0
00D2 D02C RCALL _Delayms
(0163) LCD1602_portini(); //端口初始化
00D3 DF90 RCALL _LCD1602_portini
(0164)
(0165) LCD1602_sendbyte(iCmd, LCDa_FUNCTION); // 功能、模式设定
00D4 E328 LDI R18,0x38
00D5 2700 CLR R16
00D6 DFAC RCALL _LCD1602_sendbyte
(0166) while(LCD1602_readBF());
00D7 DFD4 RCALL _LCD1602_readBF
00D8 2300 TST R16
00D9 F7E9 BNE 0x00D7
(0167) LCD1602_sendbyte(iCmd, LCDa_ON); //打开显示
00DA E02C LDI R18,0xC
00DB 2700 CLR R16
00DC DFA6 RCALL _LCD1602_sendbyte
(0168) while(LCD1602_readBF());
00DD DFCE RCALL _LCD1602_readBF
00DE 2300 TST R16
00DF F7E9 BNE 0x00DD
(0169) LCD1602_clear(); //清屏
00E0 DFC5 RCALL _LCD1602_clear
(0170) while(LCD1602_readBF());
00E1 DFCA RCALL _LCD1602_readBF
00E2 2300 TST R16
00E3 F7E9 BNE 0x00E1
(0171) LCD1602_sendbyte(iCmd, LCDa_ENTRY); // 输入模式设定
00E4 E026 LDI R18,6
00E5 2700 CLR R16
(0172) } 00E6 CF9C RJMP _LCD1602_sendbyte
_Delayus:
i --> R20
US --> R22
00E7 940E02CE CALL push_gset2
00E9 01B8 MOVW R22,R16
FILE: I:\AVR视频教程\视频教程\lesson11\ds1302\ds1302\ds1302.c
(0001) #include <iom16v.h> //包含型号头文件
(0002) #include <macros.h> //包含"位"操作头文件
(0003) #define uchar unsigned char
(0004) #define uint unsigned int
(0005)
(0006) #define TRUE 1
(0007) #define FALSE 0
(0008) #include "YJ1602.C" //包含1602液晶函数文件
(0009)
(0010) /******************RTC常量******************/
(0011) #define RTC_CLK PB7
(0012) #define RTC_DATA PB5
(0013) #define RTC_CS PC7
(0014) //命令
(0015) #define RD 0x01
(0016) #define WR 0x00
(0017) #define C_SEC 0x80 //秒
(0018) #define C_MIN 0x82 //分
(0019) #define C_HR 0x84 //时
(0020) #define C_DAY 0x86 //日
(0021) #define C_MTH 0x88 //月
(0022) #define C_WK 0x8A //星期 DATE
(0023) #define C_YR 0x8C //年
(0024) #define C_WP 0x8E //控制(写保护)
(0025) #define C_CHARGE 0x90 //涓流充电
(0026) #define C_BURST 0xBE //时钟多字节
(0027) //配置
(0028) #define CLK_HALT 0x80 //停止时钟控制位 SECOND bit7
(0029) #define CLK_START 0x00 //启动时钟
(0030) #define M12_24 0x80 //12/24小时值选择位 HOUR bit7
(0031) #define PROTECT 0x80 //写保护控制位 CONTROL bit7
(0032) #define UPROTECT 0x00 //写保护控制位 CONTROL bit7
(0033) //涓流充电控制常量
(0034) #define TC_D1R2 0xA5 //high 1 Diode +2K Resistors
(0035) #define TC_D2R8 0xAB //low 2 Diodes+8K Resistors
(0036) #define TC_DISABLED 0x00 //Disabled(TCS<>1010 or DS=00 or RS=00)
(0037) //RAM 命令
(0038) #define C_RAMBASE 0xC0 //RAM0~RAM30<<1 地址需左移一位
(0039)
(0040) void Delayus(uint US)
(0041) {
(0042) uint i;
(0043) US=US*5/4; //5/4是在8MHz晶振下,通过软件仿真反复实验得到的数值
00EA E005 LDI R16,5
00EB E010 LDI R17,0
00EC 019B MOVW R18,R22
00ED 940E02A7 CALL empy16s
00EF 01B8 MOVW R22,R16
00F0 9576 LSR R23
00F1 9567 ROR R22
00F2 9576 LSR R23
00F3 9567 ROR R22
(0044) for( i=0;i<US;i++);
00F4 2744 CLR R20
00F5 2755 CLR R21
00F6 C002 RJMP 0x00F9
00F7 5F4F SUBI R20,0xFF
00F8 4F5F SBCI R21,0xFF
00F9 1746 CP R20,R22
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -